hlsdemux: Set stream discontinuity when the last PCR value differs by more than 1...
authorGilbok Lee <gilbok.lee@samsung.com>
Fri, 12 Nov 2021 05:45:42 +0000 (14:45 +0900)
committerGilbok Lee <gilbok.lee@samsung.com>
Fri, 12 Nov 2021 09:36:52 +0000 (09:36 +0000)
Change-Id: I1747f7485c9f2eabae67f6f17e11005715a1a081

ext/hls/gsthlsdemux.c
ext/hls/gsthlsdemux.h
packaging/gst-plugins-bad.spec

index 7e5742b..3e7da32 100644 (file)
@@ -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;
 
index 548927a..105afb3 100644 (file)
@@ -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)
index 9c3b1fc..1e8821c 100644 (file)
@@ -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__\