diff --git a/configure.ac b/configure.ac index 3b39968..48e0fb6 100644 --- a/configure.ac +++ b/configure.ac @@ -6,7 +6,7 @@ dnl please read gstreamer/docs/random/autotools before changing this file dnl initialize autoconf dnl releases only do -Wall, git and prerelease does -Werror too dnl use a three digit version number for releases, and four for git/pre -AC_INIT([GstInterpipe],[1.0.6], +AC_INIT([GstInterpipe],[1.0.7], [http://www.github.com/RidgeRun/gst-interpipe-1.0], [gst-interpipe], [http://developer.ridgerun.com/wiki/index.php?title=GstInterpipe]) diff --git a/gst-interpipe.doap b/gst-interpipe.doap index 5ef89c5..8b0f12e 100644 --- a/gst-interpipe.doap +++ b/gst-interpipe.doap @@ -30,6 +30,16 @@ GstInterpipe is a plug-in with two elements which allow the communication betwee + + + 1.0.7 + master + + 2020-01-13 + + + + 1.0.6 diff --git a/gst/interpipe/gstinterpipesrc.c b/gst/interpipe/gstinterpipesrc.c index ab74d0d..fd4c587 100644 --- a/gst/interpipe/gstinterpipesrc.c +++ b/gst/interpipe/gstinterpipesrc.c @@ -58,7 +58,7 @@ enum PROP_LISTEN_TO, PROP_BLOCK_SWITCH, PROP_ALLOW_RENEGOTIATION, - PROP_ENABLE_SYNC, + PROP_STREAM_SYNC, PROP_ACCEPT_EVENTS, PROP_ACCEPT_EOS_EVENT }; @@ -95,6 +95,35 @@ static gboolean gst_inter_pipe_src_event (GstBaseSrc * base, GstEvent * event); static void gst_inter_pipe_ilistener_init (GstInterPipeIListenerInterface * iface); + +typedef enum +{ + GST_INTER_PIPE_SRC_RESTART_TIMESTAMP, + GST_INTER_PIPE_SRC_PASSTHROUGH_TIMESTAMP, + GST_INTER_PIPE_SRC_COMPENSATE_TIMESTAMP +} GstInterPipeSrcStreamSync; + + +#define GST_TYPE_INTER_PIPE_SRC_STREAM_SYNC (gst_inter_pipe_src_stream_sync_get_type ()) +static GType +gst_inter_pipe_src_stream_sync_get_type (void) +{ + static GType inter_pipe_src_stream_sync_type = 0; + static const GEnumValue stream_sync_types[] = { + {GST_INTER_PIPE_SRC_RESTART_TIMESTAMP, "Restart Timestamp", "restart-ts"}, + {GST_INTER_PIPE_SRC_PASSTHROUGH_TIMESTAMP, "Passthrough Timestamp", + "passthrough-ts"}, + {GST_INTER_PIPE_SRC_COMPENSATE_TIMESTAMP, "Compensate Timestamp", + "compensate-ts"}, + {0, NULL, NULL} + }; + if (!inter_pipe_src_stream_sync_type) { + inter_pipe_src_stream_sync_type = + g_enum_register_static ("GstInterPipeSrcStreamSync", stream_sync_types); + } + return inter_pipe_src_stream_sync_type; +} + struct _GstInterPipeSrc { GstAppSrc parent; @@ -117,8 +146,8 @@ struct _GstInterPipeSrc /* Allow caps renegotiation */ gboolean allow_renegotiation; - /* Synchronization switch */ - gboolean enable_sync; + /* Stream synchronization */ + GstInterPipeSrcStreamSync stream_sync; /* Accept the events received from the interpipesink */ gboolean accept_events; @@ -176,11 +205,12 @@ gst_inter_pipe_src_class_init (GstInterPipeSrcClass * klass) "caps only if the allow-renegotiation property is set to true", TRUE, G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_ENABLE_SYNC, - g_param_spec_boolean ("enable-sync", "Enable Synchronization", - "Perform buffer timestamp compensation to have equivalent relative " - "buffer times in the different pipelines", - TRUE, G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_STREAM_SYNC, + g_param_spec_enum ("stream-sync", "Stream Synchronization", + "Define buffer synchronization between the different pipelines", + GST_TYPE_INTER_PIPE_SRC_STREAM_SYNC, + GST_INTER_PIPE_SRC_PASSTHROUGH_TIMESTAMP, + G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_ACCEPT_EVENTS, g_param_spec_boolean ("accept-events", "Accept Events", @@ -209,7 +239,7 @@ gst_inter_pipe_src_init (GstInterPipeSrc * src) src->block_switch = FALSE; src->allow_renegotiation = TRUE; src->first_switch = TRUE; - src->enable_sync = TRUE; + src->stream_sync = GST_INTER_PIPE_SRC_PASSTHROUGH_TIMESTAMP; src->accept_events = TRUE; src->accept_eos_event = TRUE; } @@ -267,8 +297,8 @@ gst_inter_pipe_src_set_property (GObject * object, guint prop_id, case PROP_ALLOW_RENEGOTIATION: src->allow_renegotiation = g_value_get_boolean (value); break; - case PROP_ENABLE_SYNC: - src->enable_sync = g_value_get_boolean (value); + case PROP_STREAM_SYNC: + src->stream_sync = g_value_get_enum (value); break; case PROP_ACCEPT_EVENTS: src->accept_events = g_value_get_boolean (value); @@ -302,8 +332,8 @@ gst_inter_pipe_src_get_property (GObject * object, guint prop_id, case PROP_ALLOW_RENEGOTIATION: g_value_set_boolean (value, src->allow_renegotiation); break; - case PROP_ENABLE_SYNC: - g_value_set_boolean (value, src->enable_sync); + case PROP_STREAM_SYNC: + g_value_set_enum (value, src->stream_sync); break; case PROP_ACCEPT_EVENTS: g_value_set_boolean (value, src->accept_events); @@ -342,22 +372,30 @@ gst_inter_pipe_src_start (GstBaseSrc * base) basesrc_class = GST_BASE_SRC_CLASS (gst_inter_pipe_src_parent_class); src = GST_INTER_PIPE_SRC (base); - if(!basesrc_class->start (base)) - return FALSE; + if (!basesrc_class->start (base)) + goto start_fail; if (src->listen_to) { if (!gst_inter_pipe_src_listen_node (src, src->listen_to)) { GST_ERROR_OBJECT (src, "Could not listen to node %s", src->listen_to); - return FALSE; + goto start_fail; } else { GST_INFO_OBJECT (src, "Listening to node %s", src->listen_to); src->listening = TRUE; - return TRUE; + goto start_done; } } else { /* it's valid to be started but not listening (yet) */ - return TRUE; + goto start_done; } + +start_done: + if (GST_INTER_PIPE_SRC_RESTART_TIMESTAMP == src->stream_sync) + gst_base_src_set_do_timestamp (base, TRUE); + + return TRUE; +start_fail: + return FALSE; } static gboolean @@ -588,7 +626,7 @@ gst_inter_pipe_src_push_buffer (GstInterPipeIListener * iface, goto out; } - if (src->enable_sync) { + if (GST_INTER_PIPE_SRC_COMPENSATE_TIMESTAMP == src->stream_sync) { guint64 difftime; buffer = gst_buffer_make_writable (buffer); @@ -627,6 +665,10 @@ gst_inter_pipe_src_push_buffer (GstInterPipeIListener * iface, GST_LOG_OBJECT (src, "Calculated Buffer Timestamp (PTS): %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_PTS (buffer))); + } else if (GST_INTER_PIPE_SRC_RESTART_TIMESTAMP == src->stream_sync) { + /* Remove the incoming timestamp to be generated according this basetime */ + GST_BUFFER_PTS (buffer) = GST_CLOCK_TIME_NONE; + GST_BUFFER_DTS (buffer) = GST_CLOCK_TIME_NONE; } ret = gst_app_src_push_buffer (appsrc, buffer);