From 948b87bf1514de55ee96575d204140eeec3a80a8 Mon Sep 17 00:00:00 2001 From: Jan Schmidt 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 --- gst/mpegdemux/Makefile.am | 2 +- gst/mpegdemux/gstmpegdemux.c | 322 ++++++++++++++++--------------------------- 2 files changed, 117 insertions(+), 207 deletions(-) Index: gst-plugins-bad1.0-1.4.4/gst/mpegdemux/Makefile.am =================================================================== --- gst-plugins-bad1.0-1.4.4.orig/gst/mpegdemux/Makefile.am +++ gst-plugins-bad1.0-1.4.4/gst/mpegdemux/Makefile.am @@ -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) Index: gst-plugins-bad1.0-1.4.4/gst/mpegdemux/gstmpegdemux.c =================================================================== --- gst-plugins-bad1.0-1.4.4.orig/gst/mpegdemux/gstmpegdemux.c +++ gst-plugins-bad1.0-1.4.4/gst/mpegdemux/gstmpegdemux.c @@ -50,6 +50,7 @@ #include #include +#include #include "gstmpegdefs.h" #include "gstmpegdemux.h" @@ -77,6 +78,34 @@ typedef enum #define ADAPTER_OFFSET_FLUSH(_bytes_) demux->adapter_offset += (_bytes_) +#if !GST_CHECK_VERSION(1, 6, 0) +static inline gboolean +gst_byte_reader_peek_sub_reader (GstByteReader * reader, + GstByteReader * sub_reader, guint size) +{ + g_return_val_if_fail (reader != NULL, FALSE); + g_return_val_if_fail (sub_reader != NULL, FALSE); + + if (gst_byte_reader_get_remaining (reader) < size) + return FALSE; + + sub_reader->data = reader->data + reader->byte; + sub_reader->byte = 0; + sub_reader->size = size; + return TRUE; +} + +static inline gboolean +gst_byte_reader_get_sub_reader (GstByteReader * reader, + GstByteReader * sub_reader, guint size) +{ + if (!gst_byte_reader_peek_sub_reader (reader, sub_reader, size)) + return FALSE; + gst_byte_reader_skip_unchecked (reader, size); + return TRUE; +} +#endif + GST_DEBUG_CATEGORY_STATIC (gstflupsdemux_debug); #define GST_CAT_DEFAULT (gstflupsdemux_debug) @@ -2029,42 +2058,48 @@ need_more_data: static GstFlowReturn gst_flups_demux_parse_psm (GstFluPSDemux * 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); + { + const guint8 *data; - /* skip start code */ - data += 4; + /* 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); - length = GST_READ_UINT16_BE (data); - GST_DEBUG_OBJECT (demux, "length %u", length); + if (G_UNLIKELY (psm_length > 0x3FA)) + goto psm_len_error; + psm_length += 6; /* Add start code + size to length */ - if (G_UNLIKELY (length > 0x3FA)) - goto psm_len_error; + gst_adapter_unmap (demux->adapter); - length += 6; + if (gst_adapter_available (demux->adapter) < psm_length) + goto need_more_data; - gst_adapter_unmap (demux->adapter); + data = gst_adapter_map (demux->adapter, psm_length); - if (gst_adapter_available (demux->adapter) < length) - goto need_more_data; - - 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 @@ -2072,62 +2107,70 @@ gst_flups_demux_parse_psm (GstFluPSDemux 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"); @@ -2158,13 +2201,10 @@ gst_flups_demux_data_cb (GstPESFilter * 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]; @@ -2175,7 +2215,6 @@ gst_flups_demux_data_cb (GstPESFilter * * (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; @@ -2187,10 +2226,8 @@ gst_flups_demux_data_cb (GstPESFilter * /* 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 */ @@ -2198,7 +2235,6 @@ gst_flups_demux_data_cb (GstPESFilter * /* 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); @@ -2206,8 +2242,8 @@ gst_flups_demux_data_cb (GstPESFilter * 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); } } } @@ -2220,7 +2256,6 @@ gst_flups_demux_data_cb (GstPESFilter * "(%" G_GUINT64_FORMAT ")", filter->pts, demux->next_pts); } else demux->next_pts = G_MAXUINT64; - if (filter->dts != -1) { demux->next_dts = filter->dts + demux->scr_adjust; } else { @@ -2267,9 +2302,7 @@ gst_flups_demux_data_cb (GstPESFilter * done: gst_buffer_unmap (buffer, &map); gst_buffer_unref (buffer); - return ret; - /* ERRORS */ unknown_stream_type: { @@ -2287,17 +2320,13 @@ gst_flups_demux_resync (GstFluPSDemux * 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); @@ -2311,16 +2340,12 @@ gst_flups_demux_resync (GstFluPSDemux * 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 */ @@ -2351,7 +2376,6 @@ gst_flups_demux_resync (GstFluPSDemux * } return found; - need_data: { GST_LOG_OBJECT (demux, "we need more data for resync %d", avail); @@ -2420,7 +2444,6 @@ gst_flups_demux_scan_ts (GstFluPSDemux * next32 = GST_READ_UINT32_BE (data); if ((next32 & 0x00000300) != 0x00000300) goto beach; - stuffing_bytes = (next32 & 0x07); data += 4; while (stuffing_bytes--) { @@ -2431,10 +2454,8 @@ gst_flups_demux_scan_ts (GstFluPSDemux * /* 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; @@ -2469,9 +2490,7 @@ gst_flups_demux_scan_ts (GstFluPSDemux * /* 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) { @@ -2483,7 +2502,6 @@ gst_flups_demux_scan_ts (GstFluPSDemux * /* 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); @@ -2495,7 +2513,6 @@ gst_flups_demux_scan_ts (GstFluPSDemux * } else if ((*data & 0xc0) == 0x80) { /* mpeg2 case */ guchar flags; - /* 2: '10' * 2: PES_scrambling_control * 1: PES_priority @@ -2504,10 +2521,8 @@ gst_flups_demux_scan_ts (GstFluPSDemux * * 1: original_or_copy */ flags = *data++; - if ((flags & 0xc0) != 0x80) goto beach; - /* 2: PTS_DTS_flags * 1: ESCR_flag * 1: ES_rate_flag @@ -2517,14 +2532,11 @@ gst_flups_demux_scan_ts (GstFluPSDemux * * 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); @@ -2587,7 +2599,6 @@ gst_flups_demux_scan_forward_ts (GstFluP } end_scan = map.size - scan_sz; - /* scan the block */ for (cursor = 0; !found && cursor <= end_scan; cursor++) { found = gst_flups_demux_scan_ts (demux, map.data + cursor, mode, &ts); @@ -2596,7 +2607,6 @@ gst_flups_demux_scan_forward_ts (GstFluP /* done with the buffer, unref it */ gst_buffer_unmap (buffer, &map); gst_buffer_unref (buffer); - if (found) { *rts = ts; *pos = offset + cursor - 1; @@ -2604,7 +2614,6 @@ gst_flups_demux_scan_forward_ts (GstFluP offset += cursor; } } while (!found && offset < demux->sink_segment.stop); - return found; } @@ -2641,9 +2650,7 @@ gst_flups_demux_scan_backward_ts (GstFlu 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); @@ -2653,7 +2660,6 @@ gst_flups_demux_scan_backward_ts (GstFlu start_scan = map.size - scan_sz; data = map.data + start_scan; - /* scan the block */ for (cursor = (start_scan + 1); !found && cursor > 0; cursor--) { found = gst_flups_demux_scan_ts (demux, data--, mode, &ts); @@ -2662,14 +2668,12 @@ gst_flups_demux_scan_backward_ts (GstFlu /* 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; } @@ -2707,30 +2711,30 @@ gst_flups_sink_get_duration (GstFluPSDem /* Scan for notorious SCR and PTS to calculate the duration */ /* scan for first SCR in the stream */ offset = demux->sink_segment.start; - gst_flups_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_flups_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_flups_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); + &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_flups_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_flups_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; @@ -2755,8 +2759,8 @@ gst_flups_sink_get_duration (GstFluPSDem /* 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; } @@ -2766,7 +2770,6 @@ gst_flups_sink_get_duration (GstFluPSDem 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 */ @@ -2783,9 +2786,7 @@ gst_flups_sink_get_duration (GstFluPSDem &demux->sink_segment); GST_INFO_OBJECT (demux, "src segment configured %" GST_SEGMENT_FORMAT, &demux->src_segment); - res = TRUE; - beach: return res; } @@ -2796,7 +2797,6 @@ gst_flups_demux_pull_block (GstPad * pad { GstFlowReturn ret = GST_FLOW_OK; 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 @@ -2855,10 +2855,11 @@ gst_flups_demux_loop (GstPad * pad) ((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; @@ -2881,10 +2882,11 @@ gst_flups_demux_loop (GstPad * pad) /* 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; @@ -2893,27 +2895,21 @@ gst_flups_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), @@ -2922,8 +2918,8 @@ pause: gst_flups_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)); @@ -2960,7 +2956,6 @@ gst_flups_demux_sink_activate (GstPad * { 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)) { @@ -2973,7 +2968,6 @@ gst_flups_demux_sink_activate (GstPad * } gst_query_unref (query); - return res; } @@ -3030,12 +3024,9 @@ static GstFlowReturn gst_flups_demux_combine_flows (GstFluPSDemux * 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; } @@ -3085,7 +3076,6 @@ gst_flups_demux_chain (GstPad * pad, Gst 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: @@ -3155,7 +3145,6 @@ gst_flups_demux_chain (GstPad * pad, Gst * 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"); @@ -3189,7 +3178,6 @@ gst_flups_demux_change_state (GstElement { GstFluPSDemux *demux = GST_FLUPS_DEMUX (element); GstStateChangeReturn result; - switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: gst_pes_filter_init (&demux->filter, demux->adapter, @@ -3206,7 +3194,6 @@ gst_flups_demux_change_state (GstElement } result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: gst_flups_demux_reset (demux);