tsdemux: Check the continuity counter for non-section packets too

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.
This commit is contained in:
Sebastian Dröge 2013-04-11 13:08:57 +02:00
parent 2991e1ed48
commit 2713fd1058

View file

@ -55,6 +55,9 @@
#define TABLE_ID_UNSET 0xFF #define TABLE_ID_UNSET 0xFF
#define CONTINUITY_UNSET 255
#define MAX_CONTINUITY 15
#define PCR_WRAP_SIZE_128KBPS (((gint64)1490)*(1024*1024)) #define PCR_WRAP_SIZE_128KBPS (((gint64)1490)*(1024*1024))
/* small PCR for wrap detection */ /* small PCR for wrap detection */
#define PCR_SMALL 17775000 #define PCR_SMALL 17775000
@ -148,6 +151,8 @@ struct _TSDemuxStream
gboolean need_newsegment; gboolean need_newsegment;
GstTagList *taglist; GstTagList *taglist;
gint continuity_counter;
}; };
#define VIDEO_CAPS \ #define VIDEO_CAPS \
@ -1038,6 +1043,7 @@ gst_ts_demux_stream_added (MpegTSBase * base, MpegTSBaseStream * bstream,
stream->fixed_dts = 0; stream->fixed_dts = 0;
stream->nb_pts_rollover = 0; stream->nb_pts_rollover = 0;
stream->nb_dts_rollover = 0; stream->nb_dts_rollover = 0;
stream->continuity_counter = CONTINUITY_UNSET;
} }
stream->flow_return = GST_FLOW_OK; stream->flow_return = GST_FLOW_OK;
} }
@ -1122,6 +1128,7 @@ gst_ts_demux_stream_flush (TSDemuxStream * stream)
if (stream->flow_return == GST_FLOW_FLUSHING) { if (stream->flow_return == GST_FLOW_FLUSHING) {
stream->flow_return = GST_FLOW_OK; stream->flow_return = GST_FLOW_OK;
} }
stream->continuity_counter = CONTINUITY_UNSET;
} }
static void static void
@ -1340,11 +1347,24 @@ gst_ts_demux_queue_data (GstTSDemux * demux, TSDemuxStream * stream,
guint8 *data; guint8 *data;
guint size; 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; size = packet->data_end - packet->payload;
data = 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 (stream->state == PENDING_PACKET_EMPTY) {
if (G_UNLIKELY (!packet->payload_unit_start_indicator)) { if (G_UNLIKELY (!packet->payload_unit_start_indicator)) {
stream->state = PENDING_PACKET_DISCONT; stream->state = PENDING_PACKET_DISCONT;
@ -1383,6 +1403,7 @@ gst_ts_demux_queue_data (GstTSDemux * demux, TSDemuxStream * stream,
g_free (stream->data); g_free (stream->data);
stream->data = NULL; stream->data = NULL;
} }
stream->continuity_counter = CONTINUITY_UNSET;
break; break;
} }
default: default: