hlsdemux/mpegtsdemux : Check the pcr_pid in PMT at every ts fragment
authorGilbok Lee <gilbok.lee@samsung.com>
Mon, 10 Sep 2018 06:20:17 +0000 (15:20 +0900)
committerGilbok Lee <gilbok.lee@samsung.com>
Wed, 12 Sep 2018 05:53:50 +0000 (14:53 +0900)
problems : video is not playing smoothly after seek.
cause : During hls streaming, there is a stream where pmt version
does not change but pcr_pid changes when fragment is changed.
When converting the time stamp, the problem is caused using the wrong
pcr.

Change-Id: I6c11cfeb01b7a1e85fa2cca98316a204c178f3f5

ext/hls/gsthlsdemux.c [changed mode: 0644->0755]
gst/mpegtsdemux/mpegtsbase.c
gst/mpegtsdemux/mpegtspacketizer.c
gst/mpegtsdemux/mpegtspacketizer.h

old mode 100644 (file)
new mode 100755 (executable)
index e21bf34..cd50c78
@@ -115,6 +115,10 @@ static gboolean gst_hls_demux_get_live_seek_range (GstAdaptiveDemux * demux,
 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_AVOID_PAD_SWITCHING
+static void gst_hls_demux_push_fragment_finished_event (GstAdaptiveDemux * demux,
+    GstAdaptiveDemuxStream * stream);
+#endif
 
 #define gst_hls_demux_parent_class parent_class
 G_DEFINE_TYPE (GstHLSDemux, gst_hls_demux, GST_TYPE_ADAPTIVE_DEMUX);
@@ -517,8 +521,8 @@ gst_adaptive_demux_find_stream (GstAdaptiveDemux * demux, gboolean is_primary_pl
         ((type == GST_HLS_MEDIA_TYPE_VIDEO) && (g_strrstr(caps_str, "video"))))
       find_stream = TRUE;
 
-      g_free (caps_str);
-      gst_caps_unref(caps);
+    g_free (caps_str);
+    gst_caps_unref(caps);
 
     if (find_stream)
       return stream;
@@ -1025,6 +1029,9 @@ gst_hls_demux_finish_fragment (GstAdaptiveDemux * demux,
   if (hls_stream->current_key)
     gst_hls_demux_stream_decrypt_end (hls_stream);
 
+#ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
+  gst_hls_demux_push_fragment_finished_event (demux, stream);
+#endif
   if (stream->last_ret == GST_FLOW_OK) {
     if (hls_stream->pending_decrypted_buffer) {
       if (hls_stream->current_key) {
@@ -1214,14 +1221,15 @@ gst_hls_demux_update_fragment_info (GstAdaptiveDemuxStream * stream)
 
   /* set up our source for download */
 #ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
-  hlsdemux_stream->current_pts = sequence_pos;
-#endif
+  stream->fragment.timestamp = hlsdemux_stream->current_pts = sequence_pos;
+#else
   if (hlsdemux_stream->reset_pts || discont
       || stream->demux->segment.rate < 0.0) {
     stream->fragment.timestamp = sequence_pos;
   } else {
     stream->fragment.timestamp = GST_CLOCK_TIME_NONE;
   }
+#endif
 
   g_free (hlsdemux_stream->current_key);
   hlsdemux_stream->current_key = g_strdup (file->key);
@@ -1273,10 +1281,8 @@ gst_hls_demux_select_bitrate (GstAdaptiveDemuxStream * stream, guint64 bitrate)
 
   gst_hls_demux_change_playlist (hlsdemux, bitrate / MAX (1.0,
           ABS (demux->segment.rate)), &changed);
-#ifndef TIZEN_FEATURE_AVOID_PAD_SWITCHING
   if (changed)
     gst_hls_demux_setup_streams (GST_ADAPTIVE_DEMUX_CAST (hlsdemux));
-#endif
   return changed;
 }
 
@@ -1998,3 +2004,19 @@ gst_hls_demux_get_live_seek_range (GstAdaptiveDemux * demux, gint64 * start,
 
   return ret;
 }
+
+#ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
+static void
+gst_hls_demux_push_fragment_finished_event (GstAdaptiveDemux * demux,
+    GstAdaptiveDemuxStream * stream)
+{
+  GstPad *pad = stream->pad;
+  GstEvent *event;
+
+  event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM,
+              gst_structure_new_empty ("fragment_finished"));
+
+  GST_DEBUG_OBJECT(demux, "push fragment_finished event");
+  gst_pad_push_event (pad, event);
+}
+#endif
index 2625b7d..1189bcf 100644 (file)
@@ -794,6 +794,9 @@ mpegts_base_is_same_program (MpegTSBase * base, MpegTSBaseProgram * oldprogram,
   guint i, nbstreams;
   MpegTSBaseStream *oldstream;
   gboolean sawpcrpid = FALSE;
+#ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
+  gboolean pcrpid_changed = FALSE;
+#endif
 
   if (oldprogram->pmt_pid != new_pmt_pid) {
     GST_DEBUG ("Different pmt_pid (new:0x%04x, old:0x%04x)", new_pmt_pid,
@@ -804,7 +807,11 @@ mpegts_base_is_same_program (MpegTSBase * base, MpegTSBaseProgram * oldprogram,
   if (oldprogram->pcr_pid != new_pmt->pcr_pid) {
     GST_DEBUG ("Different pcr_pid (new:0x%04x, old:0x%04x)",
         new_pmt->pcr_pid, oldprogram->pcr_pid);
+#ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
+    pcrpid_changed = TRUE;
+#else
     return FALSE;
+#endif
   }
 
   /* Check the streams */
@@ -837,6 +844,13 @@ mpegts_base_is_same_program (MpegTSBase * base, MpegTSBaseProgram * oldprogram,
     return FALSE;
   }
 
+#ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
+  if (pcrpid_changed) {
+    GST_DEBUG ("only pcr_pid is changed");
+    oldprogram->pcr_pid = new_pmt->pcr_pid;
+    return TRUE;
+  }
+#endif
   GST_DEBUG ("Programs are equal");
   return TRUE;
 }
@@ -1446,6 +1460,18 @@ mpegts_base_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
       gst_segment_init (&base->segment, GST_FORMAT_UNDEFINED);
       base->seen_pat = FALSE;
       break;
+#ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
+    case GST_EVENT_CUSTOM_DOWNSTREAM:
+      structure = gst_event_get_structure(event);
+      if (gst_structure_has_name (structure, "fragment_finished")) {
+        GST_DEBUG_OBJECT (base, "Got fragment_finished event");
+        if (!base->packetizer->need_pmt_update) {
+          base->packetizer->need_pmt_update = TRUE;
+          GST_DEBUG_OBJECT (base, "Set need_pmt_update");
+        }
+      }
+      break;
+#endif
     default:
       res = GST_MPEGTS_BASE_GET_CLASS (base)->push_event (base, event);
   }
index 593cb23..9f47054 100644 (file)
@@ -271,6 +271,7 @@ mpegts_packetizer_init (MpegTSPacketizer2 * packetizer)
   packetizer->last_in_time = GST_CLOCK_TIME_NONE;
 #ifdef TIZEN_FEATURE_TSDEMUX_MODIFICATION
   packetizer->is_live_stream = FALSE;
+  packetizer->need_pmt_update = FALSE;
 #endif
   packetizer->pcr_discont_threshold = GST_SECOND;
 }
@@ -396,26 +397,12 @@ mpegts_packetizer_parse_adaptation_field_control (MpegTSPacketizer2 *
         GST_TIME_ARGS (PCRTIME_TO_GSTTIME (packet->pcr)), packet->offset);
 
     PACKETIZER_GROUP_LOCK (packetizer);
-#ifdef TIZEN_FEATURE_TSDEMUX_MODIFICATION
-    if (packetizer->calculate_skew
-        && GST_CLOCK_TIME_IS_VALID (packetizer->last_in_time)) {
-      pcrtable = get_pcr_table (packetizer, packet->pid);
-      if (((!GST_CLOCK_TIME_IS_VALID (pcrtable->base_time))
-              || (!GST_CLOCK_TIME_IS_VALID (pcrtable->base_pcrtime)))
-          || (packetizer->is_live_stream)) {
-        calculate_skew (packetizer, pcrtable, packet->pcr,
-            packetizer->last_in_time);
-      } else
-        GST_DEBUG (" **** skew calculation not done **** !!!");
-    }
-#else
     if (packetizer->calculate_skew
         && GST_CLOCK_TIME_IS_VALID (packetizer->last_in_time)) {
       pcrtable = get_pcr_table (packetizer, packet->pid);
       calculate_skew (packetizer, pcrtable, packet->pcr,
           packetizer->last_in_time);
     }
-#endif
     if (packetizer->calculate_offset) {
       if (!pcrtable)
         pcrtable = get_pcr_table (packetizer, packet->pid);
@@ -1186,6 +1173,13 @@ section_start:
    * * same last_section_number
    * * same section_number was seen
    */
+#ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
+  if (table_id == 0x02 && packetizer->need_pmt_update) {
+    GST_DEBUG ("Didn't check the seen_section_before");
+    packetizer->need_pmt_update = FALSE;
+    goto skip;
+  }
+#endif
   if (seen_section_before (stream, table_id, subtable_extension,
           version_number, section_number, last_section_number)) {
     GST_DEBUG
@@ -1198,6 +1192,9 @@ section_start:
       goto out;
     goto section_start;
   }
+#ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
+skip:
+#endif
   if (G_UNLIKELY (section_number > last_section_number)) {
     GST_WARNING
         ("PID 0x%04x corrupted packet (section_number:%d > last_section_number:%d)",
index e4f85e2..c59e7bc 100644 (file)
@@ -280,6 +280,7 @@ struct _MpegTSPacketizer2 {
 
 #ifdef TIZEN_FEATURE_TSDEMUX_MODIFICATION
   gboolean is_live_stream;
+  gboolean need_pmt_update;
 #endif
 
   /* offset to observations table */