From 0195d1f9022ec7cd2faf41f817d15166baa996fd Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Fri, 12 Nov 2021 14:45:42 +0900 Subject: [PATCH] hlsdemux: Set stream discontinuity when the last PCR value differs by more than 1 second Change-Id: I1747f7485c9f2eabae67f6f17e11005715a1a081 --- ext/hls/gsthlsdemux.c | 63 ++++++++++++++++++++++++++++++++---------- ext/hls/gsthlsdemux.h | 4 +++ packaging/gst-plugins-bad.spec | 1 + 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/ext/hls/gsthlsdemux.c b/ext/hls/gsthlsdemux.c index 7e5742b..3e7da32 100644 --- a/ext/hls/gsthlsdemux.c +++ b/ext/hls/gsthlsdemux.c @@ -73,6 +73,10 @@ enum }; #endif +#ifdef TIZEN_FEATURE_HLSDEMUX_DISCONT +#define ABSDIFF(a,b) ((a) < (b) ? (b) - (a) : (a) - (b)) +#endif + /* GObject */ static void gst_hls_demux_finalize (GObject * obj); #ifdef TIZEN_FEATURE_HLSDEMUX_PROPERTY @@ -134,8 +138,8 @@ static GstM3U8 *gst_hls_demux_stream_get_m3u8 (GstHLSDemuxStream * hls_stream); static void gst_hls_demux_set_current_variant (GstHLSDemux * hlsdemux, GstHLSVariantStream * variant); #ifdef TIZEN_FEATURE_HLSDEMUX_LANG_TAG -static gboolean gst_hlsdemux_set_stream_event (GstAdaptiveDemuxStream *stream, - GstHLSMedia *media); +static gboolean gst_hlsdemux_set_stream_event (GstAdaptiveDemuxStream * stream, + GstHLSMedia * media); static gboolean gst_hlsdemux_set_language_tags (GstAdaptiveDemuxStream * stream, const gchar * language); #endif @@ -180,14 +184,15 @@ gst_hls_demux_class_init (GstHLSDemuxClass * klass) FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_LIVE_START_TIME, - g_param_spec_uint64 ("live-start-time", "start time of the first fragment", - "start time of the first fragment in the current media playlist in case of live", 0, G_MAXUINT64, - 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + g_param_spec_uint64 ("live-start-time", + "start time of the first fragment", + "start time of the first fragment in the current media playlist in case of live", + 0, G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_LIVE_END_TIME, g_param_spec_uint64 ("live-end-time", "end time of the last fragment", - "end time of the last fragment in the current media playlist in case of live", 0, G_MAXUINT64, - 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + "end time of the last fragment in the current media playlist in case of live", + 0, G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); #endif element_class->change_state = GST_DEBUG_FUNCPTR (gst_hls_demux_change_state); @@ -508,7 +513,7 @@ gst_hls_demux_stream_seek (GstAdaptiveDemuxStream * stream, gboolean forward, /* Snap to segment boundary. Improves seek performance on slow machines. */ snap_nearest = (flags & GST_SEEK_FLAG_SNAP_NEAREST) == GST_SEEK_FLAG_SNAP_NEAREST; - snap_after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER); + snap_after = !!(flags & GST_SEEK_FLAG_SNAP_AFTER); GST_M3U8_CLIENT_LOCK (hlsdemux->client); /* FIXME: Here we need proper discont handling */ @@ -691,6 +696,10 @@ create_stream_for_playlist (GstAdaptiveDemux * demux, GstM3U8 * playlist, hlsdemux_stream->do_typefind = TRUE; hlsdemux_stream->reset_pts = TRUE; +#ifdef TIZEN_FEATURE_HLSDEMUX_DISCONT + hlsdemux_stream->sequence_pos = GST_CLOCK_TIME_NONE; + hlsdemux_stream->last_pcr = GST_CLOCK_TIME_NONE; +#endif #ifdef TIZEN_FEATURE_HLSDEMUX_LANG_TAG if (media) { @@ -698,7 +707,9 @@ create_stream_for_playlist (GstAdaptiveDemux * demux, GstM3U8 * playlist, return; } - for (GList *mlist = hlsdemux->current_variant->media[GST_HLS_MEDIA_TYPE_AUDIO]; mlist; mlist = g_list_next(mlist)) { + for (GList * mlist = + hlsdemux->current_variant->media[GST_HLS_MEDIA_TYPE_AUDIO]; mlist; + mlist = g_list_next (mlist)) { GstHLSMedia *media = mlist->data; if (!media->uri && gst_hlsdemux_set_stream_event (stream, media)) return; @@ -1314,6 +1325,22 @@ gst_hls_demux_handle_buffer (GstAdaptiveDemux * demux, hls_stream->pending_pcr_buffer = buffer; return GST_FLOW_OK; } +#ifdef TIZEN_FEATURE_HLSDEMUX_DISCONT + if (!stream->discont && GST_CLOCK_TIME_IS_VALID (hls_stream->last_pcr) + && GST_CLOCK_TIME_IS_VALID (last_pcr)) { + if (G_UNLIKELY (ABSDIFF (hls_stream->last_pcr, last_pcr) > 1 * GST_SECOND)) { + GST_DEBUG_OBJECT (stream->pad, + "Overwriting fragment timestamp [%" GST_TIME_FORMAT "] to [%" + GST_TIME_FORMAT "]", GST_TIME_ARGS (stream->fragment.timestamp), + GST_TIME_ARGS (hls_stream->sequence_pos)); + stream->fragment.timestamp = hls_stream->sequence_pos; + stream->discont = TRUE; + } + } + + if (GST_CLOCK_TIME_IS_VALID (last_pcr)) + hls_stream->last_pcr = last_pcr; +#endif if (tags) { #ifdef TIZEN_FEATURE_HLSDEMUX_LANG_TAG @@ -1536,6 +1563,9 @@ gst_hls_demux_update_fragment_info (GstAdaptiveDemuxStream * stream) if (stream->discont) discont = TRUE; +#ifdef TIZEN_FEATURE_HLSDEMUX_DISCONT + hlsdemux_stream->sequence_pos = sequence_pos; +#endif /* set up our source for download */ #ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING stream->fragment.timestamp = hlsdemux_stream->current_pts = sequence_pos; @@ -2396,7 +2426,8 @@ gst_hls_demux_get_live_seek_range (GstAdaptiveDemux * demux, gint64 * start, #ifdef TIZEN_FEATURE_HLSDEMUX_LANG_TAG static gboolean -gst_hlsdemux_set_stream_event (GstAdaptiveDemuxStream *stream, GstHLSMedia *media) +gst_hlsdemux_set_stream_event (GstAdaptiveDemuxStream * stream, + GstHLSMedia * media) { GstStructure *structure; GstEvent *event; @@ -2414,10 +2445,11 @@ gst_hlsdemux_set_stream_event (GstAdaptiveDemuxStream *stream, GstHLSMedia *medi if (media->lang) gst_hlsdemux_set_language_tags (stream, media->lang); - structure = gst_structure_new ("GstHLSMedia", "mtype", G_TYPE_INT, media->mtype, - "default", G_TYPE_BOOLEAN, media->is_default, - "autoselect", G_TYPE_BOOLEAN, media->autoselect, - "forced", G_TYPE_BOOLEAN, media->forced, NULL); + structure = + gst_structure_new ("GstHLSMedia", "mtype", G_TYPE_INT, media->mtype, + "default", G_TYPE_BOOLEAN, media->is_default, "autoselect", + G_TYPE_BOOLEAN, media->autoselect, "forced", G_TYPE_BOOLEAN, + media->forced, NULL); event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, structure); @@ -2427,7 +2459,8 @@ gst_hlsdemux_set_stream_event (GstAdaptiveDemuxStream *stream, GstHLSMedia *medi } static gboolean -gst_hlsdemux_set_language_tags (GstAdaptiveDemuxStream *stream, const gchar *language) +gst_hlsdemux_set_language_tags (GstAdaptiveDemuxStream * stream, + const gchar * language) { GstTagList *lang_tag = NULL; diff --git a/ext/hls/gsthlsdemux.h b/ext/hls/gsthlsdemux.h index 548927a..105afb3 100644 --- a/ext/hls/gsthlsdemux.h +++ b/ext/hls/gsthlsdemux.h @@ -101,6 +101,10 @@ struct _GstHLSDemuxStream #ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING GstClockTime current_pts; #endif +#ifdef TIZEN_FEATURE_HLSDEMUX_DISCONT + GstClockTime sequence_pos; + GstClockTime last_pcr; +#endif /* decryption tooling */ #if defined(HAVE_OPENSSL) diff --git a/packaging/gst-plugins-bad.spec b/packaging/gst-plugins-bad.spec index 9c3b1fc..1e8821c 100644 --- a/packaging/gst-plugins-bad.spec +++ b/packaging/gst-plugins-bad.spec @@ -90,6 +90,7 @@ export CFLAGS+=" -Wall -g -fPIC\ -DTIZEN_FEATURE_H264PARSE_MODIFICATION\ -DTIZEN_FEATURE_AD\ -DTIZEN_FEATURE_HLSDEMUX_LANG_TAG\ + -DTIZEN_FEATURE_HLSDEMUX_DISCONT\ -DTIZEN_FEATURE_UPSTREAM\ -DTIZEN_FEATURE_GST_UPSTREAM_AVOID_BUILD_BREAK\ -D__TIZEN__\ -- 2.7.4