/[packages]/updates/5/gstreamer1.0-plugins-bad/current/SOURCES/0001-psdemux-Rewrite-PSM-parsing-using-GstByteReader.patch
ViewVC logotype

Contents of /updates/5/gstreamer1.0-plugins-bad/current/SOURCES/0001-psdemux-Rewrite-PSM-parsing-using-GstByteReader.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1185974 - (show annotations) (download)
Wed Dec 27 21:20:34 2017 UTC (6 years, 3 months ago) by luigiwalser
File size: 25614 byte(s)
add patches from debian to fix additional security issues (mga#19814, mga#20238)
1 From 948b87bf1514de55ee96575d204140eeec3a80a8 Mon Sep 17 00:00:00 2001
2 From: Jan Schmidt <jan@centricular.com>
3 Date: Wed, 1 Feb 2017 14:25:32 +1100
4 Subject: [PATCH] psdemux: Rewrite PSM parsing using GstByteReader
5
6 Avoid possible buffer overflows and ignore invalid PSM packets better
7 by using GstByteReader.
8
9 https://bugzilla.gnome.org/show_bug.cgi?id=777957
10 ---
11 gst/mpegdemux/Makefile.am | 2 +-
12 gst/mpegdemux/gstmpegdemux.c | 322 ++++++++++++++++---------------------------
13 2 files changed, 117 insertions(+), 207 deletions(-)
14
15 Index: gst-plugins-bad1.0-1.4.4/gst/mpegdemux/Makefile.am
16 ===================================================================
17 --- gst-plugins-bad1.0-1.4.4.orig/gst/mpegdemux/Makefile.am
18 +++ gst-plugins-bad1.0-1.4.4/gst/mpegdemux/Makefile.am
19 @@ -11,7 +11,7 @@ libgstmpegpsdemux_la_CFLAGS = \
20 libgstmpegpsdemux_la_LIBADD = \
21 $(GST_PLUGINS_BASE_LIBS) -lgsttag-$(GST_API_VERSION) \
22 -lgstpbutils-$(GST_API_VERSION) \
23 - $(GST_BASE_LIBS) $(GST_LIBS)
24 + $(GST_BASE_LIBS) -lgstbase-$(GST_API_VERSION) $(GST_LIBS)
25 libgstmpegpsdemux_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
26 libgstmpegpsdemux_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
27
28 Index: gst-plugins-bad1.0-1.4.4/gst/mpegdemux/gstmpegdemux.c
29 ===================================================================
30 --- gst-plugins-bad1.0-1.4.4.orig/gst/mpegdemux/gstmpegdemux.c
31 +++ gst-plugins-bad1.0-1.4.4/gst/mpegdemux/gstmpegdemux.c
32 @@ -50,6 +50,7 @@
33
34 #include <gst/tag/tag.h>
35 #include <gst/pbutils/pbutils.h>
36 +#include <gst/base/gstbytereader.h>
37
38 #include "gstmpegdefs.h"
39 #include "gstmpegdemux.h"
40 @@ -77,6 +78,34 @@ typedef enum
41
42 #define ADAPTER_OFFSET_FLUSH(_bytes_) demux->adapter_offset += (_bytes_)
43
44 +#if !GST_CHECK_VERSION(1, 6, 0)
45 +static inline gboolean
46 +gst_byte_reader_peek_sub_reader (GstByteReader * reader,
47 + GstByteReader * sub_reader, guint size)
48 +{
49 + g_return_val_if_fail (reader != NULL, FALSE);
50 + g_return_val_if_fail (sub_reader != NULL, FALSE);
51 +
52 + if (gst_byte_reader_get_remaining (reader) < size)
53 + return FALSE;
54 +
55 + sub_reader->data = reader->data + reader->byte;
56 + sub_reader->byte = 0;
57 + sub_reader->size = size;
58 + return TRUE;
59 +}
60 +
61 +static inline gboolean
62 +gst_byte_reader_get_sub_reader (GstByteReader * reader,
63 + GstByteReader * sub_reader, guint size)
64 +{
65 + if (!gst_byte_reader_peek_sub_reader (reader, sub_reader, size))
66 + return FALSE;
67 + gst_byte_reader_skip_unchecked (reader, size);
68 + return TRUE;
69 +}
70 +#endif
71 +
72 GST_DEBUG_CATEGORY_STATIC (gstflupsdemux_debug);
73 #define GST_CAT_DEFAULT (gstflupsdemux_debug)
74
75 @@ -2029,42 +2058,48 @@ need_more_data:
76 static GstFlowReturn
77 gst_flups_demux_parse_psm (GstFluPSDemux * demux)
78 {
79 - guint16 length = 0, info_length = 0, es_map_length = 0;
80 + guint16 psm_length, info_length = 0, es_map_length = 0;
81 guint8 psm_version = 0;
82 - const guint8 *data, *es_map_base;
83 + GstByteReader br;
84 #ifndef GST_DISABLE_GST_DEBUG
85 gboolean applicable;
86 #endif
87
88 + /* Need at least 6 bytes for start code + length */
89 if (gst_adapter_available (demux->adapter) < 6)
90 goto need_more_data;
91
92 - /* start code + length */
93 - data = gst_adapter_map (demux->adapter, 6);
94 + {
95 + const guint8 *data;
96
97 - /* skip start code */
98 - data += 4;
99 + /* start code + length */
100 + data = gst_adapter_map (demux->adapter, 6);
101 + /* skip start code */
102 + data += 4;
103 + psm_length = GST_READ_UINT16_BE (data);
104 + GST_DEBUG_OBJECT (demux, "PSM length %u", psm_length);
105
106 - length = GST_READ_UINT16_BE (data);
107 - GST_DEBUG_OBJECT (demux, "length %u", length);
108 + if (G_UNLIKELY (psm_length > 0x3FA))
109 + goto psm_len_error;
110 + psm_length += 6; /* Add start code + size to length */
111
112 - if (G_UNLIKELY (length > 0x3FA))
113 - goto psm_len_error;
114 + gst_adapter_unmap (demux->adapter);
115
116 - length += 6;
117 + if (gst_adapter_available (demux->adapter) < psm_length)
118 + goto need_more_data;
119
120 - gst_adapter_unmap (demux->adapter);
121 + data = gst_adapter_map (demux->adapter, psm_length);
122
123 - if (gst_adapter_available (demux->adapter) < length)
124 - goto need_more_data;
125 -
126 - data = gst_adapter_map (demux->adapter, length);
127 + gst_byte_reader_init (&br, data, psm_length);
128 + }
129
130 /* skip start code and length */
131 - data += 6;
132 + if (!gst_byte_reader_skip (&br, 6))
133 + goto fail_invalid;
134
135 /* Read PSM applicable bit together with version */
136 - psm_version = GST_READ_UINT8 (data);
137 + if (!gst_byte_reader_get_uint8 (&br, &psm_version))
138 + goto fail_invalid;
139 #ifndef GST_DISABLE_GST_DEBUG
140 applicable = (psm_version & 0x80) >> 7;
141 #endif
142 @@ -2072,62 +2107,70 @@ gst_flups_demux_parse_psm (GstFluPSDemux
143 GST_DEBUG_OBJECT (demux, "PSM version %u (applicable now %u)", psm_version,
144 applicable);
145
146 - /* Jump over version and marker bit */
147 - data += 2;
148 + /* Jump over the next byte (marker bit) */
149 + if (!gst_byte_reader_skip (&br, 1))
150 + goto fail_invalid;
151
152 /* Read PS info length */
153 - info_length = GST_READ_UINT16_BE (data);
154 - /* Cap it to PSM length - needed bytes for ES map length and CRC */
155 - info_length = MIN (length - 16, info_length);
156 + if (!gst_byte_reader_get_uint16_be (&br, &info_length))
157 + goto fail_invalid;
158 GST_DEBUG_OBJECT (demux, "PS info length %u bytes", info_length);
159 -
160 - /* Jump over that section */
161 - data += (2 + info_length);
162 + /* Skip the PS info, we don't use it */
163 + if (!gst_byte_reader_skip (&br, info_length))
164 + goto fail_invalid;
165
166 /* Read ES map length */
167 - es_map_length = GST_READ_UINT16_BE (data);
168 - /* Cap it to PSM remaining length - CRC */
169 - es_map_length = MIN (length - (16 + info_length), es_map_length);
170 + if (!gst_byte_reader_get_uint16_be (&br, &es_map_length))
171 + goto fail_invalid;
172 GST_DEBUG_OBJECT (demux, "ES map length %u bytes", es_map_length);
173
174 - /* Jump over the size */
175 - data += 2;
176 -
177 /* Now read the ES map */
178 - es_map_base = data;
179 - while (es_map_base + 4 <= data + es_map_length) {
180 - guint8 stream_type = 0, stream_id = 0;
181 - guint16 stream_info_length = 0;
182 -
183 - stream_type = GST_READ_UINT8 (es_map_base);
184 - es_map_base++;
185 - stream_id = GST_READ_UINT8 (es_map_base);
186 - es_map_base++;
187 - stream_info_length = GST_READ_UINT16_BE (es_map_base);
188 - es_map_base += 2;
189 - /* Cap stream_info_length */
190 - stream_info_length = MIN (data + es_map_length - es_map_base,
191 - stream_info_length);
192 -
193 - GST_DEBUG_OBJECT (demux, "Stream type %02X with id %02X and %u bytes info",
194 - stream_type, stream_id, stream_info_length);
195 - if (G_LIKELY (stream_id != 0xbd))
196 - demux->psm[stream_id] = stream_type;
197 - else {
198 - /* Ignore stream type for private_stream_1 and discover it looking at
199 - * the stream data.
200 - * Fixes demuxing some clips with lpcm that was wrongly declared as
201 - * mpeg audio */
202 - GST_DEBUG_OBJECT (demux, "stream type for private_stream_1 ignored");
203 + {
204 + GstByteReader es_map_br;
205 + if (!gst_byte_reader_get_sub_reader (&br, &es_map_br, es_map_length))
206 + goto fail_invalid;
207 +
208 + while (gst_byte_reader_get_remaining (&es_map_br) >= 4) {
209 + guint8 stream_type = 0, stream_id = 0;
210 + guint16 stream_info_length = 0;
211 +
212 + if (!gst_byte_reader_get_uint8 (&es_map_br, &stream_type) ||
213 + !gst_byte_reader_get_uint8 (&es_map_br, &stream_id) ||
214 + !gst_byte_reader_get_uint16_be (&es_map_br, &stream_info_length))
215 + break;
216 +
217 + GST_DEBUG_OBJECT (demux,
218 + "Stream type %02X with id %02X and %u bytes info", stream_type,
219 + stream_id, stream_info_length);
220 +
221 + if (G_LIKELY (stream_id != 0xbd))
222 + demux->psm[stream_id] = stream_type;
223 + else {
224 + /* Ignore stream type for private_stream_1 and discover it looking at
225 + * the stream data.
226 + * Fixes demuxing some clips with lpcm that was wrongly declared as
227 + * mpeg audio */
228 + GST_DEBUG_OBJECT (demux, "stream type for private_stream_1 ignored");
229 + }
230 +
231 + /* FIXME: We could use the descriptors instead of skipping them */
232 + if (!gst_byte_reader_skip (&es_map_br, stream_info_length))
233 + break;
234 }
235 - es_map_base += stream_info_length;
236 }
237 + /* We ignore the 4-byte CRC at the end */
238
239 gst_adapter_unmap (demux->adapter);
240 - gst_adapter_flush (demux->adapter, length);
241 - ADAPTER_OFFSET_FLUSH (length);
242 + gst_adapter_flush (demux->adapter, psm_length);
243 + ADAPTER_OFFSET_FLUSH (psm_length);
244 return GST_FLOW_OK;
245
246 +fail_invalid:
247 + GST_DEBUG_OBJECT (demux, "Failed to parse PSM. Skipping");
248 + gst_adapter_unmap (demux->adapter);
249 + gst_adapter_flush (demux->adapter, psm_length);
250 + ADAPTER_OFFSET_FLUSH (psm_length);
251 + return GST_FLOW_LOST_SYNC;
252 psm_len_error:
253 {
254 GST_DEBUG_OBJECT (demux, "error in PSM length");
255 @@ -2158,13 +2201,10 @@ gst_flups_demux_data_cb (GstPESFilter *
256 GstMapInfo map;
257 gsize datalen;
258 guint offset = 0;
259 -
260 gst_buffer_map (buffer, &map, GST_MAP_READ);
261 datalen = map.size;
262 -
263 start_code = filter->start_code;
264 id = filter->id;
265 -
266 if (first) {
267 /* find the stream type */
268 stream_type = demux->psm[id];
269 @@ -2175,7 +2215,6 @@ gst_flups_demux_data_cb (GstPESFilter *
270 * (see ftp://ftp.mplayerhq.hu/MPlayer/samples/MPEG-VOB/vdr-AC3) */
271 if (datalen >= 4) {
272 guint hdr = GST_READ_UINT32_BE (map.data);
273 -
274 if (G_UNLIKELY ((hdr & 0xffff0000) == AC3_SYNC_WORD)) {
275 id = 0x80;
276 stream_type = demux->psm[id] = ST_GST_AUDIO_RAWA52;
277 @@ -2187,10 +2226,8 @@ gst_flups_demux_data_cb (GstPESFilter *
278 /* new id is in the first byte */
279 id = map.data[offset++];
280 datalen--;
281 -
282 /* and remap */
283 stream_type = demux->psm[id];
284 -
285 /* Now, if it's a subpicture stream - no more, otherwise
286 * take the first byte too, since it's the frame count in audio
287 * streams and our backwards compat convention is to strip it off */
288 @@ -2198,7 +2235,6 @@ gst_flups_demux_data_cb (GstPESFilter *
289 /* Number of audio frames in this packet */
290 #ifndef GST_DISABLE_GST_DEBUG
291 guint8 nframes;
292 -
293 nframes = map.data[offset];
294 GST_LOG_OBJECT (demux, "private type 0x%02x, %d frames", id,
295 nframes);
296 @@ -2206,8 +2242,8 @@ gst_flups_demux_data_cb (GstPESFilter *
297 offset++;
298 datalen--;
299 } else {
300 - GST_LOG_OBJECT (demux, "private type 0x%02x, stream type %d", id,
301 - stream_type);
302 + GST_LOG_OBJECT (demux, "private type 0x%02x, stream type %d",
303 + id, stream_type);
304 }
305 }
306 }
307 @@ -2220,7 +2256,6 @@ gst_flups_demux_data_cb (GstPESFilter *
308 "(%" G_GUINT64_FORMAT ")", filter->pts, demux->next_pts);
309 } else
310 demux->next_pts = G_MAXUINT64;
311 -
312 if (filter->dts != -1) {
313 demux->next_dts = filter->dts + demux->scr_adjust;
314 } else {
315 @@ -2267,9 +2302,7 @@ gst_flups_demux_data_cb (GstPESFilter *
316 done:
317 gst_buffer_unmap (buffer, &map);
318 gst_buffer_unref (buffer);
319 -
320 return ret;
321 -
322 /* ERRORS */
323 unknown_stream_type:
324 {
325 @@ -2287,17 +2320,13 @@ gst_flups_demux_resync (GstFluPSDemux *
326 guint32 code;
327 gint offset;
328 gboolean found;
329 -
330 avail = gst_adapter_available (demux->adapter);
331 if (G_UNLIKELY (avail < 4))
332 goto need_data;
333 -
334 /* Common case, read 4 bytes an check it */
335 data = gst_adapter_map (demux->adapter, 4);
336 -
337 /* read currect code */
338 code = GST_READ_UINT32_BE (data);
339 -
340 /* The common case is that the sync code is at 0 bytes offset */
341 if (G_LIKELY ((code & 0xffffff00) == 0x100L)) {
342 GST_LOG_OBJECT (demux, "Found resync code %08x after 0 bytes", code);
343 @@ -2311,16 +2340,12 @@ gst_flups_demux_resync (GstFluPSDemux *
344 offset = 4;
345 if (offset >= avail)
346 goto need_data; /* Not enough data to find sync */
347 -
348 data = gst_adapter_map (demux->adapter, avail);
349 -
350 do {
351 code = (code << 8) | data[offset++];
352 found = (code & 0xffffff00) == 0x100L;
353 } while (offset < avail && !found);
354 -
355 gst_adapter_unmap (demux->adapter);
356 -
357 if (!save || demux->sink_segment.rate >= 0.0) {
358 GST_LOG_OBJECT (demux, "flushing %d bytes", offset - 4);
359 /* forward playback, we can discard and flush the skipped bytes */
360 @@ -2351,7 +2376,6 @@ gst_flups_demux_resync (GstFluPSDemux *
361 }
362
363 return found;
364 -
365 need_data:
366 {
367 GST_LOG_OBJECT (demux, "we need more data for resync %d", avail);
368 @@ -2420,7 +2444,6 @@ gst_flups_demux_scan_ts (GstFluPSDemux *
369 next32 = GST_READ_UINT32_BE (data);
370 if ((next32 & 0x00000300) != 0x00000300)
371 goto beach;
372 -
373 stuffing_bytes = (next32 & 0x07);
374 data += 4;
375 while (stuffing_bytes--) {
376 @@ -2431,10 +2454,8 @@ gst_flups_demux_scan_ts (GstFluPSDemux *
377 /* check markers */
378 if ((scr1 & 0xf1000100) != 0x21000100)
379 goto beach;
380 -
381 if ((scr2 & 0x01800001) != 0x01800001)
382 goto beach;
383 -
384 /* :4=0010 ! scr:3 ! marker:1==1 ! scr:15 ! marker:1==1 ! scr:15 ! marker:1==1 */
385 scr = ((guint64) scr1 & 0x0e000000) << 5;
386 scr |= ((guint64) scr1 & 0x00fffe00) << 6;
387 @@ -2469,9 +2490,7 @@ gst_flups_demux_scan_ts (GstFluPSDemux *
388
389 /* skip sync code and size */
390 data += 6;
391 -
392 pts = dts = -1;
393 -
394 /* stuffing bits, first two bits are '10' for mpeg2 pes so this code is
395 * not triggered. */
396 while (TRUE) {
397 @@ -2483,7 +2502,6 @@ gst_flups_demux_scan_ts (GstFluPSDemux *
398 /* STD buffer size, never for mpeg2 */
399 if ((*data & 0xc0) == 0x40)
400 data += 2;
401 -
402 /* PTS but no DTS, never for mpeg2 */
403 if ((*data & 0xf0) == 0x20) {
404 READ_TS (data, pts, beach);
405 @@ -2495,7 +2513,6 @@ gst_flups_demux_scan_ts (GstFluPSDemux *
406 } else if ((*data & 0xc0) == 0x80) {
407 /* mpeg2 case */
408 guchar flags;
409 -
410 /* 2: '10'
411 * 2: PES_scrambling_control
412 * 1: PES_priority
413 @@ -2504,10 +2521,8 @@ gst_flups_demux_scan_ts (GstFluPSDemux *
414 * 1: original_or_copy
415 */
416 flags = *data++;
417 -
418 if ((flags & 0xc0) != 0x80)
419 goto beach;
420 -
421 /* 2: PTS_DTS_flags
422 * 1: ESCR_flag
423 * 1: ES_rate_flag
424 @@ -2517,14 +2532,11 @@ gst_flups_demux_scan_ts (GstFluPSDemux *
425 * 1: PES_extension_flag
426 */
427 flags = *data++;
428 -
429 /* 8: PES_header_data_length */
430 data++;
431 -
432 /* only DTS: this is invalid */
433 if ((flags & 0xc0) == 0x40)
434 goto beach;
435 -
436 /* check for PTS */
437 if ((flags & 0x80)) {
438 READ_TS (data, pts, beach);
439 @@ -2587,7 +2599,6 @@ gst_flups_demux_scan_forward_ts (GstFluP
440 }
441
442 end_scan = map.size - scan_sz;
443 -
444 /* scan the block */
445 for (cursor = 0; !found && cursor <= end_scan; cursor++) {
446 found = gst_flups_demux_scan_ts (demux, map.data + cursor, mode, &ts);
447 @@ -2596,7 +2607,6 @@ gst_flups_demux_scan_forward_ts (GstFluP
448 /* done with the buffer, unref it */
449 gst_buffer_unmap (buffer, &map);
450 gst_buffer_unref (buffer);
451 -
452 if (found) {
453 *rts = ts;
454 *pos = offset + cursor - 1;
455 @@ -2604,7 +2614,6 @@ gst_flups_demux_scan_forward_ts (GstFluP
456 offset += cursor;
457 }
458 } while (!found && offset < demux->sink_segment.stop);
459 -
460 return found;
461 }
462
463 @@ -2641,9 +2650,7 @@ gst_flups_demux_scan_backward_ts (GstFlu
464 ret = gst_pad_pull_range (demux->sinkpad, offset, to_read, &buffer);
465 if (G_UNLIKELY (ret != GST_FLOW_OK))
466 return FALSE;
467 -
468 gst_buffer_map (buffer, &map, GST_MAP_READ);
469 -
470 /* may get a short buffer at the end of the file */
471 if (G_UNLIKELY (map.size <= scan_sz)) {
472 gst_buffer_unmap (buffer, &map);
473 @@ -2653,7 +2660,6 @@ gst_flups_demux_scan_backward_ts (GstFlu
474
475 start_scan = map.size - scan_sz;
476 data = map.data + start_scan;
477 -
478 /* scan the block */
479 for (cursor = (start_scan + 1); !found && cursor > 0; cursor--) {
480 found = gst_flups_demux_scan_ts (demux, data--, mode, &ts);
481 @@ -2662,14 +2668,12 @@ gst_flups_demux_scan_backward_ts (GstFlu
482 /* done with the buffer, unref it */
483 gst_buffer_unmap (buffer, &map);
484 gst_buffer_unref (buffer);
485 -
486 if (found) {
487 *rts = ts;
488 *pos = offset + cursor;
489 }
490
491 } while (!found && offset > 0);
492 -
493 return found;
494 }
495
496 @@ -2707,30 +2711,30 @@ gst_flups_sink_get_duration (GstFluPSDem
497 /* Scan for notorious SCR and PTS to calculate the duration */
498 /* scan for first SCR in the stream */
499 offset = demux->sink_segment.start;
500 - gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &demux->first_scr,
501 - DURATION_SCAN_LIMIT);
502 - GST_DEBUG_OBJECT (demux, "First SCR: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
503 - " in packet starting at %" G_GUINT64_FORMAT,
504 - demux->first_scr, GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->first_scr)),
505 - offset);
506 + gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_SCR,
507 + &demux->first_scr, DURATION_SCAN_LIMIT);
508 + GST_DEBUG_OBJECT (demux,
509 + "First SCR: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
510 + " in packet starting at %" G_GUINT64_FORMAT, demux->first_scr,
511 + GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->first_scr)), offset);
512 demux->first_scr_offset = offset;
513 /* scan for last SCR in the stream */
514 offset = demux->sink_segment.stop;
515 gst_flups_demux_scan_backward_ts (demux, &offset, SCAN_SCR,
516 - &demux->last_scr, 0);
517 - GST_DEBUG_OBJECT (demux, "Last SCR: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
518 - " in packet starting at %" G_GUINT64_FORMAT,
519 - demux->last_scr, GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->last_scr)),
520 - offset);
521 + &demux->last_scr, DURATION_SCAN_LIMIT);
522 + GST_DEBUG_OBJECT (demux,
523 + "Last SCR: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
524 + " in packet starting at %" G_GUINT64_FORMAT, demux->last_scr,
525 + GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->last_scr)), offset);
526 demux->last_scr_offset = offset;
527 /* scan for first PTS in the stream */
528 offset = demux->sink_segment.start;
529 - gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_PTS, &demux->first_pts,
530 - DURATION_SCAN_LIMIT);
531 - GST_DEBUG_OBJECT (demux, "First PTS: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
532 - " in packet starting at %" G_GUINT64_FORMAT,
533 - demux->first_pts, GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->first_pts)),
534 - offset);
535 + gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_PTS,
536 + &demux->first_pts, DURATION_SCAN_LIMIT);
537 + GST_DEBUG_OBJECT (demux,
538 + "First PTS: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
539 + " in packet starting at %" G_GUINT64_FORMAT, demux->first_pts,
540 + GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->first_pts)), offset);
541 if (demux->first_pts != G_MAXUINT64) {
542 /* scan for last PTS in the stream */
543 offset = demux->sink_segment.stop;
544 @@ -2755,8 +2759,8 @@ gst_flups_sink_get_duration (GstFluPSDem
545 /* Start demuxing from the right place */
546 demux->sink_segment.position = offset;
547 GST_DEBUG_OBJECT (demux, "Replaced First SCR: %" G_GINT64_FORMAT
548 - " %" GST_TIME_FORMAT " in packet starting at %" G_GUINT64_FORMAT,
549 - demux->first_scr,
550 + " %" GST_TIME_FORMAT " in packet starting at %"
551 + G_GUINT64_FORMAT, demux->first_scr,
552 GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->first_scr)), offset);
553 break;
554 }
555 @@ -2766,7 +2770,6 @@ gst_flups_sink_get_duration (GstFluPSDem
556 demux->base_time = MPEGTIME_TO_GSTTIME (demux->first_scr);
557 demux->scr_rate_n = demux->last_scr_offset - demux->first_scr_offset;
558 demux->scr_rate_d = demux->last_scr - demux->first_scr;
559 -
560 if (G_LIKELY (demux->first_pts != G_MAXUINT64 &&
561 demux->last_pts != G_MAXUINT64)) {
562 /* update the src segment */
563 @@ -2783,9 +2786,7 @@ gst_flups_sink_get_duration (GstFluPSDem
564 &demux->sink_segment);
565 GST_INFO_OBJECT (demux, "src segment configured %" GST_SEGMENT_FORMAT,
566 &demux->src_segment);
567 -
568 res = TRUE;
569 -
570 beach:
571 return res;
572 }
573 @@ -2796,7 +2797,6 @@ gst_flups_demux_pull_block (GstPad * pad
574 {
575 GstFlowReturn ret = GST_FLOW_OK;
576 GstBuffer *buffer = NULL;
577 -
578 ret = gst_pad_pull_range (pad, offset, size, &buffer);
579 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
580 GST_DEBUG_OBJECT (demux, "pull range at %" G_GUINT64_FORMAT
581 @@ -2855,10 +2855,11 @@ gst_flups_demux_loop (GstPad * pad)
582 ((demux->sink_segment.position >= demux->sink_segment.stop) ||
583 (demux->src_segment.stop != (guint64) - 1 &&
584 demux->src_segment.position >= demux->src_segment.stop))) {
585 - GST_DEBUG_OBJECT (demux, "forward mode using segment reached end of "
586 - "segment pos %" GST_TIME_FORMAT " stop %" GST_TIME_FORMAT
587 - " pos in bytes %" G_GUINT64_FORMAT " stop in bytes %"
588 - G_GUINT64_FORMAT, GST_TIME_ARGS (demux->src_segment.position),
589 + GST_DEBUG_OBJECT (demux,
590 + "forward mode using segment reached end of " "segment pos %"
591 + GST_TIME_FORMAT " stop %" GST_TIME_FORMAT " pos in bytes %"
592 + G_GUINT64_FORMAT " stop in bytes %" G_GUINT64_FORMAT,
593 + GST_TIME_ARGS (demux->src_segment.position),
594 GST_TIME_ARGS (demux->src_segment.stop),
595 demux->sink_segment.position, demux->sink_segment.stop);
596 ret = GST_FLOW_EOS;
597 @@ -2881,10 +2882,11 @@ gst_flups_demux_loop (GstPad * pad)
598 /* check EOS condition */
599 if (demux->sink_segment.position <= demux->sink_segment.start ||
600 demux->src_segment.position <= demux->src_segment.start) {
601 - GST_DEBUG_OBJECT (demux, "reverse mode using segment reached end of "
602 - "segment pos %" GST_TIME_FORMAT " stop %" GST_TIME_FORMAT
603 - " pos in bytes %" G_GUINT64_FORMAT " stop in bytes %"
604 - G_GUINT64_FORMAT, GST_TIME_ARGS (demux->src_segment.position),
605 + GST_DEBUG_OBJECT (demux,
606 + "reverse mode using segment reached end of " "segment pos %"
607 + GST_TIME_FORMAT " stop %" GST_TIME_FORMAT " pos in bytes %"
608 + G_GUINT64_FORMAT " stop in bytes %" G_GUINT64_FORMAT,
609 + GST_TIME_ARGS (demux->src_segment.position),
610 GST_TIME_ARGS (demux->src_segment.start),
611 demux->sink_segment.position, demux->sink_segment.start);
612 ret = GST_FLOW_EOS;
613 @@ -2893,27 +2895,21 @@ gst_flups_demux_loop (GstPad * pad)
614 }
615
616 gst_object_unref (demux);
617 -
618 return;
619 -
620 pause:
621 {
622 const gchar *reason = gst_flow_get_name (ret);
623 -
624 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
625 gst_pad_pause_task (pad);
626 -
627 if (ret == GST_FLOW_EOS) {
628 /* perform EOS logic */
629 gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
630 if (demux->src_segment.flags & GST_SEEK_FLAG_SEGMENT) {
631 gint64 stop;
632 -
633 /* for segment playback we need to post when (in stream time)
634 * we stopped, this is either stop (when set) or the duration. */
635 if ((stop = demux->src_segment.stop) == -1)
636 stop = demux->src_segment.duration;
637 -
638 if (demux->sink_segment.rate >= 0) {
639 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
640 gst_element_post_message (GST_ELEMENT_CAST (demux),
641 @@ -2922,8 +2918,8 @@ pause:
642 gst_flups_demux_send_event (demux,
643 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
644 } else { /* Reverse playback */
645 - GST_LOG_OBJECT (demux, "Sending segment done, at beginning of "
646 - "segment");
647 + GST_LOG_OBJECT (demux,
648 + "Sending segment done, at beginning of " "segment");
649 gst_element_post_message (GST_ELEMENT_CAST (demux),
650 gst_message_new_segment_done (GST_OBJECT_CAST (demux),
651 GST_FORMAT_TIME, demux->src_segment.start));
652 @@ -2960,7 +2956,6 @@ gst_flups_demux_sink_activate (GstPad *
653 {
654 gboolean res = FALSE;
655 GstQuery *query = gst_query_new_scheduling ();
656 -
657 if (gst_pad_peer_query (sinkpad, query)) {
658 if (gst_query_has_scheduling_mode_with_flags (query,
659 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE)) {
660 @@ -2973,7 +2968,6 @@ gst_flups_demux_sink_activate (GstPad *
661 }
662
663 gst_query_unref (query);
664 -
665 return res;
666 }
667
668 @@ -3030,12 +3024,9 @@ static GstFlowReturn
669 gst_flups_demux_combine_flows (GstFluPSDemux * demux, GstFlowReturn ret)
670 {
671 GST_LOG_OBJECT (demux, "flow return: %s", gst_flow_get_name (ret));
672 -
673 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
674 -
675 if (G_UNLIKELY (demux->need_no_more_pads && ret == GST_FLOW_NOT_LINKED))
676 ret = GST_FLOW_OK;
677 -
678 GST_LOG_OBJECT (demux, "combined flow return: %s", gst_flow_get_name (ret));
679 return ret;
680 }
681 @@ -3085,7 +3076,6 @@ gst_flups_demux_chain (GstPad * pad, Gst
682
683 avail = gst_adapter_available (demux->adapter);
684 GST_LOG_OBJECT (demux, "avail now: %d, state %d", avail, demux->filter.state);
685 -
686 switch (demux->filter.state) {
687 case STATE_DATA_SKIP:
688 case STATE_DATA_PUSH:
689 @@ -3155,7 +3145,6 @@ gst_flups_demux_chain (GstPad * pad, Gst
690 * saved up to the next ps sync. */
691 if (ps_sync)
692 save = FALSE;
693 -
694 switch (ret) {
695 case GST_FLOW_NEED_MORE_DATA:
696 GST_DEBUG_OBJECT (demux, "need more data");
697 @@ -3189,7 +3178,6 @@ gst_flups_demux_change_state (GstElement
698 {
699 GstFluPSDemux *demux = GST_FLUPS_DEMUX (element);
700 GstStateChangeReturn result;
701 -
702 switch (transition) {
703 case GST_STATE_CHANGE_NULL_TO_READY:
704 gst_pes_filter_init (&demux->filter, demux->adapter,
705 @@ -3206,7 +3194,6 @@ gst_flups_demux_change_state (GstElement
706 }
707
708 result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
709 -
710 switch (transition) {
711 case GST_STATE_CHANGE_PAUSED_TO_READY:
712 gst_flups_demux_reset (demux);

  ViewVC Help
Powered by ViewVC 1.1.30