File gstreamer-psmux-rewrite.patch of Package gstreamer-plugins-bad
From 96f9b83eed617886fefa0ec5682e072f65eafc8b Mon Sep 17 00:00:00 2001
From: Jan Schmidt <jan@centricular.com>
Date: Wed, 1 Feb 2017 14:25:32 +1100
Subject: [PATCH] psdemux: Rewrite PSM parsing using GstByteReader
Avoid possible buffer overflows and ignore invalid PSM packets better
by using GstByteReader.
https://bugzilla.gnome.org/show_bug.cgi?id=777957
Backported by Mike Gorse <mgorse@suse.com>
---
diff -urp gst-plugins-bad-1.8.3.orig/gst/mpegdemux/gstmpegdemux.c gst-plugins-bad-1.8.3/gst/mpegdemux/gstmpegdemux.c
--- gst-plugins-bad-1.8.3.orig/gst/mpegdemux/gstmpegdemux.c 2017-03-02 11:39:54.833318377 -0600
+++ gst-plugins-bad-1.8.3/gst/mpegdemux/gstmpegdemux.c 2017-03-02 11:41:01.193319588 -0600
@@ -50,6 +50,7 @@
#include <gst/tag/tag.h>
#include <gst/pbutils/pbutils.h>
+#include <gst/base/gstbytereader.h>
#include "gstmpegdefs.h"
#include "gstmpegdemux.h"
@@ -2062,42 +2063,48 @@ need_more_data:
static GstFlowReturn
gst_ps_demux_parse_psm (GstPsDemux * demux)
{
- guint16 length = 0, info_length = 0, es_map_length = 0;
+ guint16 psm_length, info_length = 0, es_map_length = 0;
guint8 psm_version = 0;
- const guint8 *data, *es_map_base;
+ GstByteReader br;
#ifndef GST_DISABLE_GST_DEBUG
gboolean applicable;
#endif
+ /* Need at least 6 bytes for start code + length */
if (gst_adapter_available (demux->adapter) < 6)
goto need_more_data;
- /* start code + length */
- data = gst_adapter_map (demux->adapter, 6);
-
- /* skip start code */
- data += 4;
+ {
+ const guint8 *data;
- length = GST_READ_UINT16_BE (data);
- GST_DEBUG_OBJECT (demux, "length %u", length);
+ /* start code + length */
+ data = gst_adapter_map (demux->adapter, 6);
+ /* skip start code */
+ data += 4;
+ psm_length = GST_READ_UINT16_BE (data);
+ GST_DEBUG_OBJECT (demux, "PSM length %u", psm_length);
- if (G_UNLIKELY (length > 0x3FA))
- goto psm_len_error;
+ if (G_UNLIKELY (psm_length > 0x3FA))
+ goto psm_len_error;
+ psm_length += 6; /* Add start code + size to length */
- length += 6;
+ gst_adapter_unmap (demux->adapter);
- gst_adapter_unmap (demux->adapter);
+ if (gst_adapter_available (demux->adapter) < psm_length)
+ goto need_more_data;
- if (gst_adapter_available (demux->adapter) < length)
- goto need_more_data;
+ data = gst_adapter_map (demux->adapter, psm_length);
- data = gst_adapter_map (demux->adapter, length);
+ gst_byte_reader_init (&br, data, psm_length);
+ }
/* skip start code and length */
- data += 6;
+ if (!gst_byte_reader_skip (&br, 6))
+ goto fail_invalid;
/* Read PSM applicable bit together with version */
- psm_version = GST_READ_UINT8 (data);
+ if (!gst_byte_reader_get_uint8 (&br, &psm_version))
+ goto fail_invalid;
#ifndef GST_DISABLE_GST_DEBUG
applicable = (psm_version & 0x80) >> 7;
#endif
@@ -2105,62 +2112,70 @@ gst_ps_demux_parse_psm (GstPsDemux * dem
GST_DEBUG_OBJECT (demux, "PSM version %u (applicable now %u)", psm_version,
applicable);
- /* Jump over version and marker bit */
- data += 2;
+ /* Jump over the next byte (marker bit) */
+ if (!gst_byte_reader_skip (&br, 1))
+ goto fail_invalid;
/* Read PS info length */
- info_length = GST_READ_UINT16_BE (data);
- /* Cap it to PSM length - needed bytes for ES map length and CRC */
- info_length = MIN (length - 16, info_length);
+ if (!gst_byte_reader_get_uint16_be (&br, &info_length))
+ goto fail_invalid;
GST_DEBUG_OBJECT (demux, "PS info length %u bytes", info_length);
-
- /* Jump over that section */
- data += (2 + info_length);
+ /* Skip the PS info, we don't use it */
+ if (!gst_byte_reader_skip (&br, info_length))
+ goto fail_invalid;
/* Read ES map length */
- es_map_length = GST_READ_UINT16_BE (data);
- /* Cap it to PSM remaining length - CRC */
- es_map_length = MIN (length - (16 + info_length), es_map_length);
+ if (!gst_byte_reader_get_uint16_be (&br, &es_map_length))
+ goto fail_invalid;
GST_DEBUG_OBJECT (demux, "ES map length %u bytes", es_map_length);
- /* Jump over the size */
- data += 2;
-
/* Now read the ES map */
- es_map_base = data;
- while (es_map_base + 4 <= data + es_map_length) {
- guint8 stream_type = 0, stream_id = 0;
- guint16 stream_info_length = 0;
-
- stream_type = GST_READ_UINT8 (es_map_base);
- es_map_base++;
- stream_id = GST_READ_UINT8 (es_map_base);
- es_map_base++;
- stream_info_length = GST_READ_UINT16_BE (es_map_base);
- es_map_base += 2;
- /* Cap stream_info_length */
- stream_info_length = MIN (data + es_map_length - es_map_base,
- stream_info_length);
-
- GST_DEBUG_OBJECT (demux, "Stream type %02X with id %02X and %u bytes info",
- stream_type, stream_id, stream_info_length);
- if (G_LIKELY (stream_id != 0xbd))
- demux->psm[stream_id] = stream_type;
- else {
- /* Ignore stream type for private_stream_1 and discover it looking at
- * the stream data.
- * Fixes demuxing some clips with lpcm that was wrongly declared as
- * mpeg audio */
- GST_DEBUG_OBJECT (demux, "stream type for private_stream_1 ignored");
+ {
+ GstByteReader es_map_br;
+ if (!gst_byte_reader_get_sub_reader (&br, &es_map_br, es_map_length))
+ goto fail_invalid;
+
+ while (gst_byte_reader_get_remaining (&es_map_br) >= 4) {
+ guint8 stream_type = 0, stream_id = 0;
+ guint16 stream_info_length = 0;
+
+ if (!gst_byte_reader_get_uint8 (&es_map_br, &stream_type) ||
+ !gst_byte_reader_get_uint8 (&es_map_br, &stream_id) ||
+ !gst_byte_reader_get_uint16_be (&es_map_br, &stream_info_length))
+ break;
+
+ GST_DEBUG_OBJECT (demux,
+ "Stream type %02X with id %02X and %u bytes info", stream_type,
+ stream_id, stream_info_length);
+
+ if (G_LIKELY (stream_id != 0xbd))
+ demux->psm[stream_id] = stream_type;
+ else {
+ /* Ignore stream type for private_stream_1 and discover it looking at
+ * the stream data.
+ * Fixes demuxing some clips with lpcm that was wrongly declared as
+ * mpeg audio */
+ GST_DEBUG_OBJECT (demux, "stream type for private_stream_1 ignored");
+ }
+
+ /* FIXME: We could use the descriptors instead of skipping them */
+ if (!gst_byte_reader_skip (&es_map_br, stream_info_length))
+ break;
}
- es_map_base += stream_info_length;
}
+ /* We ignore the 4-byte CRC at the end */
gst_adapter_unmap (demux->adapter);
- gst_adapter_flush (demux->adapter, length);
- ADAPTER_OFFSET_FLUSH (length);
+ gst_adapter_flush (demux->adapter, psm_length);
+ ADAPTER_OFFSET_FLUSH (psm_length);
return GST_FLOW_OK;
+fail_invalid:
+ GST_DEBUG_OBJECT (demux, "Failed to parse PSM. Skipping");
+ gst_adapter_unmap (demux->adapter);
+ gst_adapter_flush (demux->adapter, psm_length);
+ ADAPTER_OFFSET_FLUSH (psm_length);
+ return GST_FLOW_LOST_SYNC;
psm_len_error:
{
GST_DEBUG_OBJECT (demux, "error in PSM length");
@@ -2191,13 +2206,10 @@ gst_ps_demux_data_cb (GstPESFilter * fil
GstMapInfo map;
gsize datalen;
guint offset = 0;
-
gst_buffer_map (buffer, &map, GST_MAP_READ);
datalen = map.size;
-
start_code = filter->start_code;
id = filter->id;
-
if (first) {
/* find the stream type */
stream_type = demux->psm[id];
@@ -2208,7 +2220,6 @@ gst_ps_demux_data_cb (GstPESFilter * fil
* (see ftp://ftp.mplayerhq.hu/MPlayer/samples/MPEG-VOB/vdr-AC3) */
if (datalen >= 4) {
guint hdr = GST_READ_UINT32_BE (map.data);
-
if (G_UNLIKELY ((hdr & 0xffff0000) == AC3_SYNC_WORD)) {
id = 0x80;
stream_type = demux->psm[id] = ST_GST_AUDIO_RAWA52;
@@ -2220,10 +2231,8 @@ gst_ps_demux_data_cb (GstPESFilter * fil
/* new id is in the first byte */
id = map.data[offset++];
datalen--;
-
/* and remap */
stream_type = demux->psm[id];
-
/* Now, if it's a subpicture stream - no more, otherwise
* take the first byte too, since it's the frame count in audio
* streams and our backwards compat convention is to strip it off */
@@ -2231,7 +2240,6 @@ gst_ps_demux_data_cb (GstPESFilter * fil
/* Number of audio frames in this packet */
#ifndef GST_DISABLE_GST_DEBUG
guint8 nframes;
-
nframes = map.data[offset];
GST_LOG_OBJECT (demux, "private type 0x%02x, %d frames", id,
nframes);
@@ -2239,8 +2247,8 @@ gst_ps_demux_data_cb (GstPESFilter * fil
offset++;
datalen--;
} else {
- GST_LOG_OBJECT (demux, "private type 0x%02x, stream type %d", id,
- stream_type);
+ GST_LOG_OBJECT (demux, "private type 0x%02x, stream type %d",
+ id, stream_type);
}
}
}
@@ -2253,7 +2261,6 @@ gst_ps_demux_data_cb (GstPESFilter * fil
" (%" G_GUINT64_FORMAT ")", id, filter->pts, demux->next_pts);
} else
demux->next_pts = G_MAXUINT64;
-
if (filter->dts != -1) {
demux->next_dts = filter->dts + demux->scr_adjust;
GST_LOG_OBJECT (demux, "stream 0x%02x DTS = orig %" G_GUINT64_FORMAT
@@ -2290,7 +2297,6 @@ gst_ps_demux_data_cb (GstPESFilter * fil
if (demux->current_stream->notlinked == FALSE) {
out_buf =
gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, offset, datalen);
-
ret = gst_ps_demux_send_data (demux, demux->current_stream, out_buf);
if (ret == GST_FLOW_NOT_LINKED) {
demux->current_stream->notlinked = TRUE;
@@ -2300,9 +2306,7 @@ gst_ps_demux_data_cb (GstPESFilter * fil
done:
gst_buffer_unmap (buffer, &map);
gst_buffer_unref (buffer);
-
return ret;
-
/* ERRORS */
unknown_stream_type:
{
@@ -2320,17 +2324,13 @@ gst_ps_demux_resync (GstPsDemux * demux,
guint32 code;
gint offset;
gboolean found;
-
avail = gst_adapter_available (demux->adapter);
if (G_UNLIKELY (avail < 4))
goto need_data;
-
/* Common case, read 4 bytes an check it */
data = gst_adapter_map (demux->adapter, 4);
-
/* read currect code */
code = GST_READ_UINT32_BE (data);
-
/* The common case is that the sync code is at 0 bytes offset */
if (G_LIKELY ((code & 0xffffff00) == 0x100L)) {
GST_LOG_OBJECT (demux, "Found resync code %08x after 0 bytes", code);
@@ -2344,16 +2344,12 @@ gst_ps_demux_resync (GstPsDemux * demux,
offset = 4;
if (offset >= avail)
goto need_data; /* Not enough data to find sync */
-
data = gst_adapter_map (demux->adapter, avail);
-
do {
code = (code << 8) | data[offset++];
found = (code & 0xffffff00) == 0x100L;
} while (offset < avail && !found);
-
gst_adapter_unmap (demux->adapter);
-
if (!save || demux->sink_segment.rate >= 0.0) {
GST_LOG_OBJECT (demux, "flushing %d bytes", offset - 4);
/* forward playback, we can discard and flush the skipped bytes */
@@ -2384,7 +2380,6 @@ gst_ps_demux_resync (GstPsDemux * demux,
}
return found;
-
need_data:
{
GST_LOG_OBJECT (demux, "we need more data for resync %d", avail);
@@ -2455,7 +2450,6 @@ gst_ps_demux_scan_ts (GstPsDemux * demux
next32 = GST_READ_UINT32_BE (data);
if ((next32 & 0x00000300) != 0x00000300)
goto beach;
-
stuffing_bytes = (next32 & 0x07);
data += 4;
while (stuffing_bytes--) {
@@ -2467,10 +2461,8 @@ gst_ps_demux_scan_ts (GstPsDemux * demux
/* check markers */
if ((scr1 & 0xf1000100) != 0x21000100)
goto beach;
-
if ((scr2 & 0x01800001) != 0x01800001)
goto beach;
-
/* :4=0010 ! scr:3 ! marker:1==1 ! scr:15 ! marker:1==1 ! scr:15 ! marker:1==1 */
scr = ((guint64) scr1 & 0x0e000000) << 5;
scr |= ((guint64) scr1 & 0x00fffe00) << 6;
@@ -2525,9 +2517,7 @@ gst_ps_demux_scan_ts (GstPsDemux * demux
/* skip sync code and size */
data += 6;
-
pts = dts = -1;
-
/* stuffing bits, first two bits are '10' for mpeg2 pes so this code is
* not triggered. */
while (TRUE) {
@@ -2539,7 +2529,6 @@ gst_ps_demux_scan_ts (GstPsDemux * demux
/* STD buffer size, never for mpeg2 */
if ((*data & 0xc0) == 0x40)
data += 2;
-
/* PTS but no DTS, never for mpeg2 */
if ((*data & 0xf0) == 0x20) {
READ_TS (data, pts, beach);
@@ -2551,7 +2540,6 @@ gst_ps_demux_scan_ts (GstPsDemux * demux
} else if ((*data & 0xc0) == 0x80) {
/* mpeg2 case */
guchar flags;
-
/* 2: '10'
* 2: PES_scrambling_control
* 1: PES_priority
@@ -2560,10 +2548,8 @@ gst_ps_demux_scan_ts (GstPsDemux * demux
* 1: original_or_copy
*/
flags = *data++;
-
if ((flags & 0xc0) != 0x80)
goto beach;
-
/* 2: PTS_DTS_flags
* 1: ESCR_flag
* 1: ES_rate_flag
@@ -2573,14 +2559,11 @@ gst_ps_demux_scan_ts (GstPsDemux * demux
* 1: PES_extension_flag
*/
flags = *data++;
-
/* 8: PES_header_data_length */
data++;
-
/* only DTS: this is invalid */
if ((flags & 0xc0) == 0x40)
goto beach;
-
/* check for PTS */
if ((flags & 0x80)) {
READ_TS (data, pts, beach);
@@ -2653,7 +2636,6 @@ gst_ps_demux_scan_forward_ts (GstPsDemux
/* done with the buffer, unref it */
gst_buffer_unmap (buffer, &map);
gst_buffer_unref (buffer);
-
if (found) {
*rts = ts;
*pos = offset + cursor - 1;
@@ -2661,7 +2643,6 @@ gst_ps_demux_scan_forward_ts (GstPsDemux
offset += cursor;
}
} while (!found && offset < demux->sink_segment.stop);
-
return found;
}
@@ -2698,9 +2679,7 @@ gst_ps_demux_scan_backward_ts (GstPsDemu
ret = gst_pad_pull_range (demux->sinkpad, offset, to_read, &buffer);
if (G_UNLIKELY (ret != GST_FLOW_OK))
return FALSE;
-
gst_buffer_map (buffer, &map, GST_MAP_READ);
-
/* may get a short buffer at the end of the file */
if (G_UNLIKELY (map.size <= scan_sz)) {
gst_buffer_unmap (buffer, &map);
@@ -2720,14 +2699,12 @@ gst_ps_demux_scan_backward_ts (GstPsDemu
/* done with the buffer, unref it */
gst_buffer_unmap (buffer, &map);
gst_buffer_unref (buffer);
-
if (found) {
*rts = ts;
*pos = offset + cursor;
}
} while (!found && offset > 0);
-
return found;
}
@@ -2765,29 +2742,30 @@ gst_ps_sink_get_duration (GstPsDemux * d
/* Scan for notorious SCR and PTS to calculate the duration */
/* scan for first SCR in the stream */
offset = demux->sink_segment.start;
- gst_ps_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &demux->first_scr,
- DURATION_SCAN_LIMIT);
- GST_DEBUG_OBJECT (demux, "First SCR: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
- " in packet starting at %" G_GUINT64_FORMAT,
- demux->first_scr, GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->first_scr)),
- offset);
+ gst_ps_demux_scan_forward_ts (demux, &offset, SCAN_SCR,
+ &demux->first_scr, DURATION_SCAN_LIMIT);
+ GST_DEBUG_OBJECT (demux,
+ "First SCR: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
+ " in packet starting at %" G_GUINT64_FORMAT, demux->first_scr,
+ GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->first_scr)), offset);
demux->first_scr_offset = offset;
/* scan for last SCR in the stream */
offset = demux->sink_segment.stop;
- gst_ps_demux_scan_backward_ts (demux, &offset, SCAN_SCR, &demux->last_scr, 0);
- GST_DEBUG_OBJECT (demux, "Last SCR: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
- " in packet starting at %" G_GUINT64_FORMAT,
- demux->last_scr, GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->last_scr)),
- offset);
+ gst_ps_demux_scan_backward_ts (demux, &offset, SCAN_SCR,
+ &demux->last_scr, DURATION_SCAN_LIMIT);
+ GST_DEBUG_OBJECT (demux,
+ "Last SCR: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
+ " in packet starting at %" G_GUINT64_FORMAT, demux->last_scr,
+ GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->last_scr)), offset);
demux->last_scr_offset = offset;
/* scan for first PTS in the stream */
offset = demux->sink_segment.start;
- gst_ps_demux_scan_forward_ts (demux, &offset, SCAN_PTS, &demux->first_pts,
- DURATION_SCAN_LIMIT);
- GST_DEBUG_OBJECT (demux, "First PTS: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
- " in packet starting at %" G_GUINT64_FORMAT,
- demux->first_pts, GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->first_pts)),
- offset);
+ gst_ps_demux_scan_forward_ts (demux, &offset, SCAN_PTS,
+ &demux->first_pts, DURATION_SCAN_LIMIT);
+ GST_DEBUG_OBJECT (demux,
+ "First PTS: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
+ " in packet starting at %" G_GUINT64_FORMAT, demux->first_pts,
+ GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->first_pts)), offset);
if (demux->first_pts != G_MAXUINT64) {
/* scan for last PTS in the stream */
offset = demux->sink_segment.stop;
@@ -2812,8 +2790,8 @@ gst_ps_sink_get_duration (GstPsDemux * d
/* Start demuxing from the right place */
demux->sink_segment.position = offset;
GST_DEBUG_OBJECT (demux, "Replaced First SCR: %" G_GINT64_FORMAT
- " %" GST_TIME_FORMAT " in packet starting at %" G_GUINT64_FORMAT,
- demux->first_scr,
+ " %" GST_TIME_FORMAT " in packet starting at %"
+ G_GUINT64_FORMAT, demux->first_scr,
GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->first_scr)), offset);
break;
}
@@ -2823,7 +2801,6 @@ gst_ps_sink_get_duration (GstPsDemux * d
demux->base_time = MPEGTIME_TO_GSTTIME (demux->first_scr);
demux->scr_rate_n = demux->last_scr_offset - demux->first_scr_offset;
demux->scr_rate_d = demux->last_scr - demux->first_scr;
-
if (G_LIKELY (demux->first_pts != G_MAXUINT64 &&
demux->last_pts != G_MAXUINT64)) {
/* update the src segment */
@@ -2840,9 +2817,7 @@ gst_ps_sink_get_duration (GstPsDemux * d
&demux->sink_segment);
GST_INFO_OBJECT (demux, "src segment configured %" GST_SEGMENT_FORMAT,
&demux->src_segment);
-
res = TRUE;
-
beach:
return res;
}
@@ -2853,7 +2828,6 @@ gst_ps_demux_pull_block (GstPad * pad, G
{
GstFlowReturn ret;
GstBuffer *buffer = NULL;
-
ret = gst_pad_pull_range (pad, offset, size, &buffer);
if (G_UNLIKELY (ret != GST_FLOW_OK)) {
GST_DEBUG_OBJECT (demux, "pull range at %" G_GUINT64_FORMAT
@@ -2862,13 +2836,11 @@ gst_ps_demux_pull_block (GstPad * pad, G
} else
GST_LOG_OBJECT (demux, "pull range at %" G_GUINT64_FORMAT
" size %u done", offset, size);
-
if (demux->sink_segment.rate < 0) {
GST_LOG_OBJECT (demux, "setting discont flag on backward rate");
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
}
ret = gst_ps_demux_chain (pad, GST_OBJECT (demux), buffer);
-
beach:
return ret;
}
@@ -2879,9 +2851,7 @@ gst_ps_demux_loop (GstPad * pad)
GstPsDemux *demux;
GstFlowReturn ret = GST_FLOW_OK;
guint64 offset = 0;
-
demux = GST_PS_DEMUX (gst_pad_get_parent (pad));
-
if (G_UNLIKELY (demux->flushing)) {
ret = GST_FLOW_FLUSHING;
goto pause;
@@ -2889,7 +2859,6 @@ gst_ps_demux_loop (GstPad * pad)
if (G_UNLIKELY (demux->sink_segment.format == GST_FORMAT_UNDEFINED))
gst_ps_sink_get_duration (demux);
-
offset = demux->sink_segment.position;
if (demux->sink_segment.rate >= 0) {
guint size = BLOCK_SZ;
@@ -2898,24 +2867,22 @@ gst_ps_demux_loop (GstPad * pad)
}
/* pull in data */
ret = gst_ps_demux_pull_block (pad, demux, offset, size);
-
/* pause if something went wrong */
if (G_UNLIKELY (ret != GST_FLOW_OK))
goto pause;
-
/* update our position */
offset += size;
gst_segment_set_position (&demux->sink_segment, GST_FORMAT_BYTES, offset);
-
/* check EOS condition */
if ((demux->src_segment.flags & GST_SEEK_FLAG_SEGMENT) &&
((demux->sink_segment.position >= demux->sink_segment.stop) ||
(demux->src_segment.stop != (guint64) - 1 &&
demux->src_segment.position >= demux->src_segment.stop))) {
- GST_DEBUG_OBJECT (demux, "forward mode using segment reached end of "
- "segment pos %" GST_TIME_FORMAT " stop %" GST_TIME_FORMAT
- " pos in bytes %" G_GUINT64_FORMAT " stop in bytes %"
- G_GUINT64_FORMAT, GST_TIME_ARGS (demux->src_segment.position),
+ GST_DEBUG_OBJECT (demux,
+ "forward mode using segment reached end of " "segment pos %"
+ GST_TIME_FORMAT " stop %" GST_TIME_FORMAT " pos in bytes %"
+ G_GUINT64_FORMAT " stop in bytes %" G_GUINT64_FORMAT,
+ GST_TIME_ARGS (demux->src_segment.position),
GST_TIME_ARGS (demux->src_segment.stop),
demux->sink_segment.position, demux->sink_segment.stop);
ret = GST_FLOW_EOS;
@@ -2923,25 +2890,22 @@ gst_ps_demux_loop (GstPad * pad)
}
} else { /* Reverse playback */
guint64 size = MIN (offset, BLOCK_SZ);
-
/* pull in data */
ret = gst_ps_demux_pull_block (pad, demux, offset - size, size);
-
/* pause if something went wrong */
if (G_UNLIKELY (ret != GST_FLOW_OK))
goto pause;
-
/* update our position */
offset -= size;
gst_segment_set_position (&demux->sink_segment, GST_FORMAT_BYTES, offset);
-
/* check EOS condition */
if (demux->sink_segment.position <= demux->sink_segment.start ||
demux->src_segment.position <= demux->src_segment.start) {
- GST_DEBUG_OBJECT (demux, "reverse mode using segment reached end of "
- "segment pos %" GST_TIME_FORMAT " stop %" GST_TIME_FORMAT
- " pos in bytes %" G_GUINT64_FORMAT " stop in bytes %"
- G_GUINT64_FORMAT, GST_TIME_ARGS (demux->src_segment.position),
+ GST_DEBUG_OBJECT (demux,
+ "reverse mode using segment reached end of " "segment pos %"
+ GST_TIME_FORMAT " stop %" GST_TIME_FORMAT " pos in bytes %"
+ G_GUINT64_FORMAT " stop in bytes %" G_GUINT64_FORMAT,
+ GST_TIME_ARGS (demux->src_segment.position),
GST_TIME_ARGS (demux->src_segment.start),
demux->sink_segment.position, demux->sink_segment.start);
ret = GST_FLOW_EOS;
@@ -2950,27 +2914,21 @@ gst_ps_demux_loop (GstPad * pad)
}
gst_object_unref (demux);
-
return;
-
pause:
{
const gchar *reason = gst_flow_get_name (ret);
-
GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
gst_pad_pause_task (pad);
-
if (ret == GST_FLOW_EOS) {
/* perform EOS logic */
gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
if (demux->src_segment.flags & GST_SEEK_FLAG_SEGMENT) {
gint64 stop;
-
/* for segment playback we need to post when (in stream time)
* we stopped, this is either stop (when set) or the duration. */
if ((stop = demux->src_segment.stop) == -1)
stop = demux->src_segment.duration;
-
if (demux->sink_segment.rate >= 0) {
GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
gst_element_post_message (GST_ELEMENT_CAST (demux),
@@ -2979,8 +2937,8 @@ pause:
gst_ps_demux_send_event (demux,
gst_event_new_segment_done (GST_FORMAT_TIME, stop));
} else { /* Reverse playback */
- GST_LOG_OBJECT (demux, "Sending segment done, at beginning of "
- "segment");
+ GST_LOG_OBJECT (demux,
+ "Sending segment done, at beginning of " "segment");
gst_element_post_message (GST_ELEMENT_CAST (demux),
gst_message_new_segment_done (GST_OBJECT_CAST (demux),
GST_FORMAT_TIME, demux->src_segment.start));
@@ -3017,7 +2975,6 @@ gst_ps_demux_sink_activate (GstPad * sin
{
gboolean res = FALSE;
GstQuery *query = gst_query_new_scheduling ();
-
if (gst_pad_peer_query (sinkpad, query)) {
if (gst_query_has_scheduling_mode_with_flags (query,
GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE)) {
@@ -3030,7 +2987,6 @@ gst_ps_demux_sink_activate (GstPad * sin
}
gst_query_unref (query);
-
return res;
}
@@ -3040,9 +2996,7 @@ gst_ps_demux_sink_activate_push (GstPad
gboolean active)
{
GstPsDemux *demux = GST_PS_DEMUX (parent);
-
demux->random_access = FALSE;
-
return TRUE;
}
@@ -3054,12 +3008,11 @@ gst_ps_demux_sink_activate_pull (GstPad
gboolean active)
{
GstPsDemux *demux = GST_PS_DEMUX (parent);
-
if (active) {
GST_DEBUG ("pull mode activated");
demux->random_access = TRUE;
- return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_ps_demux_loop,
- sinkpad, NULL);
+ return gst_pad_start_task (sinkpad,
+ (GstTaskFunction) gst_ps_demux_loop, sinkpad, NULL);
} else {
demux->random_access = FALSE;
return gst_pad_stop_task (sinkpad);
@@ -3087,12 +3040,9 @@ static GstFlowReturn
gst_ps_demux_combine_flows (GstPsDemux * demux, GstFlowReturn ret)
{
GST_LOG_OBJECT (demux, "flow return: %s", gst_flow_get_name (ret));
-
ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
-
if (G_UNLIKELY (demux->need_no_more_pads && ret == GST_FLOW_NOT_LINKED))
ret = GST_FLOW_OK;
-
GST_LOG_OBJECT (demux, "combined flow return: %s", gst_flow_get_name (ret));
return ret;
}
@@ -3104,32 +3054,28 @@ gst_ps_demux_chain (GstPad * pad, GstObj
GstFlowReturn ret = GST_FLOW_OK;
guint32 avail;
gboolean save, discont;
-
discont = GST_BUFFER_IS_DISCONT (buffer);
-
if (discont) {
- GST_LOG_OBJECT (demux, "Received buffer with discont flag and"
- " offset %" G_GUINT64_FORMAT, GST_BUFFER_OFFSET (buffer));
-
+ GST_LOG_OBJECT (demux,
+ "Received buffer with discont flag and" " offset %"
+ G_GUINT64_FORMAT, GST_BUFFER_OFFSET (buffer));
gst_pes_filter_drain (&demux->filter);
gst_ps_demux_mark_discont (demux, TRUE, FALSE);
-
/* mark discont on all streams */
if (demux->sink_segment.rate >= 0.0) {
demux->current_scr = G_MAXUINT64;
demux->bytes_since_scr = 0;
}
} else {
- GST_LOG_OBJECT (demux, "Received buffer with offset %" G_GUINT64_FORMAT,
+ GST_LOG_OBJECT (demux,
+ "Received buffer with offset %" G_GUINT64_FORMAT,
GST_BUFFER_OFFSET (buffer));
}
/* We keep the offset to interpolate SCR */
demux->adapter_offset = GST_BUFFER_OFFSET (buffer);
-
gst_adapter_push (demux->adapter, buffer);
demux->bytes_since_scr += gst_buffer_get_size (buffer);
-
avail = gst_adapter_available (demux->rev_adapter);
if (avail > 0) {
GST_LOG_OBJECT (demux, "appending %u saved bytes", avail);
@@ -3142,7 +3088,6 @@ gst_ps_demux_chain (GstPad * pad, GstObj
avail = gst_adapter_available (demux->adapter);
GST_LOG_OBJECT (demux, "avail now: %d, state %d", avail, demux->filter.state);
-
switch (demux->filter.state) {
case STATE_DATA_SKIP:
case STATE_DATA_PUSH:
@@ -3212,7 +3157,6 @@ gst_ps_demux_chain (GstPad * pad, GstObj
* saved up to the next ps sync. */
if (ps_sync)
save = FALSE;
-
switch (ret) {
case GST_FLOW_NEED_MORE_DATA:
GST_DEBUG_OBJECT (demux, "need more data");
@@ -3246,7 +3190,6 @@ gst_ps_demux_change_state (GstElement *
{
GstPsDemux *demux = GST_PS_DEMUX (element);
GstStateChangeReturn result;
-
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
gst_pes_filter_init (&demux->filter, demux->adapter,
@@ -3263,7 +3206,6 @@ gst_ps_demux_change_state (GstElement *
}
result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
switch (transition) {
case GST_STATE_CHANGE_PAUSED_TO_READY:
gst_ps_demux_reset (demux);
diff -urp gst-plugins-bad-1.8.3.orig/gst/mpegdemux/Makefile.am gst-plugins-bad-1.8.3/gst/mpegdemux/Makefile.am
--- gst-plugins-bad-1.8.3.orig/gst/mpegdemux/Makefile.am 2017-03-02 11:39:54.833318377 -0600
+++ gst-plugins-bad-1.8.3/gst/mpegdemux/Makefile.am 2017-03-02 11:41:01.197319588 -0600
@@ -11,7 +11,7 @@ libgstmpegpsdemux_la_CFLAGS = \
libgstmpegpsdemux_la_LIBADD = \
$(GST_PLUGINS_BASE_LIBS) -lgsttag-$(GST_API_VERSION) \
-lgstpbutils-$(GST_API_VERSION) \
- $(GST_BASE_LIBS) $(GST_LIBS)
+ $(GST_BASE_LIBS) -lgstbase-$(GST_API_VERSION) $(GST_LIBS)
libgstmpegpsdemux_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstmpegpsdemux_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)