mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
gst: add keepalive-time property
Add a property to periodically send the last buffer to keep the stream alive. Useful for sparse streams that need to keep the encoder busy every once and a while.
This commit is contained in:
parent
f28ca843a6
commit
993aa89030
2 changed files with 47 additions and 11 deletions
|
|
@ -63,6 +63,7 @@ GST_DEBUG_CATEGORY_STATIC (pipewire_src_debug);
|
||||||
#define DEFAULT_MIN_BUFFERS 1
|
#define DEFAULT_MIN_BUFFERS 1
|
||||||
#define DEFAULT_MAX_BUFFERS INT32_MAX
|
#define DEFAULT_MAX_BUFFERS INT32_MAX
|
||||||
#define DEFAULT_RESEND_LAST false
|
#define DEFAULT_RESEND_LAST false
|
||||||
|
#define DEFAULT_KEEPALIVE_TIME 0
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
|
@ -75,6 +76,7 @@ enum
|
||||||
PROP_MAX_BUFFERS,
|
PROP_MAX_BUFFERS,
|
||||||
PROP_FD,
|
PROP_FD,
|
||||||
PROP_RESEND_LAST,
|
PROP_RESEND_LAST,
|
||||||
|
PROP_KEEPALIVE_TIME,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -148,6 +150,10 @@ gst_pipewire_src_set_property (GObject * object, guint prop_id,
|
||||||
pwsrc->resend_last = g_value_get_boolean (value);
|
pwsrc->resend_last = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_KEEPALIVE_TIME:
|
||||||
|
pwsrc->keepalive_time = g_value_get_int (value);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
|
@ -193,6 +199,10 @@ gst_pipewire_src_get_property (GObject * object, guint prop_id,
|
||||||
g_value_set_boolean (value, pwsrc->resend_last);
|
g_value_set_boolean (value, pwsrc->resend_last);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_KEEPALIVE_TIME:
|
||||||
|
g_value_set_int (value, pwsrc->keepalive_time);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
|
@ -313,14 +323,14 @@ gst_pipewire_src_class_init (GstPipeWireSrcClass * klass)
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class,
|
g_object_class_install_property (gobject_class,
|
||||||
PROP_FD,
|
PROP_FD,
|
||||||
g_param_spec_int ("fd",
|
g_param_spec_int ("fd",
|
||||||
"Fd",
|
"Fd",
|
||||||
"The fd to connect with",
|
"The fd to connect with",
|
||||||
-1, G_MAXINT, -1,
|
-1, G_MAXINT, -1,
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class,
|
g_object_class_install_property (gobject_class,
|
||||||
PROP_RESEND_LAST,
|
PROP_RESEND_LAST,
|
||||||
|
|
@ -331,6 +341,14 @@ gst_pipewire_src_class_init (GstPipeWireSrcClass * klass)
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_KEEPALIVE_TIME,
|
||||||
|
g_param_spec_int ("keepalive-time",
|
||||||
|
"Keepalive Time",
|
||||||
|
"Periodically send last buffer (in seconds, 0 = disabled)",
|
||||||
|
0, G_MAXINT, DEFAULT_KEEPALIVE_TIME,
|
||||||
|
G_PARAM_READWRITE |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
gstelement_class->provide_clock = gst_pipewire_src_provide_clock;
|
gstelement_class->provide_clock = gst_pipewire_src_provide_clock;
|
||||||
gstelement_class->change_state = gst_pipewire_src_change_state;
|
gstelement_class->change_state = gst_pipewire_src_change_state;
|
||||||
|
|
@ -371,6 +389,7 @@ gst_pipewire_src_init (GstPipeWireSrc * src)
|
||||||
src->max_buffers = DEFAULT_MAX_BUFFERS;
|
src->max_buffers = DEFAULT_MAX_BUFFERS;
|
||||||
src->fd = -1;
|
src->fd = -1;
|
||||||
src->resend_last = DEFAULT_RESEND_LAST;
|
src->resend_last = DEFAULT_RESEND_LAST;
|
||||||
|
src->keepalive_time = DEFAULT_KEEPALIVE_TIME;
|
||||||
|
|
||||||
src->client_name = g_strdup(pw_get_client_name ());
|
src->client_name = g_strdup(pw_get_client_name ());
|
||||||
|
|
||||||
|
|
@ -848,6 +867,7 @@ gst_pipewire_src_create (GstPushSrc * psrc, GstBuffer ** buffer)
|
||||||
GstClockTime pts, dts, base_time;
|
GstClockTime pts, dts, base_time;
|
||||||
const char *error = NULL;
|
const char *error = NULL;
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
|
gboolean update_time = FALSE, timeout = FALSE;
|
||||||
|
|
||||||
pwsrc = GST_PIPEWIRE_SRC (psrc);
|
pwsrc = GST_PIPEWIRE_SRC (psrc);
|
||||||
|
|
||||||
|
|
@ -876,17 +896,30 @@ gst_pipewire_src_create (GstPushSrc * psrc, GstBuffer ** buffer)
|
||||||
goto streaming_eos;
|
goto streaming_eos;
|
||||||
buf = pwsrc->last_buffer;
|
buf = pwsrc->last_buffer;
|
||||||
pwsrc->last_buffer = NULL;
|
pwsrc->last_buffer = NULL;
|
||||||
|
update_time = TRUE;
|
||||||
break;
|
break;
|
||||||
|
} else if (timeout) {
|
||||||
|
if (pwsrc->last_buffer != NULL) {
|
||||||
|
update_time = TRUE;
|
||||||
|
buf = gst_buffer_ref(pwsrc->last_buffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
buf = dequeue_buffer (pwsrc);
|
buf = dequeue_buffer (pwsrc);
|
||||||
GST_LOG_OBJECT (pwsrc, "popped buffer %p", buf);
|
GST_LOG_OBJECT (pwsrc, "popped buffer %p", buf);
|
||||||
if (buf != NULL) {
|
if (buf != NULL) {
|
||||||
if (pwsrc->resend_last)
|
if (pwsrc->resend_last || pwsrc->keepalive_time > 0)
|
||||||
gst_buffer_replace (&pwsrc->last_buffer, buf);
|
gst_buffer_replace (&pwsrc->last_buffer, buf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pw_thread_loop_wait (pwsrc->core->loop);
|
timeout = FALSE;
|
||||||
|
if (pwsrc->keepalive_time > 0) {
|
||||||
|
if (pw_thread_loop_timed_wait (pwsrc->core->loop, pwsrc->keepalive_time) == ETIMEDOUT)
|
||||||
|
timeout = TRUE;
|
||||||
|
} else {
|
||||||
|
pw_thread_loop_wait (pwsrc->core->loop);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pw_thread_loop_unlock (pwsrc->core->loop);
|
pw_thread_loop_unlock (pwsrc->core->loop);
|
||||||
|
|
||||||
|
|
@ -902,7 +935,7 @@ gst_pipewire_src_create (GstPushSrc * psrc, GstBuffer ** buffer)
|
||||||
else
|
else
|
||||||
base_time = 0;
|
base_time = 0;
|
||||||
|
|
||||||
if (pwsrc->last_buffer == NULL && pwsrc->resend_last) {
|
if (update_time) {
|
||||||
GstClock *clock = gst_element_get_clock (GST_ELEMENT_CAST (pwsrc));
|
GstClock *clock = gst_element_get_clock (GST_ELEMENT_CAST (pwsrc));
|
||||||
if (clock != NULL) {
|
if (clock != NULL) {
|
||||||
pts = dts = gst_clock_get_time (clock);
|
pts = dts = gst_clock_get_time (clock);
|
||||||
|
|
@ -1039,6 +1072,8 @@ no_stream:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (pwsrc, RESOURCE, FAILED, ("can't create stream"), (NULL));
|
GST_ELEMENT_ERROR (pwsrc, RESOURCE, FAILED, ("can't create stream"), (NULL));
|
||||||
pw_thread_loop_unlock (pwsrc->core->loop);
|
pw_thread_loop_unlock (pwsrc->core->loop);
|
||||||
|
gst_pipewire_core_release (pwsrc->core);
|
||||||
|
pwsrc->core = NULL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ struct _GstPipeWireSrc {
|
||||||
gint max_buffers;
|
gint max_buffers;
|
||||||
int fd;
|
int fd;
|
||||||
gboolean resend_last;
|
gboolean resend_last;
|
||||||
|
gint keepalive_time;
|
||||||
|
|
||||||
gboolean negotiated;
|
gboolean negotiated;
|
||||||
gboolean flushing;
|
gboolean flushing;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue