summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaud Vrac <avrac@freebox.fr>2013-05-27 22:22:32 +0200
committerEdward Hervey <edward@collabora.com>2013-06-12 08:01:24 +0200
commita5402d6eeb42e1b3f7ae986340ff6f3753dd69b4 (patch)
tree57bb2da588efec391f76b118b55d17a7f44ea939
parent065d421d34908eedabfe0690d77436e1dd9aa046 (diff)
tsdemux: fix M2TS stream resync
Sync byte scan is incorrect for M2TS streams because the timestamp 4 bytes were not included in the flush size. This can result in an infinite loop. Rework the scan code to be clearer and work in all cases.
-rw-r--r--gst/mpegtsdemux/mpegtspacketizer.c60
1 files changed, 28 insertions, 32 deletions
diff --git a/gst/mpegtsdemux/mpegtspacketizer.c b/gst/mpegtsdemux/mpegtspacketizer.c
index a19c3909c..40f620d26 100644
--- a/gst/mpegtsdemux/mpegtspacketizer.c
+++ b/gst/mpegtsdemux/mpegtspacketizer.c
@@ -2636,67 +2636,63 @@ mpegts_packetizer_next_packet (MpegTSPacketizer2 * packetizer,
MpegTSPacketizerPacket * packet)
{
MpegTSPacketizerPrivate *priv = packetizer->priv;
- guint avail;
- int i;
+ guint skip;
+ guint sync_offset;
if (G_UNLIKELY (!packetizer->know_packet_size)) {
if (!mpegts_try_discover_packet_size (packetizer))
return PACKET_NEED_MORE;
}
- while ((avail = priv->available) >= packetizer->packet_size) {
+ while (priv->available >= packetizer->packet_size) {
if (priv->mapped == NULL) {
- priv->mapped_size =
- priv->available - (priv->available % packetizer->packet_size);
+ priv->mapped_size = priv->available;
priv->mapped =
(guint8 *) gst_adapter_map (packetizer->adapter, priv->mapped_size);
priv->offset = 0;
}
- packet->data_start = priv->mapped + priv->offset;
/* M2TS packets don't start with the sync byte, all other variants do */
+ sync_offset = priv->offset;
if (packetizer->packet_size == MPEGTS_M2TS_PACKETSIZE)
- packet->data_start += 4;
-
- /* ALL mpeg-ts variants contain 188 bytes of data. Those with bigger packet
- * sizes contain either extra data (timesync, FEC, ..) either before or after
- * the data */
- packet->data_end = packet->data_start + 188;
- packet->offset = packetizer->offset;
- GST_LOG ("offset %" G_GUINT64_FORMAT, packet->offset);
- packetizer->offset += packetizer->packet_size;
- GST_MEMDUMP ("data_start", packet->data_start, 16);
- packet->origts = priv->last_in_time;
+ sync_offset += 4;
/* Check sync byte */
- if (G_LIKELY (packet->data_start[0] == 0x47))
+ if (G_LIKELY (priv->mapped[sync_offset] == 0x47)) {
+ /* ALL mpeg-ts variants contain 188 bytes of data. Those with bigger
+ * packet sizes contain either extra data (timesync, FEC, ..) either
+ * before or after the data */
+ packet->data_start = priv->mapped + sync_offset;
+ packet->data_end = packet->data_start + 188;
+ packet->offset = packetizer->offset;
+ GST_LOG ("offset %" G_GUINT64_FORMAT, packet->offset);
+ packetizer->offset += packetizer->packet_size;
+ GST_MEMDUMP ("data_start", packet->data_start, 16);
+ packet->origts = priv->last_in_time;
goto got_valid_packet;
+ }
GST_LOG ("Lost sync %d", packetizer->packet_size);
/* Find the 0x47 in the buffer */
- for (i = 0; i < packetizer->packet_size; i++)
- if (packet->data_start[i] == 0x47)
+ for (; sync_offset < priv->mapped_size; sync_offset++)
+ if (priv->mapped[sync_offset] == 0x47)
break;
- if (packetizer->packet_size == MPEGTS_M2TS_PACKETSIZE) {
- if (i >= 4)
- i -= 4;
- else
- i += 188;
- }
-
- GST_DEBUG ("Flushing %d bytes out", i);
- /* gst_adapter_flush (packetizer->adapter, i); */
/* Pop out the remaining data... */
- priv->offset += i;
- priv->available -= i;
+ skip = sync_offset - priv->offset;
+ if (packetizer->packet_size == MPEGTS_M2TS_PACKETSIZE)
+ skip -= 4;
+
+ priv->available -= skip;
+ priv->offset += skip;
+ packetizer->offset += skip;
+
if (G_UNLIKELY (priv->available < packetizer->packet_size)) {
GST_DEBUG ("Flushing %d bytes out", priv->offset);
gst_adapter_flush (packetizer->adapter, priv->offset);
priv->mapped = NULL;
}
- continue;
}
return PACKET_NEED_MORE;