File gstreamer-mpegdemux-Handle-system-header-timestamp.patch of Package gstreamer-plugins-bad
From b6d5aac1c057ad67e983bb3de99a702f23a2dde6 Mon Sep 17 00:00:00 2001
From: Jan Schmidt <jan@centricular.com>
Date: Sun, 15 May 2016 19:05:48 +1000
Subject: [PATCH] mpegdemux: Handle system header when scanning for timestamps.
When scanning for SCR / PTS / DTS, handle the case where
the pack header is followed by the optional system header,
so we can correctly collect timestamps in such cases.
https://bugzilla.gnome.org/show_bug.cgi?id=623860
---
gst/mpegdemux/gstmpegdemux.c | 32 ++++++++++++++++++++++++++++----
1 file changed, 28 insertions(+), 4 deletions(-)
diff --git a/gst/mpegdemux/gstmpegdemux.c b/gst/mpegdemux/gstmpegdemux.c
index 3a7229d..68985b2 100644
--- a/gst/mpegdemux/gstmpegdemux.c
+++ b/gst/mpegdemux/gstmpegdemux.c
@@ -2401,13 +2401,14 @@ gst_ps_demux_is_pes_sync (guint32 sync)
static inline gboolean
gst_ps_demux_scan_ts (GstPsDemux * demux, const guint8 * data,
- SCAN_MODE mode, guint64 * rts)
+ SCAN_MODE mode, guint64 * rts, const guint8 * end)
{
gboolean ret = FALSE;
guint32 scr1, scr2;
guint64 scr;
guint64 pts, dts;
guint32 code;
+ guint16 len;
/* read the 4 bytes for the sync code */
code = GST_READ_UINT32_BE (data);
@@ -2422,6 +2423,7 @@ gst_ps_demux_scan_ts (GstPsDemux * demux, const guint8 * data,
/* start parsing the stream */
if ((*data & 0xc0) == 0x40) {
+ /* MPEG-2 PACK header */
guint32 scr_ext;
guint32 next32;
guint8 stuffing_bytes;
@@ -2461,6 +2463,7 @@ gst_ps_demux_scan_ts (GstPsDemux * demux, const guint8 * data,
goto beach;
}
} else {
+ /* MPEG-1 pack header */
/* check markers */
if ((scr1 & 0xf1000100) != 0x21000100)
goto beach;
@@ -2482,8 +2485,27 @@ gst_ps_demux_scan_ts (GstPsDemux * demux, const guint8 * data,
goto beach;
}
- /* read the 4 bytes for the PES sync code */
+ /* Possible optional System header here */
code = GST_READ_UINT32_BE (data);
+ len = GST_READ_UINT16_BE (data + 4);
+
+ if (code == ID_PS_SYSTEM_HEADER_START_CODE) {
+ /* Found a system header, skip it */
+ /* Check for sufficient data - system header, plus enough
+ * left over for the PES packet header */
+ if (data + 6 + len + 6 > end)
+ return FALSE;
+ data += len + 6;
+
+ /* read the 4 bytes for the PES sync code */
+ code = GST_READ_UINT32_BE (data);
+ len = GST_READ_UINT16_BE (data + 4);
+ }
+
+ /* Check we have enough data left for reading the PES packet */
+ if (data + 6 + len > end)
+ return FALSE;
+
if (!gst_ps_demux_is_pes_sync (code))
goto beach;
@@ -2626,7 +2648,8 @@ gst_ps_demux_scan_forward_ts (GstPsDemux * demux, guint64 * pos,
/* scan the block */
for (cursor = 0; !found && cursor <= end_scan; cursor++) {
- found = gst_ps_demux_scan_ts (demux, map.data + cursor, mode, &ts);
+ found = gst_ps_demux_scan_ts (demux, map.data + cursor, mode, &ts,
+ map.data + map.size);
}
/* done with the buffer, unref it */
@@ -2694,7 +2717,8 @@ gst_ps_demux_scan_backward_ts (GstPsDemux * demux, guint64 * pos,
/* scan the block */
for (cursor = (start_scan + 1); !found && cursor > 0; cursor--) {
- found = gst_ps_demux_scan_ts (demux, data--, mode, &ts);
+ found = gst_ps_demux_scan_ts (demux, data--, mode, &ts,
+ map.data + map.size);
}
/* done with the buffer, unref it */
--
2.6.6