mpegtspacketizer: Handle PCR issues with adaptive streams
authorEdward Hervey <edward@centricular.com>
Mon, 9 Nov 2020 17:27:14 +0000 (18:27 +0100)
committerEdward Hervey <bilboed@bilboed.com>
Mon, 9 Nov 2020 17:30:51 +0000 (18:30 +0100)
A lot of content producers out there targetting "adaptive streaming" are riddled
with non-compliant PCR streams (essentially all the players out there just use
PTS/DTS and don't care about the PCR).

In order to gracefully cope with these, we detect them appropriately and any
small (< 15s) PCR resets get gracefully ignored.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1785>

gst/mpegtsdemux/mpegtspacketizer.c

index 8816dacd0bd59a66322953602a8f7f3826cd0def..a0ba2a5e7b6382648b221e4cabc74c59faf1bec6 100644 (file)
@@ -1386,7 +1386,19 @@ calculate_skew (MpegTSPacketizer2 * packetizer,
       /* Small jumps backward, assume some arrival jitter and skip it */
       send_diff = 0;
 
-      if (pcr->last_pcrtime - gstpcrtime < GST_SECOND) {
+      /* The following code are the different ways we deal with small-ish
+       * jitter, ranging in severity from "can be ignored" to "this needs a full
+       * resync" */
+
+      if (time == pcr->base_time) {
+        /* If this comes from a non-fully-timestamped source (i.e. adaptive
+         * streams), then cope with the fact that some producers generate utter
+         * PCR garbage on fragment ends.
+         *
+         * We detect this comes from a non-fully-timestamped source by the fact
+         * that the buffer time never changes */
+        GST_DEBUG ("Ignoring PCR resets on non-fully timestamped stream");
+      } else if (pcr->last_pcrtime - gstpcrtime < GST_SECOND) {
         GST_WARNING
             ("(small) backward timestamps at server or no buffer timestamps. Ignoring.");
         /* This will trigger the no_skew logic before but leave other state
@@ -1444,8 +1456,8 @@ calculate_skew (MpegTSPacketizer2 * packetizer,
    * changed too quickly we have to resync because the server likely restarted
    * its timestamps. */
   if (ABS (delta - pcr->skew) > packetizer->pcr_discont_threshold) {
-    GST_WARNING ("delta - skew: %" GST_TIME_FORMAT " too big, reset skew",
-        GST_TIME_ARGS (delta - pcr->skew));
+    GST_WARNING ("delta - skew: %" GST_STIME_FORMAT " too big, reset skew",
+        GST_STIME_ARGS (delta - pcr->skew));
     mpegts_packetizer_resync (pcr, time, gstpcrtime, TRUE);
     send_diff = 0;
     delta = 0;