From 0f1770f2bdfeaaeab33725bfe3cb659239738326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 29 Mar 2018 19:19:21 +0300 Subject: [PATCH] splitmuxsink: Add new reset-muxer property With this the muxer is not set to NULL after each segment but instead only flush events are sent to it to reset the EOS state. As a result, the muxer will keep stream state and e.g. mpegtsmux will keep the packet continuity counter continuous between segments as needed by hlssink2. https://bugzilla.gnome.org/show_bug.cgi?id=794816 --- gst/multifile/gstsplitmuxsink.c | 50 +++++++++++++++++++++++++++++++-- gst/multifile/gstsplitmuxsink.h | 2 ++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/gst/multifile/gstsplitmuxsink.c b/gst/multifile/gstsplitmuxsink.c index 6ec436c293..f1cb7a4aa3 100644 --- a/gst/multifile/gstsplitmuxsink.c +++ b/gst/multifile/gstsplitmuxsink.c @@ -84,7 +84,8 @@ enum PROP_USE_ROBUST_MUXING, PROP_ALIGNMENT_THRESHOLD, PROP_MUXER, - PROP_SINK + PROP_SINK, + PROP_RESET_MUXER, }; #define DEFAULT_MAX_SIZE_TIME 0 @@ -96,6 +97,7 @@ enum #define DEFAULT_MUXER "mp4mux" #define DEFAULT_SINK "filesink" #define DEFAULT_USE_ROBUST_MUXING FALSE +#define DEFAULT_RESET_MUXER TRUE enum { @@ -284,6 +286,12 @@ gst_splitmux_sink_class_init (GstSplitMuxSinkClass * klass) DEFAULT_USE_ROBUST_MUXING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_RESET_MUXER, + g_param_spec_boolean ("reset-muxer", + "Reset Muxer", + "Reset the muxer after each segment. Disabling this will not work for most muxers.", + DEFAULT_RESET_MUXER, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** * GstSplitMuxSink::format-location: * @splitmux: the #GstSplitMuxSink @@ -343,6 +351,7 @@ gst_splitmux_sink_init (GstSplitMuxSink * splitmux) splitmux->next_max_tc_time = GST_CLOCK_TIME_NONE; splitmux->alignment_threshold = DEFAULT_ALIGNMENT_THRESHOLD; splitmux->use_robust_muxing = DEFAULT_USE_ROBUST_MUXING; + splitmux->reset_muxer = DEFAULT_RESET_MUXER; splitmux->threshold_timecode_str = NULL; @@ -512,6 +521,11 @@ gst_splitmux_sink_set_property (GObject * object, guint prop_id, gst_object_ref_sink (splitmux->provided_muxer); GST_OBJECT_UNLOCK (splitmux); break; + case PROP_RESET_MUXER: + GST_OBJECT_LOCK (splitmux); + splitmux->reset_muxer = g_value_get_boolean (value); + GST_OBJECT_UNLOCK (splitmux); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -580,6 +594,11 @@ gst_splitmux_sink_get_property (GObject * object, guint prop_id, g_value_set_object (value, splitmux->provided_muxer); GST_OBJECT_UNLOCK (splitmux); break; + case PROP_RESET_MUXER: + GST_OBJECT_LOCK (splitmux); + g_value_set_boolean (value, splitmux->reset_muxer); + GST_OBJECT_UNLOCK (splitmux); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1153,6 +1172,15 @@ restart_context (MqStreamCtx * ctx, GstSplitMuxSink * splitmux) gst_object_unref (peer); } +static void +_send_event (const GValue * value, gpointer user_data) +{ + GstPad *pad = g_value_get_object (value); + GstEvent *ev = user_data; + + gst_pad_send_event (pad, gst_event_ref (ev)); +} + /* Called with lock held when a fragment * reaches EOS and it is time to restart * a new fragment @@ -1175,9 +1203,27 @@ start_next_fragment (GstSplitMuxSink * splitmux, MqStreamCtx * ctx) gst_element_set_locked_state (muxer, TRUE); gst_element_set_locked_state (sink, TRUE); - gst_element_set_state (muxer, GST_STATE_NULL); gst_element_set_state (sink, GST_STATE_NULL); + if (splitmux->reset_muxer) { + gst_element_set_state (muxer, GST_STATE_NULL); + } else { + GstIterator *it = gst_element_iterate_sink_pads (muxer); + GstEvent *ev; + + ev = gst_event_new_flush_start (); + gst_iterator_foreach (it, _send_event, ev); + gst_event_unref (ev); + + gst_iterator_resync (it); + + ev = gst_event_new_flush_stop (TRUE); + gst_iterator_foreach (it, _send_event, ev); + gst_event_unref (ev); + + gst_iterator_free (it); + } + GST_SPLITMUX_LOCK (splitmux); if (splitmux->muxed_out_bytes > 0 || splitmux->fragment_id == 0) set_next_filename (splitmux, ctx); diff --git a/gst/multifile/gstsplitmuxsink.h b/gst/multifile/gstsplitmuxsink.h index aab90659b8..0d35647843 100644 --- a/gst/multifile/gstsplitmuxsink.h +++ b/gst/multifile/gstsplitmuxsink.h @@ -120,6 +120,8 @@ struct _GstSplitMuxSink GstClockTime next_max_tc_time; GstClockTime alignment_threshold; + gboolean reset_muxer; + GstElement *muxer; GstElement *sink;