tsdemux: Check the continuity counter for non-section packets too
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Thu, 11 Apr 2013 11:08:57 +0000 (13:08 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Thu, 11 Apr 2013 11:11:44 +0000 (13:11 +0200)
And if we detect a discontinuity there (like... when losing packets
or having MPEGTS over raw UDP with out-of-order packets) we just
drop the corresponding packet.

A future version could try to implement a re-ordering algorithm based
on that, similar to what rtpjitterbuffer does.

gst/mpegtsdemux/tsdemux.c

index c3e0d93..03a3fba 100644 (file)
@@ -55,6 +55,9 @@
 
 #define TABLE_ID_UNSET 0xFF
 
+#define CONTINUITY_UNSET 255
+#define MAX_CONTINUITY 15
+
 #define PCR_WRAP_SIZE_128KBPS (((gint64)1490)*(1024*1024))
 /* small PCR for wrap detection */
 #define PCR_SMALL 17775000
@@ -148,6 +151,8 @@ struct _TSDemuxStream
   gboolean need_newsegment;
 
   GstTagList *taglist;
+
+  gint continuity_counter;
 };
 
 #define VIDEO_CAPS \
@@ -1038,6 +1043,7 @@ gst_ts_demux_stream_added (MpegTSBase * base, MpegTSBaseStream * bstream,
     stream->fixed_dts = 0;
     stream->nb_pts_rollover = 0;
     stream->nb_dts_rollover = 0;
+    stream->continuity_counter = CONTINUITY_UNSET;
   }
   stream->flow_return = GST_FLOW_OK;
 }
@@ -1122,6 +1128,7 @@ gst_ts_demux_stream_flush (TSDemuxStream * stream)
   if (stream->flow_return == GST_FLOW_FLUSHING) {
     stream->flow_return = GST_FLOW_OK;
   }
+  stream->continuity_counter = CONTINUITY_UNSET;
 }
 
 static void
@@ -1340,11 +1347,24 @@ gst_ts_demux_queue_data (GstTSDemux * demux, TSDemuxStream * stream,
   guint8 *data;
   guint size;
 
-  GST_DEBUG ("state:%d", stream->state);
+  GST_DEBUG ("pid: 0x%04x state:%d", stream->stream.pid, stream->state);
 
   size = packet->data_end - packet->payload;
   data = packet->payload;
 
+  if (stream->continuity_counter == CONTINUITY_UNSET) {
+    GST_DEBUG ("CONTINUITY: Initialize to %d", packet->continuity_counter);
+  } else if ((packet->continuity_counter == stream->continuity_counter + 1 ||
+          (stream->continuity_counter == MAX_CONTINUITY &&
+              packet->continuity_counter == 0))) {
+    GST_LOG ("CONTINUITY: Got expected %d", packet->continuity_counter);
+  } else {
+    GST_ERROR ("CONTINUITY: Mismatch packet %d, stream %d",
+        packet->continuity_counter, stream->continuity_counter);
+    stream->state = PENDING_PACKET_DISCONT;
+  }
+  stream->continuity_counter = packet->continuity_counter;
+
   if (stream->state == PENDING_PACKET_EMPTY) {
     if (G_UNLIKELY (!packet->payload_unit_start_indicator)) {
       stream->state = PENDING_PACKET_DISCONT;
@@ -1383,6 +1403,7 @@ gst_ts_demux_queue_data (GstTSDemux * demux, TSDemuxStream * stream,
         g_free (stream->data);
         stream->data = NULL;
       }
+      stream->continuity_counter = CONTINUITY_UNSET;
       break;
     }
     default: