From 03b1790e0dde43296e060a96ffabd1762d7a34f5 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Fri, 4 Mar 2022 14:17:47 +0100 Subject: [PATCH] tsdemux: Handle PES headers bigger than a mpeg-ts packet While the actual PES header parser could notify us that it needed more data, we would never actually act on it. This commit will accumulate incoming packets in such situation and re-attempt the header parsing. Fixes #1027 Part-of: --- .../gst-plugins-bad/gst/mpegtsdemux/tsdemux.c | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/subprojects/gst-plugins-bad/gst/mpegtsdemux/tsdemux.c b/subprojects/gst-plugins-bad/gst/mpegtsdemux/tsdemux.c index fb19acf4eb..73e1c063e5 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsdemux/tsdemux.c +++ b/subprojects/gst-plugins-bad/gst/mpegtsdemux/tsdemux.c @@ -172,6 +172,10 @@ struct _TSDemuxStream /* Output data */ PendingPacketState state; + /* PES header being reconstructed (optional, allocated) */ + guint8 *pending_header_data; + guint pending_header_size; + /* Data being reconstructed (allocated) */ guint8 *data; @@ -2144,6 +2148,9 @@ gst_ts_demux_stream_flush (TSDemuxStream * stream, GstTSDemux * tsdemux, g_free (stream->data); stream->data = NULL; + g_free (stream->pending_header_data); + stream->pending_header_data = NULL; + stream->pending_header_size = 0; stream->state = PENDING_PACKET_EMPTY; stream->expected_size = 0; stream->allocated_size = 0; @@ -2598,9 +2605,26 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream, GST_MEMDUMP ("Header buffer", data, MIN (length, 32)); + if (G_UNLIKELY (stream->pending_header_data)) { + /* Accumulate with previous header if present */ + stream->pending_header_data = + g_realloc (stream->pending_header_data, + stream->pending_header_size + length); + memcpy (stream->pending_header_data + stream->pending_header_size, data, + length); + data = stream->pending_header_data; + length = stream->pending_header_size + length; + } + parseres = mpegts_parse_pes_header (data, length, &header); - if (G_UNLIKELY (parseres == PES_PARSING_NEED_MORE)) - goto discont; + + if (G_UNLIKELY (parseres == PES_PARSING_NEED_MORE)) { + /* This can happen if PES header is bigger than a packet. */ + if (!stream->pending_header_data) + stream->pending_header_data = g_memdup2 (data, length); + stream->pending_header_size = length; + return; + } if (G_UNLIKELY (parseres == PES_PARSING_BAD)) { GST_WARNING ("Error parsing PES header. pid: 0x%x stream_type: 0x%x", stream->stream.pid, stream->stream.stream_type); @@ -2660,9 +2684,20 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream, stream->state = PENDING_PACKET_BUFFER; + if (stream->pending_header_data) { + g_free (stream->pending_header_data); + stream->pending_header_data = NULL; + stream->pending_header_size = 0; + } + return; discont: + if (stream->pending_header_data) { + g_free (stream->pending_header_data); + stream->pending_header_data = NULL; + stream->pending_header_size = 0; + } stream->state = PENDING_PACKET_DISCONT; return; } @@ -2699,6 +2734,10 @@ gst_ts_demux_queue_data (GstTSDemux * demux, TSDemuxStream * stream, g_free (stream->data); stream->data = NULL; } + if (G_UNLIKELY (stream->pending_header_data)) { + g_free (stream->pending_header_data); + stream->pending_header_data = NULL; + } stream->state = PENDING_PACKET_HEADER; } else { GST_ELEMENT_WARNING_WITH_DETAILS (demux, STREAM, DEMUX, @@ -2754,6 +2793,10 @@ gst_ts_demux_queue_data (GstTSDemux * demux, TSDemuxStream * stream, g_free (stream->data); stream->data = NULL; } + if (G_UNLIKELY (stream->pending_header_data)) { + g_free (stream->pending_header_data); + stream->pending_header_data = NULL; + } stream->continuity_counter = CONTINUITY_UNSET; break; }