[hls/tsdemux] add handling about non pcr live stream 68/99468/1 accepted/tizen/common/20161123.140237 accepted/tizen/ivi/20161123.233410 accepted/tizen/mobile/20161123.233313 accepted/tizen/tv/20161123.233331 accepted/tizen/wearable/20161123.233350 submit/tizen/20161123.104017
authorEunhae Choi <eunhae1.choi@samsung.com>
Wed, 23 Nov 2016 03:22:16 +0000 (12:22 +0900)
committereunhae choi <eunhae1.choi@samsung.com>
Wed, 23 Nov 2016 03:35:46 +0000 (19:35 -0800)
Change-Id: Ic10e786aab88385053f878f0393e2ae031ddbd94

ext/hls/gsthlsdemux.c
gst-libs/gst/adaptivedemux/gstadaptivedemux.c
gst/mpegtsdemux/mpegtsbase.c
gst/mpegtsdemux/mpegtspacketizer.c
gst/mpegtsdemux/mpegtspacketizer.h
packaging/gst-plugins-bad.spec

index 3da3906..ab53aed 100644 (file)
@@ -976,6 +976,35 @@ retry:
    * three fragments before the end of the list */
   if (update == FALSE && demux->client->current &&
       gst_m3u8_client_is_live (demux->client)) {
+#ifdef TIZEN_FEATURE_ADAPTIVE_MODIFICATION
+    gint64 last_sequence, first_sequence, previous_sequence;
+
+    GST_M3U8_CLIENT_LOCK (demux->client);
+    last_sequence =
+          GST_M3U8_MEDIA_FILE (g_list_last (demux->client->current->
+                    files)->data)->sequence;
+    first_sequence =
+          GST_M3U8_MEDIA_FILE (demux->client->current->files->data)->sequence;
+
+    previous_sequence = demux->client->sequence;
+
+    GST_DEBUG_OBJECT (demux,
+        "sequence:%" G_GINT64_FORMAT " , first_sequence:%" G_GINT64_FORMAT
+        " , last_sequence:%" G_GINT64_FORMAT, demux->client->sequence,
+        first_sequence, last_sequence);
+    if (demux->client->sequence >= last_sequence - 3) {
+      demux->client->sequence = MIN(MAX(MAX(first_sequence, last_sequence - 3),previous_sequence),last_sequence);
+      /*
+      [prasenjit.c] Refer 6.3.5 for draft-pantos-http-live-streaming-19.
+      As per specification , "In order to play the presentation normally, the next Media Segment to
+      load is the one with the lowest Media Sequence Number that is greater
+      than the Media Sequence Number of the last Media Segment loaded."
+      */
+      GST_DEBUG_OBJECT (demux,
+          "Sequence is beyond playlist , but to maintain the playback flow , Not Moving Back if not passed Last Sequence. Loaded Sequence %" G_GINT64_FORMAT,
+          demux->client->sequence);
+    }
+#else
     gint64 last_sequence, first_sequence;
 
     GST_M3U8_CLIENT_LOCK (demux->client);
@@ -997,6 +1026,7 @@ retry:
           "Sequence is beyond playlist. Moving back to %" G_GINT64_FORMAT,
           demux->client->sequence);
     }
+#endif
     GST_M3U8_CLIENT_UNLOCK (demux->client);
   } else if (demux->client->current && !gst_m3u8_client_is_live (demux->client)) {
     GstClockTime current_pos, target_pos;
index b6bba62..91ac6c5 100644 (file)
@@ -1343,8 +1343,11 @@ gst_adaptive_demux_src_query (GstPad * pad, GstObject * parent,
 
           g_value_init (&value, G_TYPE_BOOLEAN);
           g_value_set_boolean (&value, TRUE);
-
           gst_structure_set_value ((GstStructure *)s, "adaptive-streaming", &value);
+
+          g_value_set_boolean (&value, gst_adaptive_demux_is_live (demux));
+          gst_structure_set_value ((GstStructure *)s, "is-live", &value);
+
           ret = TRUE;
         } else {
           GST_DEBUG_OBJECT (demux, "Unsupported query");
@@ -1669,6 +1672,14 @@ gst_adaptive_demux_stream_push_buffer (GstAdaptiveDemuxStream * stream,
   GST_BUFFER_DTS (buffer) = GST_CLOCK_TIME_NONE;
 
   if (G_UNLIKELY (stream->pending_caps)) {
+#ifdef TIZEN_FEATURE_ADAPTIVE_MODIFICATION
+    gst_caps_make_writable (stream->pending_caps);
+    if (gst_adaptive_demux_is_live (demux)) {
+      gst_caps_set_simple (stream->pending_caps,"is_live", G_TYPE_BOOLEAN, TRUE, NULL);
+    } else {
+      gst_caps_set_simple (stream->pending_caps,"is_live", G_TYPE_BOOLEAN, FALSE, NULL);
+    }
+#endif
     GST_DEBUG_OBJECT (stream->pad, "Setting pending caps: %" GST_PTR_FORMAT,
         stream->pending_caps);
     gst_pad_set_caps (stream->pad, stream->pending_caps);
index 4722478..de65ae3 100644 (file)
@@ -1116,6 +1116,11 @@ mpegts_base_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
   gboolean hard;
   MpegTSBase *base = GST_MPEGTS_BASE (parent);
   gboolean is_sticky = GST_EVENT_IS_STICKY (event);
+#ifdef TIZEN_FEATURE_TSDEMUX_MODIFICATION
+  GstStructure *structure = NULL;
+  GstCaps *caps = NULL;
+  gboolean caps_ret = FALSE;
+#endif
 
   GST_DEBUG_OBJECT (base, "Got event %s",
       gst_event_type_get_name (GST_EVENT_TYPE (event)));
@@ -1149,6 +1154,19 @@ mpegts_base_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
       break;
     case GST_EVENT_CAPS:
       /* FIXME, do something */
+#ifdef TIZEN_FEATURE_TSDEMUX_MODIFICATION
+      if (base->packetizer) {
+        gst_event_parse_caps (event, &caps);
+        GST_DEBUG_OBJECT (base, "got caps: %" GST_PTR_FORMAT, caps);
+
+        structure = gst_caps_get_structure (caps, 0);
+        caps_ret = gst_structure_get_boolean (structure, "is_live", &base->packetizer->is_live_stream);
+        if (caps_ret == FALSE)
+          base->packetizer->is_live_stream = TRUE;
+      } else {
+        GST_DEBUG_OBJECT (base, "base->packetizer pointer is NULL !!!");
+      }
+#endif
       gst_event_unref (event);
       break;
     case GST_EVENT_FLUSH_STOP:
index 1cdb9e9..7765afa 100644 (file)
@@ -272,6 +272,13 @@ mpegts_packetizer_init (MpegTSPacketizer2 * packetizer)
   packetizer->nb_seen_offsets = 0;
   packetizer->refoffset = -1;
   packetizer->last_in_time = GST_CLOCK_TIME_NONE;
+#ifdef TIZEN_FEATURE_TSDEMUX_MODIFICATION
+  packetizer->is_non_pcr_live_feed = FALSE;
+  packetizer->non_pcr_base_time = GST_CLOCK_TIME_NONE;
+  packetizer->last_live_pts = GST_CLOCK_TIME_NONE;
+  packetizer->last_live_pts_delta_apprx = GST_CLOCK_TIME_NONE;
+  packetizer->is_live_stream = FALSE;
+#endif
   packetizer->pcr_discont_threshold = GST_SECOND;
 }
 
@@ -443,6 +450,12 @@ mpegts_packetizer_parse_adaptation_field_control (MpegTSPacketizer2 *
     }
   }
 #endif
+#ifdef TIZEN_FEATURE_TSDEMUX_MODIFICATION
+  if ((afcflags == 0x00) && (!(afcflags & MPEGTS_AFC_PCR_FLAG)) && (packetizer->is_live_stream)) {
+    GST_DEBUG ("Non-PCR Live Stream Case !!");
+    packetizer->is_non_pcr_live_feed = TRUE;
+  }
+#endif
 
   return TRUE;
 }
@@ -582,6 +595,9 @@ mpegts_packetizer_clear (MpegTSPacketizer2 * packetizer)
   packetizer->map_size = 0;
   packetizer->map_offset = 0;
   packetizer->last_in_time = GST_CLOCK_TIME_NONE;
+#ifdef TIZEN_FEATURE_TSDEMUX_MODIFICATION
+  packetizer->is_live_stream = FALSE;
+#endif
 
   /* Close current PCR group */
   PACKETIZER_GROUP_LOCK (packetizer);
@@ -974,7 +990,7 @@ mpegts_packetizer_push_section (MpegTSPacketizer2 * packetizer,
    *  If it is not a PUSI
    *    Accumulate the expected data and check for complete section
    *    (loop)
-   *    
+   *
    **/
 
   if (packet->payload_unit_start_indicator) {
@@ -1914,7 +1930,7 @@ record_pcr (MpegTSPacketizer2 * packetizer, MpegTSPCR * pcrtable,
     GList *tmp;
     /* No current estimator. This happens for the initial value, or after
      * discont and flushes. Figure out where we need to record this position.
-     * 
+     *
      * Possible choices:
      * 1) No groups at all:
      *    Create a new group with pcr/offset
@@ -2294,7 +2310,36 @@ mpegts_packetizer_pts_to_ts (MpegTSPacketizer2 * packetizer,
           pts - PCRTIME_TO_GSTTIME (refpcr) + PCRTIME_TO_GSTTIME (refpcroffset);
     else
       GST_WARNING ("No groups, can't calculate timestamp");
-  } else
+  }
+#ifdef TIZEN_FEATURE_TSDEMUX_MODIFICATION
+  else if ((packetizer->is_non_pcr_live_feed) && (GST_CLOCK_TIME_IS_VALID(pts))) {
+    /*
+    [prasenjit.c] For Live Youtube Channels , PCR flag does not come.
+    Due to this , base offset of the content pts values are not obtained , so playback does not work.
+    Currently based on the flag is_non_pcr_live_feed set in mpegts_packetizer_parse_adaptation_field_control , we are rebasing the pts values.
+    */
+    GST_DEBUG ("non_pcr_base_time = %"GST_TIME_FORMAT" , last_live_pts = %"GST_TIME_FORMAT,
+          GST_TIME_ARGS (packetizer->non_pcr_base_time), GST_TIME_ARGS (packetizer->last_live_pts));
+    if(!GST_CLOCK_TIME_IS_VALID (packetizer->non_pcr_base_time)) {
+      GST_DEBUG ("PCR Base Time reset to Current PTS");
+      packetizer->non_pcr_base_time = pts;
+    } else if ((pts - packetizer->non_pcr_base_time) < packetizer->last_live_pts) {
+      GST_DEBUG ("Current PTS Less than Previous PTS !!");
+      GstClockTime delta = ABSDIFF ((pts - packetizer->non_pcr_base_time), packetizer->last_live_pts);
+      packetizer->non_pcr_base_time = packetizer->non_pcr_base_time - delta;
+    }
+
+    res = pts - packetizer->non_pcr_base_time;
+    packetizer->last_live_pts_delta_apprx = ABSDIFF (res, packetizer->last_live_pts);
+    packetizer->last_live_pts = res;
+  } else if ((packetizer->is_non_pcr_live_feed) &&
+             (GST_CLOCK_TIME_IS_VALID(packetizer->last_live_pts)) &&
+             (GST_CLOCK_TIME_IS_VALID(packetizer->last_live_pts_delta_apprx))) {
+    GST_DEBUG ("Invalid Live PTS : Resetting to last valid PTS");
+    res = packetizer->last_live_pts + (packetizer->last_live_pts_delta_apprx / 2);
+  }
+#endif
+  else
     GST_WARNING ("Not enough information to calculate proper timestamp");
 
   PACKETIZER_GROUP_UNLOCK (packetizer);
index be8bf37..af90268 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * mpegtspacketizer.h - 
+ * mpegtspacketizer.h -
  * Copyright (C) 2007 Alessandro Decina
- * 
+ *
  * Authors:
  *   Alessandro Decina <alessandro@nnva.org>
  *
@@ -277,7 +277,13 @@ struct _MpegTSPacketizer2 {
 
   /* Last inputted timestamp */
   GstClockTime last_in_time;
-
+#ifdef TIZEN_FEATURE_TSDEMUX_MODIFICATION
+  gboolean is_live_stream;
+  gboolean is_non_pcr_live_feed;
+  GstClockTime non_pcr_base_time;
+  GstClockTime last_live_pts;
+  GstClockTime last_live_pts_delta_apprx;
+#endif
   /* offset to observations table */
   guint8 pcrtablelut[0x2000];
   MpegTSPCR *observations[MAX_PCR_OBS_CHANNELS];
@@ -313,8 +319,8 @@ typedef struct
 typedef struct
 {
   guint8 table_id;
-  /* the spec says sub_table_extension is the fourth and fifth byte of a 
-   * section when the section_syntax_indicator is set to a value of "1". If 
+  /* the spec says sub_table_extension is the fourth and fifth byte of a
+   * section when the section_syntax_indicator is set to a value of "1". If
    * section_syntax_indicator is 0, sub_table_extension will be set to 0 */
   guint16  subtable_extension;
   guint8   version_number;
index c63657d..7ba7e46 100644 (file)
@@ -4,7 +4,7 @@
 
 Name:           gst-plugins-bad
 Version:        1.6.1
-Release:        7
+Release:        8
 Summary:        GStreamer Streaming-Media Framework Plug-Ins
 License:        LGPL-2.0+
 Group:          Multimedia/Framework
@@ -78,7 +78,7 @@ processing capabilities can be added simply by installing new plug-ins.
 %build
 export V=1
 NOCONFIGURE=1 ./autogen.sh
-export CFLAGS+=" -Wall -g -fPIC -DTIZEN_FEATURE_WLSINK_ENHANCEMENT -DTIZEN_FEATURE_AVOID_PAD_SWITCHING -DTIZEN_FEATURE_ADAPTIVE_MODIFICATION"
+export CFLAGS+=" -Wall -g -fPIC -DTIZEN_FEATURE_WLSINK_ENHANCEMENT -DTIZEN_FEATURE_AVOID_PAD_SWITCHING -DTIZEN_FEATURE_ADAPTIVE_MODIFICATION -DTIZEN_FEATURE_TSDEMUX_MODIFICATION"
 %configure\
        --disable-static\
        --disable-examples\