1 /* GStreamer Matroska muxer/demuxer
2 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3 * (c) 2006 Tim-Philipp Müller <tim centricular net>
4 * (c) 2008 Sebastian Dröge <slomo@circular-chaos.org>
5 * (c) 2011 Debarshi Ray <rishi@gnu.org>
6 *
7 * matroska-demux.c: matroska file/stream demuxer
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 */
24
25 /* TODO: check CRC32 if present
26 * TODO: there can be a segment after the first segment. Handle like
27 * chained oggs. Fixes #334082
28 * TODO: Test samples: http://www.matroska.org/samples/matrix/index.html
29 * http://samples.mplayerhq.hu/Matroska/
30 * TODO: check if demuxing is done correct for all codecs according to spec
31 * TODO: seeking with incomplete or without CUE
32 */
33
34 /**
35 * SECTION:element-matroskademux
36 *
37 * matroskademux demuxes a Matroska file into the different contained streams.
38 *
39 * <refsect2>
40 * <title>Example launch line</title>
41 * |[
42 * gst-launch-1.0 -v filesrc location=/path/to/mkv ! matroskademux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
43 * ]| This pipeline demuxes a Matroska file and outputs the contained Vorbis audio.
44 * </refsect2>
45 */
46
47
48 #ifdef HAVE_CONFIG_H
49 #include "config.h"
50 #endif
51
52 #include <math.h>
53 #include <string.h>
54 #include <glib/gprintf.h>
55
56 #include <gst/base/base.h>
57
58 /* For AVI compatibility mode
59 and for fourcc stuff */
60 #include <gst/riff/riff-read.h>
61 #include <gst/riff/riff-ids.h>
62 #include <gst/riff/riff-media.h>
63
64 #include <gst/audio/audio.h>
65 #include <gst/tag/tag.h>
66 #include <gst/pbutils/pbutils.h>
67 #include <gst/video/video.h>
68
69 #include "matroska-demux.h"
70 #include "matroska-ids.h"
71
72 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
73 #define GST_CAT_DEFAULT matroskademux_debug
74
75 #define DEBUG_ELEMENT_START(demux, ebml, element) \
76 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
77 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
78
79 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
80 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
81 " finished with '%s'", gst_flow_get_name (ret))
82
83 enum
84 {
85 PROP_0,
86 PROP_METADATA,
87 PROP_STREAMINFO,
88 PROP_MAX_GAP_TIME,
89 PROP_MAX_BACKTRACK_DISTANCE
90 };
91
92 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
93 #define DEFAULT_MAX_BACKTRACK_DISTANCE 30
94 #define INVALID_DATA_THRESHOLD (2 * 1024 * 1024)
95
96 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
97 GST_PAD_SINK,
98 GST_PAD_ALWAYS,
99 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
100 "video/x-matroska-3d; audio/webm; video/webm")
101 );
102
103 /* TODO: fill in caps! */
104
105 static GstStaticPadTemplate audio_src_templ =
106 GST_STATIC_PAD_TEMPLATE ("audio_%u",
107 GST_PAD_SRC,
108 GST_PAD_SOMETIMES,
109 GST_STATIC_CAPS ("ANY")
110 );
111
112 static GstStaticPadTemplate video_src_templ =
113 GST_STATIC_PAD_TEMPLATE ("video_%u",
114 GST_PAD_SRC,
115 GST_PAD_SOMETIMES,
116 GST_STATIC_CAPS ("ANY")
117 );
118
119 static GstStaticPadTemplate subtitle_src_templ =
120 GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
121 GST_PAD_SRC,
122 GST_PAD_SOMETIMES,
123 GST_STATIC_CAPS ("text/x-raw, format=pango-markup; application/x-ssa; "
124 "application/x-ass;application/x-usf; subpicture/x-dvd; "
125 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
126 );
127
128 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
129 guint32 id, guint64 length, guint needed);
130
131 /* element functions */
132 static void gst_matroska_demux_loop (GstPad * pad);
133
134 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
135 GstEvent * event);
136 static gboolean gst_matroska_demux_element_query (GstElement * element,
137 GstQuery * query);
138
139 /* pad functions */
140 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad,
141 GstObject * parent);
142 static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
143 GstObject * parent, GstPadMode mode, gboolean active);
144
145 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
146 GstPad * pad, GstEvent * event);
147 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
148 GstObject * parent, GstEvent * event);
149 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
150 GstObject * parent, GstQuery * query);
151
152 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
153 GstObject * parent, GstEvent * event);
154 static gboolean gst_matroska_demux_handle_sink_query (GstPad * pad,
155 GstObject * parent, GstQuery * query);
156 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
157 GstObject * object, GstBuffer * buffer);
158
159 static GstStateChangeReturn
160 gst_matroska_demux_change_state (GstElement * element,
161 GstStateChange transition);
162 #if 0
163 static void
164 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
165 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
166 #endif
167
168 /* caps functions */
169 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
170 * videocontext, const gchar * codec_id, guint8 * data, guint size,
171 gchar ** codec_name, guint32 * riff_fourcc);
172 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
173 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
174 gchar ** codec_name, guint16 * riff_audio_fmt);
175 static GstCaps
176 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
177 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
178 static const gchar *gst_matroska_track_encryption_algorithm_name (gint val);
179 static const gchar *gst_matroska_track_encryption_cipher_mode_name (gint val);
180 static const gchar *gst_matroska_track_encoding_scope_name (gint val);
181
182 /* stream methods */
183 static void gst_matroska_demux_reset (GstElement * element);
184 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
185 gdouble rate, guint64 offset, guint32 seqnum, GstSeekFlags flags);
186
187 /* gobject functions */
188 static void gst_matroska_demux_set_property (GObject * object,
189 guint prop_id, const GValue * value, GParamSpec * pspec);
190 static void gst_matroska_demux_get_property (GObject * object,
191 guint prop_id, GValue * value, GParamSpec * pspec);
192
193 GType gst_matroska_demux_get_type (void);
194 #define parent_class gst_matroska_demux_parent_class
195 G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
196
197 static void
gst_matroska_demux_finalize(GObject * object)198 gst_matroska_demux_finalize (GObject * object)
199 {
200 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
201
202 gst_matroska_read_common_finalize (&demux->common);
203 gst_flow_combiner_free (demux->flowcombiner);
204 G_OBJECT_CLASS (parent_class)->finalize (object);
205 }
206
207 static void
gst_matroska_demux_class_init(GstMatroskaDemuxClass * klass)208 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
209 {
210 GObjectClass *gobject_class = (GObjectClass *) klass;
211 GstElementClass *gstelement_class = (GstElementClass *) klass;
212
213 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
214 "Matroska demuxer");
215
216 gobject_class->finalize = gst_matroska_demux_finalize;
217
218 gobject_class->get_property = gst_matroska_demux_get_property;
219 gobject_class->set_property = gst_matroska_demux_set_property;
220
221 g_object_class_install_property (gobject_class, PROP_MAX_GAP_TIME,
222 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
223 "The demuxer sends out segment events for skipping "
224 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
225 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
226
227 g_object_class_install_property (gobject_class, PROP_MAX_BACKTRACK_DISTANCE,
228 g_param_spec_uint ("max-backtrack-distance",
229 "Maximum backtrack distance",
230 "Maximum backtrack distance in seconds when seeking without "
231 "and index in pull mode and search for a keyframe "
232 "(0 = disable backtracking).",
233 0, G_MAXUINT, DEFAULT_MAX_BACKTRACK_DISTANCE,
234 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
235
236 gstelement_class->change_state =
237 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
238 gstelement_class->send_event =
239 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
240 gstelement_class->query =
241 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
242 #if 0
243 gstelement_class->set_index =
244 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
245 gstelement_class->get_index =
246 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
247 #endif
248
249 gst_element_class_add_static_pad_template (gstelement_class,
250 &video_src_templ);
251 gst_element_class_add_static_pad_template (gstelement_class,
252 &audio_src_templ);
253 gst_element_class_add_static_pad_template (gstelement_class,
254 &subtitle_src_templ);
255 gst_element_class_add_static_pad_template (gstelement_class, &sink_templ);
256
257 gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
258 "Codec/Demuxer",
259 "Demuxes Matroska/WebM streams into video/audio/subtitles",
260 "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
261 }
262
263 static void
gst_matroska_demux_init(GstMatroskaDemux * demux)264 gst_matroska_demux_init (GstMatroskaDemux * demux)
265 {
266 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
267 "sink");
268 gst_pad_set_activate_function (demux->common.sinkpad,
269 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
270 gst_pad_set_activatemode_function (demux->common.sinkpad,
271 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
272 gst_pad_set_chain_function (demux->common.sinkpad,
273 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
274 gst_pad_set_event_function (demux->common.sinkpad,
275 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
276 gst_pad_set_query_function (demux->common.sinkpad,
277 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_query));
278 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
279
280 /* init defaults for common read context */
281 gst_matroska_read_common_init (&demux->common);
282
283 /* property defaults */
284 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
285 demux->max_backtrack_distance = DEFAULT_MAX_BACKTRACK_DISTANCE;
286
287 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
288
289 demux->flowcombiner = gst_flow_combiner_new ();
290
291 /* finish off */
292 gst_matroska_demux_reset (GST_ELEMENT (demux));
293 }
294
295 static void
gst_matroska_demux_reset(GstElement * element)296 gst_matroska_demux_reset (GstElement * element)
297 {
298 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
299
300 GST_DEBUG_OBJECT (demux, "Resetting state");
301
302 gst_matroska_read_common_reset (GST_ELEMENT (demux), &demux->common);
303
304 demux->num_a_streams = 0;
305 demux->num_t_streams = 0;
306 demux->num_v_streams = 0;
307 demux->have_nonintraonly_v_streams = FALSE;
308
309 demux->have_group_id = FALSE;
310 demux->group_id = G_MAXUINT;
311
312 demux->clock = NULL;
313 demux->tracks_parsed = FALSE;
314
315 if (demux->clusters) {
316 g_array_free (demux->clusters, TRUE);
317 demux->clusters = NULL;
318 }
319
320 g_list_foreach (demux->seek_parsed,
321 (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
322 g_list_free (demux->seek_parsed);
323 demux->seek_parsed = NULL;
324
325 demux->last_stop_end = GST_CLOCK_TIME_NONE;
326 demux->seek_block = 0;
327 demux->stream_start_time = GST_CLOCK_TIME_NONE;
328 demux->to_time = GST_CLOCK_TIME_NONE;
329 demux->cluster_time = GST_CLOCK_TIME_NONE;
330 demux->cluster_offset = 0;
331 demux->cluster_prevsize = 0;
332 demux->seen_cluster_prevsize = FALSE;
333 demux->next_cluster_offset = 0;
334 demux->stream_last_time = GST_CLOCK_TIME_NONE;
335 demux->last_cluster_offset = 0;
336 demux->index_offset = 0;
337 demux->seekable = FALSE;
338 demux->need_segment = FALSE;
339 demux->segment_seqnum = 0;
340 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
341 demux->seek_offset = -1;
342 demux->building_index = FALSE;
343 if (demux->seek_event) {
344 gst_event_unref (demux->seek_event);
345 demux->seek_event = NULL;
346 }
347
348 demux->seek_index = NULL;
349 demux->seek_entry = 0;
350
351 if (demux->new_segment) {
352 gst_event_unref (demux->new_segment);
353 demux->new_segment = NULL;
354 }
355
356 demux->invalid_duration = FALSE;
357
358 demux->cached_length = G_MAXUINT64;
359
360 if (demux->deferred_seek_event)
361 gst_event_unref (demux->deferred_seek_event);
362 demux->deferred_seek_event = NULL;
363 demux->deferred_seek_pad = NULL;
364
365 gst_flow_combiner_clear (demux->flowcombiner);
366 }
367
368 static GstBuffer *
gst_matroska_decode_buffer(GstMatroskaTrackContext * context,GstBuffer * buf)369 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
370 {
371 GstMapInfo map;
372 gpointer data;
373 gsize size;
374 GstBuffer *out_buf = buf;
375
376 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
377
378 GST_DEBUG ("decoding buffer %p", buf);
379
380 gst_buffer_map (out_buf, &map, GST_MAP_READ);
381 data = map.data;
382 size = map.size;
383
384 g_return_val_if_fail (size > 0, buf);
385
386 if (gst_matroska_decode_data (context->encodings, &data, &size,
387 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
388 if (data != map.data) {
389 gst_buffer_unmap (out_buf, &map);
390 gst_buffer_unref (out_buf);
391 out_buf = gst_buffer_new_wrapped (data, size);
392 } else {
393 gst_buffer_unmap (out_buf, &map);
394 }
395 } else {
396 GST_DEBUG ("decode data failed");
397 gst_buffer_unmap (out_buf, &map);
398 gst_buffer_unref (out_buf);
399 return NULL;
400 }
401 /* Encrypted stream */
402 if (context->protection_info) {
403
404 GstStructure *info_protect = gst_structure_copy (context->protection_info);
405 gboolean encrypted = FALSE;
406
407 gst_buffer_map (out_buf, &map, GST_MAP_READ);
408 data = map.data;
409 size = map.size;
410
411 if (gst_matroska_parse_protection_meta (&data, &size, info_protect,
412 &encrypted)) {
413 if (data != map.data) {
414 GstBuffer *tmp_buf;
415
416 gst_buffer_unmap (out_buf, &map);
417 tmp_buf = out_buf;
418 out_buf = gst_buffer_copy_region (tmp_buf, GST_BUFFER_COPY_ALL,
419 gst_buffer_get_size (tmp_buf) - size, size);
420 gst_buffer_unref (tmp_buf);
421 if (encrypted)
422 gst_buffer_add_protection_meta (out_buf, info_protect);
423 else
424 gst_structure_free (info_protect);
425 } else {
426 gst_buffer_unmap (out_buf, &map);
427 gst_structure_free (info_protect);
428 }
429 } else {
430 GST_WARNING ("Adding protection metadata failed");
431 gst_buffer_unmap (out_buf, &map);
432 gst_buffer_unref (out_buf);
433 gst_structure_free (info_protect);
434 return NULL;
435 }
436 }
437
438 return out_buf;
439 }
440
441 static void
gst_matroska_demux_add_stream_headers_to_caps(GstMatroskaDemux * demux,GstBufferList * list,GstCaps * caps)442 gst_matroska_demux_add_stream_headers_to_caps (GstMatroskaDemux * demux,
443 GstBufferList * list, GstCaps * caps)
444 {
445 GstStructure *s;
446 GValue arr_val = G_VALUE_INIT;
447 GValue buf_val = G_VALUE_INIT;
448 gint i, num;
449
450 g_assert (gst_caps_is_writable (caps));
451
452 g_value_init (&arr_val, GST_TYPE_ARRAY);
453 g_value_init (&buf_val, GST_TYPE_BUFFER);
454
455 num = gst_buffer_list_length (list);
456 for (i = 0; i < num; ++i) {
457 g_value_set_boxed (&buf_val, gst_buffer_list_get (list, i));
458 gst_value_array_append_value (&arr_val, &buf_val);
459 }
460
461 s = gst_caps_get_structure (caps, 0);
462 gst_structure_take_value (s, "streamheader", &arr_val);
463 g_value_unset (&buf_val);
464 }
465
466 static GstFlowReturn
gst_matroska_demux_parse_colour(GstMatroskaDemux * demux,GstEbmlRead * ebml,GstMatroskaTrackVideoContext * video_context)467 gst_matroska_demux_parse_colour (GstMatroskaDemux * demux, GstEbmlRead * ebml,
468 GstMatroskaTrackVideoContext * video_context)
469 {
470 GstFlowReturn ret;
471 GstVideoColorimetry colorimetry;
472 guint32 id;
473 guint64 num;
474
475 colorimetry.range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
476 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
477 colorimetry.transfer = GST_VIDEO_TRANSFER_UNKNOWN;
478 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
479
480 DEBUG_ELEMENT_START (demux, ebml, "TrackVideoColour");
481
482 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
483 goto beach;
484
485 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
486 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
487 goto beach;
488
489 switch (id) {
490 case GST_MATROSKA_ID_VIDEOMATRIXCOEFFICIENTS:{
491 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
492 goto beach;
493
494 switch (num) {
495 case 0:
496 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
497 break;
498 case 1:
499 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT709;
500 break;
501 case 2:
502 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
503 break;
504 case 4:
505 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_FCC;
506 break;
507 /* FIXME: "5: BT470BG" is undefined in GstVideoColorMatrix
508 * but it's functionally same as "6: BT601" */
509 case 5:
510 case 6:
511 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT601;
512 break;
513 case 7:
514 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_SMPTE240M;
515 break;
516 case 9:
517 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
518 break;
519 default:
520 GST_FIXME_OBJECT (demux, "Unsupported color matrix coefficients %"
521 G_GUINT64_FORMAT, num);
522 break;
523 }
524 break;
525 }
526
527 case GST_MATROSKA_ID_VIDEORANGE:{
528 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
529 goto beach;
530
531 switch (num) {
532 case 0:
533 colorimetry.range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
534 break;
535 case 1:
536 colorimetry.range = GST_VIDEO_COLOR_RANGE_16_235;
537 break;
538 case 2:
539 colorimetry.range = GST_VIDEO_COLOR_RANGE_0_255;
540 break;
541 default:
542 GST_FIXME_OBJECT (demux, "Unsupported color range %"
543 G_GUINT64_FORMAT, num);
544 break;
545 }
546 break;
547 }
548
549 case GST_MATROSKA_ID_VIDEOTRANSFERCHARACTERISTICS:{
550 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
551 goto beach;
552
553 switch (num) {
554 /* FIXME: "6: BT601" and "14: BT2020_10" are undefined in
555 * GstVideoTransferFunction, but functionally same as "1: BT709" */
556 case 1:
557 case 6:
558 case 14:
559 colorimetry.transfer = GST_VIDEO_TRANSFER_BT709;
560 break;
561 case 2:
562 colorimetry.transfer = GST_VIDEO_TRANSFER_UNKNOWN;
563 break;
564 case 4:
565 colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA22;
566 break;
567 case 5:
568 colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA28;
569 break;
570 case 7:
571 colorimetry.transfer = GST_VIDEO_TRANSFER_SMPTE240M;
572 break;
573 case 8:
574 colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA10;
575 break;
576 case 9:
577 colorimetry.transfer = GST_VIDEO_TRANSFER_LOG100;
578 break;
579 case 10:
580 colorimetry.transfer = GST_VIDEO_TRANSFER_LOG316;
581 break;
582 case 13:
583 colorimetry.transfer = GST_VIDEO_TRANSFER_SRGB;
584 break;
585 case 15:
586 colorimetry.transfer = GST_VIDEO_TRANSFER_BT2020_12;
587 break;
588 default:
589 GST_FIXME_OBJECT (demux,
590 "Unsupported color transfer characteristics %"
591 G_GUINT64_FORMAT, num);
592 break;
593 }
594 break;
595 }
596
597 case GST_MATROSKA_ID_VIDEOPRIMARIES:{
598 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
599 goto beach;
600
601 switch (num) {
602 case 1:
603 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
604 break;
605 case 2:
606 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
607 break;
608 case 4:
609 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT470M;
610 break;
611 case 5:
612 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT470BG;
613 break;
614 case 6:
615 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE170M;
616 break;
617 case 7:
618 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE240M;
619 break;
620 case 8:
621 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_FILM;
622 break;
623 case 9:
624 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
625 break;
626 default:
627 GST_FIXME_OBJECT (demux, "Unsupported color primaries %"
628 G_GUINT64_FORMAT, num);
629 break;
630 }
631 break;
632 }
633
634 default:
635 GST_FIXME_OBJECT (demux, "Unsupported subelement 0x%x in Colour", id);
636 ret = gst_ebml_read_skip (ebml);
637 break;
638 }
639 }
640
641 memcpy (&video_context->colorimetry, &colorimetry,
642 sizeof (GstVideoColorimetry));
643
644 beach:
645 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideoColour", ret);
646 return ret;
647 }
648
649 static GstFlowReturn
gst_matroska_demux_parse_stream(GstMatroskaDemux * demux,GstEbmlRead * ebml,GstMatroskaTrackContext ** dest_context)650 gst_matroska_demux_parse_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml,
651 GstMatroskaTrackContext ** dest_context)
652 {
653 GstMatroskaTrackContext *context;
654 GstCaps *caps = NULL;
655 GstTagList *cached_taglist;
656 GstFlowReturn ret;
657 guint32 id, riff_fourcc = 0;
658 guint16 riff_audio_fmt = 0;
659 gchar *codec = NULL;
660
661 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
662
663 /* start with the master */
664 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
665 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
666 return ret;
667 }
668
669 /* allocate generic... if we know the type, we'll g_renew()
670 * with the precise type */
671 context = g_new0 (GstMatroskaTrackContext, 1);
672 context->index_writer_id = -1;
673 context->type = 0; /* no type yet */
674 context->default_duration = 0;
675 context->pos = 0;
676 context->set_discont = TRUE;
677 context->timecodescale = 1.0;
678 context->flags =
679 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
680 GST_MATROSKA_TRACK_LACING;
681 context->from_time = GST_CLOCK_TIME_NONE;
682 context->from_offset = -1;
683 context->to_offset = G_MAXINT64;
684 context->alignment = 1;
685 context->dts_only = FALSE;
686 context->intra_only = FALSE;
687 context->tags = gst_tag_list_new_empty ();
688 g_queue_init (&context->protection_event_queue);
689 context->protection_info = NULL;
690
691 GST_DEBUG_OBJECT (demux, "Parsing a TrackEntry (%d tracks parsed so far)",
692 demux->common.num_streams);
693
694 /* try reading the trackentry headers */
695 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
696 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
697 break;
698
699 switch (id) {
700 /* track number (unique stream ID) */
701 case GST_MATROSKA_ID_TRACKNUMBER:{
702 guint64 num;
703
704 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
705 break;
706
707 if (num == 0) {
708 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
709 ret = GST_FLOW_ERROR;
710 break;
711 }
712
713 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
714 context->num = num;
715 break;
716 }
717 /* track UID (unique identifier) */
718 case GST_MATROSKA_ID_TRACKUID:{
719 guint64 num;
720
721 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
722 break;
723
724 if (num == 0) {
725 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
726 ret = GST_FLOW_ERROR;
727 break;
728 }
729
730 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
731 context->uid = num;
732 break;
733 }
734
735 /* track type (video, audio, combined, subtitle, etc.) */
736 case GST_MATROSKA_ID_TRACKTYPE:{
737 guint64 track_type;
738
739 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
740 break;
741 }
742
743 if (context->type != 0 && context->type != track_type) {
744 GST_WARNING_OBJECT (demux,
745 "More than one tracktype defined in a TrackEntry - skipping");
746 break;
747 } else if (track_type < 1 || track_type > 254) {
748 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
749 track_type);
750 break;
751 }
752
753 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
754
755 /* ok, so we're actually going to reallocate this thing */
756 switch (track_type) {
757 case GST_MATROSKA_TRACK_TYPE_VIDEO:
758 gst_matroska_track_init_video_context (&context);
759 break;
760 case GST_MATROSKA_TRACK_TYPE_AUDIO:
761 gst_matroska_track_init_audio_context (&context);
762 break;
763 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
764 gst_matroska_track_init_subtitle_context (&context);
765 break;
766 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
767 case GST_MATROSKA_TRACK_TYPE_LOGO:
768 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
769 case GST_MATROSKA_TRACK_TYPE_CONTROL:
770 default:
771 GST_WARNING_OBJECT (demux,
772 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
773 track_type);
774 context->type = 0;
775 break;
776 }
777 break;
778 }
779
780 /* tracktype specific stuff for video */
781 case GST_MATROSKA_ID_TRACKVIDEO:{
782 GstMatroskaTrackVideoContext *videocontext;
783
784 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
785
786 if (!gst_matroska_track_init_video_context (&context)) {
787 GST_WARNING_OBJECT (demux,
788 "TrackVideo element in non-video track - ignoring track");
789 ret = GST_FLOW_ERROR;
790 break;
791 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
792 break;
793 }
794 videocontext = (GstMatroskaTrackVideoContext *) context;
795
796 while (ret == GST_FLOW_OK &&
797 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
798 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
799 break;
800
801 switch (id) {
802 /* Should be one level up but some broken muxers write it here. */
803 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
804 guint64 num;
805
806 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
807 break;
808
809 if (num == 0) {
810 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
811 break;
812 }
813
814 GST_DEBUG_OBJECT (demux,
815 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
816 context->default_duration = num;
817 break;
818 }
819
820 /* video framerate */
821 /* NOTE: This one is here only for backward compatibility.
822 * Use _TRACKDEFAULDURATION one level up. */
823 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
824 gdouble num;
825
826 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
827 break;
828
829 if (num <= 0.0) {
830 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
831 break;
832 }
833
834 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
835 if (context->default_duration == 0)
836 context->default_duration =
837 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
838 videocontext->default_fps = num;
839 break;
840 }
841
842 /* width of the size to display the video at */
843 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
844 guint64 num;
845
846 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
847 break;
848
849 if (num == 0) {
850 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
851 break;
852 }
853
854 GST_DEBUG_OBJECT (demux,
855 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
856 videocontext->display_width = num;
857 break;
858 }
859
860 /* height of the size to display the video at */
861 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
862 guint64 num;
863
864 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
865 break;
866
867 if (num == 0) {
868 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
869 break;
870 }
871
872 GST_DEBUG_OBJECT (demux,
873 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
874 videocontext->display_height = num;
875 break;
876 }
877
878 /* width of the video in the file */
879 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
880 guint64 num;
881
882 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
883 break;
884
885 if (num == 0) {
886 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
887 break;
888 }
889
890 GST_DEBUG_OBJECT (demux,
891 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
892 videocontext->pixel_width = num;
893 break;
894 }
895
896 /* height of the video in the file */
897 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
898 guint64 num;
899
900 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
901 break;
902
903 if (num == 0) {
904 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
905 break;
906 }
907
908 GST_DEBUG_OBJECT (demux,
909 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
910 videocontext->pixel_height = num;
911 break;
912 }
913
914 /* whether the video is interlaced */
915 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
916 guint64 num;
917
918 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
919 break;
920
921 if (num == 1)
922 videocontext->interlace_mode =
923 GST_MATROSKA_INTERLACE_MODE_INTERLACED;
924 else if (num == 2)
925 videocontext->interlace_mode =
926 GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
927 else
928 videocontext->interlace_mode =
929 GST_MATROSKA_INTERLACE_MODE_UNKNOWN;
930
931 GST_DEBUG_OBJECT (demux, "video track interlacing mode: %d",
932 videocontext->interlace_mode);
933 break;
934 }
935
936 /* aspect ratio behaviour */
937 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
938 guint64 num;
939
940 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
941 break;
942
943 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
944 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
945 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
946 GST_WARNING_OBJECT (demux,
947 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
948 break;
949 }
950 GST_DEBUG_OBJECT (demux,
951 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
952 videocontext->asr_mode = num;
953 break;
954 }
955
956 /* colourspace (only matters for raw video) fourcc */
957 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
958 guint8 *data;
959 guint64 datalen;
960
961 if ((ret =
962 gst_ebml_read_binary (ebml, &id, &data,
963 &datalen)) != GST_FLOW_OK)
964 break;
965
966 if (datalen != 4) {
967 g_free (data);
968 GST_WARNING_OBJECT (demux,
969 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
970 datalen);
971 break;
972 }
973
974 memcpy (&videocontext->fourcc, data, 4);
975 GST_DEBUG_OBJECT (demux,
976 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
977 GST_FOURCC_ARGS (videocontext->fourcc));
978 g_free (data);
979 break;
980 }
981
982 /* color info */
983 case GST_MATROSKA_ID_VIDEOCOLOUR:{
984 ret = gst_matroska_demux_parse_colour (demux, ebml, videocontext);
985 break;
986 }
987
988 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
989 {
990 guint64 num;
991
992 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
993 break;
994
995 GST_DEBUG_OBJECT (demux, "StereoMode: %" G_GUINT64_FORMAT, num);
996
997 switch (num) {
998 case GST_MATROSKA_STEREO_MODE_SBS_RL:
999 videocontext->multiview_flags =
1000 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1001 /* fall through */
1002 case GST_MATROSKA_STEREO_MODE_SBS_LR:
1003 videocontext->multiview_mode =
1004 GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
1005 break;
1006 case GST_MATROSKA_STEREO_MODE_TB_RL:
1007 videocontext->multiview_flags =
1008 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1009 /* fall through */
1010 case GST_MATROSKA_STEREO_MODE_TB_LR:
1011 videocontext->multiview_mode =
1012 GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM;
1013 break;
1014 case GST_MATROSKA_STEREO_MODE_CHECKER_RL:
1015 videocontext->multiview_flags =
1016 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1017 /* fall through */
1018 case GST_MATROSKA_STEREO_MODE_CHECKER_LR:
1019 videocontext->multiview_mode =
1020 GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD;
1021 break;
1022 case GST_MATROSKA_STEREO_MODE_FBF_RL:
1023 videocontext->multiview_flags =
1024 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1025 /* fall through */
1026 case GST_MATROSKA_STEREO_MODE_FBF_LR:
1027 videocontext->multiview_mode =
1028 GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
1029 /* FIXME: In frame-by-frame mode, left/right frame buffers are
1030 * laced within one block, and we'll need to apply FIRST_IN_BUNDLE
1031 * accordingly. See http://www.matroska.org/technical/specs/index.html#StereoMode */
1032 GST_FIXME_OBJECT (demux,
1033 "Frame-by-frame stereoscopic mode not fully implemented");
1034 break;
1035 }
1036 break;
1037 }
1038
1039 default:
1040 GST_WARNING_OBJECT (demux,
1041 "Unknown TrackVideo subelement 0x%x - ignoring", id);
1042 /* fall through */
1043 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
1044 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
1045 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
1046 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
1047 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
1048 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
1049 ret = gst_ebml_read_skip (ebml);
1050 break;
1051 }
1052 }
1053
1054 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
1055 break;
1056 }
1057
1058 /* tracktype specific stuff for audio */
1059 case GST_MATROSKA_ID_TRACKAUDIO:{
1060 GstMatroskaTrackAudioContext *audiocontext;
1061
1062 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
1063
1064 if (!gst_matroska_track_init_audio_context (&context)) {
1065 GST_WARNING_OBJECT (demux,
1066 "TrackAudio element in non-audio track - ignoring track");
1067 ret = GST_FLOW_ERROR;
1068 break;
1069 }
1070
1071 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
1072 break;
1073
1074 audiocontext = (GstMatroskaTrackAudioContext *) context;
1075
1076 while (ret == GST_FLOW_OK &&
1077 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1078 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1079 break;
1080
1081 switch (id) {
1082 /* samplerate */
1083 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
1084 gdouble num;
1085
1086 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1087 break;
1088
1089
1090 if (num <= 0.0) {
1091 GST_WARNING_OBJECT (demux,
1092 "Invalid TrackAudioSamplingFrequency %lf", num);
1093 break;
1094 }
1095
1096 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
1097 audiocontext->samplerate = num;
1098 break;
1099 }
1100
1101 /* bitdepth */
1102 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
1103 guint64 num;
1104
1105 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1106 break;
1107
1108 if (num == 0) {
1109 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
1110 break;
1111 }
1112
1113 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
1114 num);
1115 audiocontext->bitdepth = num;
1116 break;
1117 }
1118
1119 /* channels */
1120 case GST_MATROSKA_ID_AUDIOCHANNELS:{
1121 guint64 num;
1122
1123 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1124 break;
1125
1126 if (num == 0) {
1127 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
1128 break;
1129 }
1130
1131 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
1132 num);
1133 audiocontext->channels = num;
1134 break;
1135 }
1136
1137 default:
1138 GST_WARNING_OBJECT (demux,
1139 "Unknown TrackAudio subelement 0x%x - ignoring", id);
1140 /* fall through */
1141 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
1142 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
1143 ret = gst_ebml_read_skip (ebml);
1144 break;
1145 }
1146 }
1147
1148 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
1149
1150 break;
1151 }
1152
1153 /* codec identifier */
1154 case GST_MATROSKA_ID_CODECID:{
1155 gchar *text;
1156
1157 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
1158 break;
1159
1160 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
1161 context->codec_id = text;
1162 break;
1163 }
1164
1165 /* codec private data */
1166 case GST_MATROSKA_ID_CODECPRIVATE:{
1167 guint8 *data;
1168 guint64 size;
1169
1170 if ((ret =
1171 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
1172 break;
1173
1174 context->codec_priv = data;
1175 context->codec_priv_size = size;
1176
1177 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1178 size);
1179 break;
1180 }
1181
1182 /* name of the codec */
1183 case GST_MATROSKA_ID_CODECNAME:{
1184 gchar *text;
1185
1186 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1187 break;
1188
1189 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1190 context->codec_name = text;
1191 break;
1192 }
1193
1194 /* codec delay */
1195 case GST_MATROSKA_ID_CODECDELAY:{
1196 guint64 num;
1197
1198 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1199 break;
1200
1201 context->codec_delay = num;
1202
1203 GST_DEBUG_OBJECT (demux, "CodecDelay: %" GST_TIME_FORMAT,
1204 GST_TIME_ARGS (num));
1205 break;
1206 }
1207
1208 /* codec delay */
1209 case GST_MATROSKA_ID_SEEKPREROLL:{
1210 guint64 num;
1211
1212 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1213 break;
1214
1215 context->seek_preroll = num;
1216
1217 GST_DEBUG_OBJECT (demux, "SeekPreroll: %" GST_TIME_FORMAT,
1218 GST_TIME_ARGS (num));
1219 break;
1220 }
1221
1222 /* name of this track */
1223 case GST_MATROSKA_ID_TRACKNAME:{
1224 gchar *text;
1225
1226 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1227 break;
1228
1229 context->name = text;
1230 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1231 break;
1232 }
1233
1234 /* language (matters for audio/subtitles, mostly) */
1235 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1236 gchar *text;
1237
1238 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1239 break;
1240
1241
1242 context->language = text;
1243
1244 /* fre-ca => fre */
1245 if (strlen (context->language) >= 4 && context->language[3] == '-')
1246 context->language[3] = '\0';
1247
1248 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1249 GST_STR_NULL (context->language));
1250 break;
1251 }
1252
1253 /* whether this is actually used */
1254 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1255 guint64 num;
1256
1257 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1258 break;
1259
1260 if (num)
1261 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1262 else
1263 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1264
1265 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1266 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1267 break;
1268 }
1269
1270 /* whether it's the default for this track type */
1271 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1272 guint64 num;
1273
1274 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1275 break;
1276
1277 if (num)
1278 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1279 else
1280 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1281
1282 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1283 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
1284 break;
1285 }
1286
1287 /* whether the track must be used during playback */
1288 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1289 guint64 num;
1290
1291 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1292 break;
1293
1294 if (num)
1295 context->flags |= GST_MATROSKA_TRACK_FORCED;
1296 else
1297 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1298
1299 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1300 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
1301 break;
1302 }
1303
1304 /* lacing (like MPEG, where blocks don't end/start on frame
1305 * boundaries) */
1306 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1307 guint64 num;
1308
1309 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1310 break;
1311
1312 if (num)
1313 context->flags |= GST_MATROSKA_TRACK_LACING;
1314 else
1315 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1316
1317 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1318 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
1319 break;
1320 }
1321
1322 /* default length (in time) of one data block in this track */
1323 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1324 guint64 num;
1325
1326 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1327 break;
1328
1329
1330 if (num == 0) {
1331 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1332 break;
1333 }
1334
1335 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1336 num);
1337 context->default_duration = num;
1338 break;
1339 }
1340
1341 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1342 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1343 ebml, context);
1344 break;
1345 }
1346
1347 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1348 gdouble num;
1349
1350 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1351 break;
1352
1353 if (num <= 0.0) {
1354 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1355 break;
1356 }
1357
1358 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1359 context->timecodescale = num;
1360 break;
1361 }
1362
1363 default:
1364 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1365 /* pass-through */
1366
1367 /* we ignore these because they're nothing useful (i.e. crap)
1368 * or simply not implemented yet. */
1369 case GST_MATROSKA_ID_TRACKMINCACHE:
1370 case GST_MATROSKA_ID_TRACKMAXCACHE:
1371 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1372 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1373 case GST_MATROSKA_ID_TRACKOVERLAY:
1374 case GST_MATROSKA_ID_TRACKTRANSLATE:
1375 case GST_MATROSKA_ID_TRACKOFFSET:
1376 case GST_MATROSKA_ID_CODECSETTINGS:
1377 case GST_MATROSKA_ID_CODECINFOURL:
1378 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1379 case GST_MATROSKA_ID_CODECDECODEALL:
1380 ret = gst_ebml_read_skip (ebml);
1381 break;
1382 }
1383 }
1384
1385 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1386
1387 /* Decode codec private data if necessary */
1388 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1389 && context->codec_priv_size > 0) {
1390 if (!gst_matroska_decode_data (context->encodings,
1391 &context->codec_priv, &context->codec_priv_size,
1392 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1393 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1394 ret = GST_FLOW_ERROR;
1395 }
1396 }
1397
1398 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1399 && ret != GST_FLOW_EOS)) {
1400 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1401 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1402
1403 gst_matroska_track_free (context);
1404 context = NULL;
1405 *dest_context = NULL;
1406 return ret;
1407 }
1408
1409 /* check for a cached track taglist */
1410 cached_taglist =
1411 (GstTagList *) g_hash_table_lookup (demux->common.cached_track_taglists,
1412 GUINT_TO_POINTER (context->uid));
1413 if (cached_taglist)
1414 gst_tag_list_insert (context->tags, cached_taglist, GST_TAG_MERGE_APPEND);
1415
1416 /* compute caps */
1417 switch (context->type) {
1418 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1419 GstMatroskaTrackVideoContext *videocontext =
1420 (GstMatroskaTrackVideoContext *) context;
1421
1422 caps = gst_matroska_demux_video_caps (videocontext,
1423 context->codec_id, context->codec_priv,
1424 context->codec_priv_size, &codec, &riff_fourcc);
1425
1426 if (codec) {
1427 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1428 GST_TAG_VIDEO_CODEC, codec, NULL);
1429 context->tags_changed = TRUE;
1430 g_free (codec);
1431 }
1432 break;
1433 }
1434
1435 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1436 GstMatroskaTrackAudioContext *audiocontext =
1437 (GstMatroskaTrackAudioContext *) context;
1438
1439 caps = gst_matroska_demux_audio_caps (audiocontext,
1440 context->codec_id, context->codec_priv, context->codec_priv_size,
1441 &codec, &riff_audio_fmt);
1442
1443 if (codec) {
1444 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1445 GST_TAG_AUDIO_CODEC, codec, NULL);
1446 context->tags_changed = TRUE;
1447 g_free (codec);
1448 }
1449 break;
1450 }
1451
1452 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1453 GstMatroskaTrackSubtitleContext *subtitlecontext =
1454 (GstMatroskaTrackSubtitleContext *) context;
1455
1456 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1457 context->codec_id, context->codec_priv, context->codec_priv_size);
1458 break;
1459 }
1460
1461 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1462 case GST_MATROSKA_TRACK_TYPE_LOGO:
1463 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1464 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1465 default:
1466 /* we should already have quit by now */
1467 g_assert_not_reached ();
1468 }
1469
1470 if ((context->language == NULL || *context->language == '\0') &&
1471 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1472 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1473 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1474 context->language = g_strdup ("eng");
1475 }
1476
1477 if (context->language) {
1478 const gchar *lang;
1479
1480 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1481 lang = gst_tag_get_language_code (context->language);
1482 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1483 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1484
1485 if (context->name) {
1486 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1487 GST_TAG_TITLE, context->name, NULL);
1488 }
1489 context->tags_changed = TRUE;
1490 }
1491
1492 if (caps == NULL) {
1493 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1494 "codec_id='%s'", context->codec_id);
1495 switch (context->type) {
1496 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1497 caps = gst_caps_new_empty_simple ("video/x-unknown");
1498 break;
1499 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1500 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1501 break;
1502 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1503 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1504 break;
1505 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1506 default:
1507 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1508 break;
1509 }
1510 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1511 NULL);
1512
1513 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1514 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1515 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1516 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1517 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1518 GST_FOURCC_ARGS (riff_fourcc));
1519 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1520 g_free (fstr);
1521 }
1522 } else if (context->stream_headers != NULL) {
1523 gst_matroska_demux_add_stream_headers_to_caps (demux,
1524 context->stream_headers, caps);
1525 }
1526
1527 if (context->encodings) {
1528 GstMatroskaTrackEncoding *enc;
1529 guint i;
1530
1531 for (i = 0; i < context->encodings->len; i++) {
1532 enc = &g_array_index (context->encodings, GstMatroskaTrackEncoding, i);
1533 if (enc->type == GST_MATROSKA_ENCODING_ENCRYPTION /* encryption */ ) {
1534 GstStructure *s = gst_caps_get_structure (caps, 0);
1535 if (!gst_structure_has_name (s, "application/x-webm-enc")) {
1536 gst_structure_set (s, "original-media-type", G_TYPE_STRING,
1537 gst_structure_get_name (s), NULL);
1538 gst_structure_set (s, "encryption-algorithm", G_TYPE_STRING,
1539 gst_matroska_track_encryption_algorithm_name (enc->enc_algo),
1540 NULL);
1541 gst_structure_set (s, "encoding-scope", G_TYPE_STRING,
1542 gst_matroska_track_encoding_scope_name (enc->scope), NULL);
1543 gst_structure_set (s, "cipher-mode", G_TYPE_STRING,
1544 gst_matroska_track_encryption_cipher_mode_name
1545 (enc->enc_cipher_mode), NULL);
1546 gst_structure_set_name (s, "application/x-webm-enc");
1547 }
1548 }
1549 }
1550 }
1551
1552 context->caps = caps;
1553
1554 /* tadaah! */
1555 *dest_context = context;
1556 return ret;
1557 }
1558
1559 static void
gst_matroska_demux_add_stream(GstMatroskaDemux * demux,GstMatroskaTrackContext * context)1560 gst_matroska_demux_add_stream (GstMatroskaDemux * demux,
1561 GstMatroskaTrackContext * context)
1562 {
1563 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
1564 gchar *padname = NULL;
1565 GstPadTemplate *templ = NULL;
1566 GstStreamFlags stream_flags;
1567
1568 GstEvent *stream_start;
1569
1570 gchar *stream_id;
1571
1572 g_ptr_array_add (demux->common.src, context);
1573 context->index = demux->common.num_streams++;
1574 g_assert (demux->common.src->len == demux->common.num_streams);
1575 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1) =
1576 context;
1577
1578 /* now create the GStreamer connectivity */
1579 switch (context->type) {
1580 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1581 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1582 templ = gst_element_class_get_pad_template (klass, "video_%u");
1583
1584 if (!context->intra_only)
1585 demux->have_nonintraonly_v_streams = TRUE;
1586 break;
1587
1588 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1589 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1590 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1591 break;
1592
1593 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1594 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1595 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1596 break;
1597
1598 default:
1599 /* we should already have quit by now */
1600 g_assert_not_reached ();
1601 }
1602
1603 /* the pad in here */
1604 context->pad = gst_pad_new_from_template (templ, padname);
1605
1606 gst_pad_set_event_function (context->pad,
1607 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1608 gst_pad_set_query_function (context->pad,
1609 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1610
1611 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1612 padname, context->caps);
1613
1614 gst_pad_set_element_private (context->pad, context);
1615
1616 gst_pad_use_fixed_caps (context->pad);
1617 gst_pad_set_active (context->pad, TRUE);
1618
1619 stream_id =
1620 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1621 "%03" G_GUINT64_FORMAT ":%03" G_GUINT64_FORMAT,
1622 context->num, context->uid);
1623 stream_start =
1624 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1625 0);
1626 if (stream_start) {
1627 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1628 demux->have_group_id = TRUE;
1629 else
1630 demux->have_group_id = FALSE;
1631 gst_event_unref (stream_start);
1632 } else if (!demux->have_group_id) {
1633 demux->have_group_id = TRUE;
1634 demux->group_id = gst_util_group_id_next ();
1635 }
1636
1637 stream_start = gst_event_new_stream_start (stream_id);
1638 g_free (stream_id);
1639 if (demux->have_group_id)
1640 gst_event_set_group_id (stream_start, demux->group_id);
1641 stream_flags = GST_STREAM_FLAG_NONE;
1642 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1643 stream_flags |= GST_STREAM_FLAG_SPARSE;
1644 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1645 stream_flags |= GST_STREAM_FLAG_SELECT;
1646 else if (!(context->flags & GST_MATROSKA_TRACK_ENABLED))
1647 stream_flags |= GST_STREAM_FLAG_UNSELECT;
1648
1649 gst_event_set_stream_flags (stream_start, stream_flags);
1650 gst_pad_push_event (context->pad, stream_start);
1651 gst_pad_set_caps (context->pad, context->caps);
1652
1653
1654 if (demux->common.global_tags) {
1655 GstEvent *tag_event;
1656
1657 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1658 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1659 GST_DEBUG_OBJECT (context->pad, "Sending global_tags %p: %" GST_PTR_FORMAT,
1660 demux->common.global_tags, demux->common.global_tags);
1661
1662 tag_event =
1663 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1664
1665 gst_pad_push_event (context->pad, tag_event);
1666 }
1667
1668 if (G_UNLIKELY (context->tags_changed)) {
1669 GST_DEBUG_OBJECT (context->pad, "Sending tags %p: %"
1670 GST_PTR_FORMAT, context->tags, context->tags);
1671 gst_pad_push_event (context->pad,
1672 gst_event_new_tag (gst_tag_list_copy (context->tags)));
1673 context->tags_changed = FALSE;
1674 }
1675
1676 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1677 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1678
1679 g_free (padname);
1680 }
1681
1682 static gboolean
gst_matroska_demux_query(GstMatroskaDemux * demux,GstPad * pad,GstQuery * query)1683 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1684 GstQuery * query)
1685 {
1686 gboolean res = FALSE;
1687 GstMatroskaTrackContext *context = NULL;
1688
1689 if (pad) {
1690 context = gst_pad_get_element_private (pad);
1691 }
1692
1693 switch (GST_QUERY_TYPE (query)) {
1694 case GST_QUERY_POSITION:
1695 {
1696 GstFormat format;
1697
1698 gst_query_parse_position (query, &format, NULL);
1699
1700 res = TRUE;
1701 if (format == GST_FORMAT_TIME) {
1702 GST_OBJECT_LOCK (demux);
1703 if (context)
1704 gst_query_set_position (query, GST_FORMAT_TIME,
1705 MAX (context->pos, demux->stream_start_time) -
1706 demux->stream_start_time);
1707 else
1708 gst_query_set_position (query, GST_FORMAT_TIME,
1709 MAX (demux->common.segment.position, demux->stream_start_time) -
1710 demux->stream_start_time);
1711 GST_OBJECT_UNLOCK (demux);
1712 } else if (format == GST_FORMAT_DEFAULT && context
1713 && context->default_duration) {
1714 GST_OBJECT_LOCK (demux);
1715 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1716 context->pos / context->default_duration);
1717 GST_OBJECT_UNLOCK (demux);
1718 } else {
1719 GST_DEBUG_OBJECT (demux,
1720 "only position query in TIME and DEFAULT format is supported");
1721 res = FALSE;
1722 }
1723
1724 break;
1725 }
1726 case GST_QUERY_DURATION:
1727 {
1728 GstFormat format;
1729
1730 gst_query_parse_duration (query, &format, NULL);
1731
1732 res = TRUE;
1733 if (format == GST_FORMAT_TIME) {
1734 GST_OBJECT_LOCK (demux);
1735 gst_query_set_duration (query, GST_FORMAT_TIME,
1736 demux->common.segment.duration);
1737 GST_OBJECT_UNLOCK (demux);
1738 } else if (format == GST_FORMAT_DEFAULT && context
1739 && context->default_duration) {
1740 GST_OBJECT_LOCK (demux);
1741 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1742 demux->common.segment.duration / context->default_duration);
1743 GST_OBJECT_UNLOCK (demux);
1744 } else {
1745 GST_DEBUG_OBJECT (demux,
1746 "only duration query in TIME and DEFAULT format is supported");
1747 res = FALSE;
1748 }
1749 break;
1750 }
1751
1752 case GST_QUERY_SEEKING:
1753 {
1754 GstFormat fmt;
1755
1756 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1757 GST_OBJECT_LOCK (demux);
1758 if (fmt == GST_FORMAT_TIME) {
1759 gboolean seekable;
1760
1761 if (demux->streaming) {
1762 /* assuming we'll be able to get an index ... */
1763 seekable = demux->seekable;
1764 } else {
1765 seekable = TRUE;
1766 }
1767
1768 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1769 0, demux->common.segment.duration);
1770 res = TRUE;
1771 }
1772 GST_OBJECT_UNLOCK (demux);
1773 break;
1774 }
1775 case GST_QUERY_SEGMENT:
1776 {
1777 GstFormat format;
1778 gint64 start, stop;
1779
1780 format = demux->common.segment.format;
1781
1782 start =
1783 gst_segment_to_stream_time (&demux->common.segment, format,
1784 demux->common.segment.start);
1785 if ((stop = demux->common.segment.stop) == -1)
1786 stop = demux->common.segment.duration;
1787 else
1788 stop =
1789 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1790
1791 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1792 stop);
1793 res = TRUE;
1794 break;
1795 }
1796 default:
1797 if (pad)
1798 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1799 else
1800 res =
1801 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1802 query);
1803 break;
1804 }
1805
1806 return res;
1807 }
1808
1809 static gboolean
gst_matroska_demux_element_query(GstElement * element,GstQuery * query)1810 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1811 {
1812 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1813 }
1814
1815 static gboolean
gst_matroska_demux_handle_src_query(GstPad * pad,GstObject * parent,GstQuery * query)1816 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1817 GstQuery * query)
1818 {
1819 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1820
1821 return gst_matroska_demux_query (demux, pad, query);
1822 }
1823
1824 /* returns FALSE if there are no pads to deliver event to,
1825 * otherwise TRUE (whatever the outcome of event sending),
1826 * takes ownership of the passed event! */
1827 static gboolean
gst_matroska_demux_send_event(GstMatroskaDemux * demux,GstEvent * event)1828 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1829 {
1830 gboolean ret = FALSE;
1831 gint i;
1832
1833 g_return_val_if_fail (event != NULL, FALSE);
1834
1835 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1836 GST_EVENT_TYPE_NAME (event));
1837
1838 g_assert (demux->common.src->len == demux->common.num_streams);
1839 for (i = 0; i < demux->common.src->len; i++) {
1840 GstMatroskaTrackContext *stream;
1841
1842 stream = g_ptr_array_index (demux->common.src, i);
1843 gst_event_ref (event);
1844 gst_pad_push_event (stream->pad, event);
1845 ret = TRUE;
1846 }
1847
1848 gst_event_unref (event);
1849 return ret;
1850 }
1851
1852 static void
gst_matroska_demux_send_tags(GstMatroskaDemux * demux)1853 gst_matroska_demux_send_tags (GstMatroskaDemux * demux)
1854 {
1855 gint i;
1856
1857 if (G_UNLIKELY (demux->common.global_tags_changed)) {
1858 GstEvent *tag_event;
1859 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1860 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1861 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1862 demux->common.global_tags, demux->common.global_tags);
1863
1864 tag_event =
1865 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1866
1867 for (i = 0; i < demux->common.src->len; i++) {
1868 GstMatroskaTrackContext *stream;
1869
1870 stream = g_ptr_array_index (demux->common.src, i);
1871 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1872 }
1873
1874 gst_event_unref (tag_event);
1875 demux->common.global_tags_changed = FALSE;
1876 }
1877
1878 g_assert (demux->common.src->len == demux->common.num_streams);
1879 for (i = 0; i < demux->common.src->len; i++) {
1880 GstMatroskaTrackContext *stream;
1881
1882 stream = g_ptr_array_index (demux->common.src, i);
1883
1884 if (G_UNLIKELY (stream->tags_changed)) {
1885 GST_DEBUG_OBJECT (demux, "Sending tags %p for pad %s:%s : %"
1886 GST_PTR_FORMAT, stream->tags,
1887 GST_DEBUG_PAD_NAME (stream->pad), stream->tags);
1888 gst_pad_push_event (stream->pad,
1889 gst_event_new_tag (gst_tag_list_copy (stream->tags)));
1890 stream->tags_changed = FALSE;
1891 }
1892 }
1893 }
1894
1895 static gboolean
gst_matroska_demux_element_send_event(GstElement * element,GstEvent * event)1896 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1897 {
1898 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1899 gboolean res;
1900
1901 g_return_val_if_fail (event != NULL, FALSE);
1902
1903 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1904 /* no seeking until we are (safely) ready */
1905 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
1906 GST_DEBUG_OBJECT (demux,
1907 "not ready for seeking yet, deferring seek: %" GST_PTR_FORMAT, event);
1908 if (demux->deferred_seek_event)
1909 gst_event_unref (demux->deferred_seek_event);
1910 demux->deferred_seek_event = event;
1911 demux->deferred_seek_pad = NULL;
1912 return TRUE;
1913 }
1914 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1915 } else {
1916 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1917 GST_EVENT_TYPE_NAME (event));
1918 res = FALSE;
1919 }
1920 gst_event_unref (event);
1921 return res;
1922 }
1923
1924 static gboolean
gst_matroska_demux_move_to_entry(GstMatroskaDemux * demux,GstMatroskaIndex * entry,gboolean reset,gboolean update)1925 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1926 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1927 {
1928 gint i;
1929
1930 GST_OBJECT_LOCK (demux);
1931
1932 if (update) {
1933 /* seek (relative to matroska segment) */
1934 /* position might be invalid; will error when streaming resumes ... */
1935 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1936 demux->next_cluster_offset = 0;
1937
1938 GST_DEBUG_OBJECT (demux,
1939 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1940 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1941 entry->block, GST_TIME_ARGS (entry->time));
1942
1943 /* update the time */
1944 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1945 gst_flow_combiner_reset (demux->flowcombiner);
1946 demux->common.segment.position = entry->time;
1947 demux->seek_block = entry->block;
1948 demux->seek_first = TRUE;
1949 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1950 }
1951
1952 for (i = 0; i < demux->common.src->len; i++) {
1953 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1954
1955 if (reset) {
1956 stream->to_offset = G_MAXINT64;
1957 } else {
1958 if (stream->from_offset != -1)
1959 stream->to_offset = stream->from_offset;
1960 }
1961 stream->from_offset = -1;
1962 stream->from_time = GST_CLOCK_TIME_NONE;
1963 }
1964
1965 GST_OBJECT_UNLOCK (demux);
1966
1967 return TRUE;
1968 }
1969
1970 static gint
gst_matroska_cluster_compare(gint64 * i1,gint64 * i2)1971 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1972 {
1973 if (*i1 < *i2)
1974 return -1;
1975 else if (*i1 > *i2)
1976 return 1;
1977 else
1978 return 0;
1979 }
1980
1981 /* searches for a cluster start from @pos,
1982 * return GST_FLOW_OK and cluster position in @pos if found */
1983 static GstFlowReturn
gst_matroska_demux_search_cluster(GstMatroskaDemux * demux,gint64 * pos,gboolean forward)1984 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos,
1985 gboolean forward)
1986 {
1987 gint64 newpos = *pos;
1988 gint64 orig_offset;
1989 GstFlowReturn ret = GST_FLOW_OK;
1990 const guint chunk = 128 * 1024;
1991 GstBuffer *buf = NULL;
1992 GstMapInfo map;
1993 gpointer data = NULL;
1994 gsize size;
1995 guint64 length;
1996 guint32 id;
1997 guint needed;
1998 gint64 oldpos, oldlength;
1999
2000 orig_offset = demux->common.offset;
2001
2002 GST_LOG_OBJECT (demux, "searching cluster %s offset %" G_GINT64_FORMAT,
2003 forward ? "following" : "preceding", *pos);
2004
2005 if (demux->clusters) {
2006 gint64 *cpos;
2007
2008 cpos = gst_util_array_binary_search (demux->clusters->data,
2009 demux->clusters->len, sizeof (gint64),
2010 (GCompareDataFunc) gst_matroska_cluster_compare,
2011 forward ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE, pos, NULL);
2012 /* sanity check */
2013 if (cpos) {
2014 GST_DEBUG_OBJECT (demux,
2015 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
2016 demux->common.offset = *cpos;
2017 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2018 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2019 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
2020 newpos = *cpos;
2021 goto exit;
2022 }
2023 }
2024 }
2025
2026 /* read in at newpos and scan for ebml cluster id */
2027 oldpos = oldlength = -1;
2028 while (1) {
2029 GstByteReader reader;
2030 gint cluster_pos;
2031 guint toread = chunk;
2032
2033 if (!forward) {
2034 /* never read beyond the requested target */
2035 if (G_UNLIKELY (newpos < chunk)) {
2036 toread = newpos;
2037 newpos = 0;
2038 } else {
2039 newpos -= chunk;
2040 }
2041 }
2042 if (buf != NULL) {
2043 gst_buffer_unmap (buf, &map);
2044 gst_buffer_unref (buf);
2045 buf = NULL;
2046 }
2047 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, toread, &buf);
2048 if (ret != GST_FLOW_OK)
2049 break;
2050 GST_DEBUG_OBJECT (demux,
2051 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
2052 gst_buffer_get_size (buf), newpos);
2053 gst_buffer_map (buf, &map, GST_MAP_READ);
2054 data = map.data;
2055 size = map.size;
2056 if (oldpos == newpos && oldlength == map.size) {
2057 GST_ERROR_OBJECT (demux, "Stuck at same position");
2058 ret = GST_FLOW_ERROR;
2059 goto exit;
2060 } else {
2061 oldpos = newpos;
2062 oldlength = map.size;
2063 }
2064
2065 gst_byte_reader_init (&reader, data, size);
2066 cluster_pos = -1;
2067 while (1) {
2068 gint found = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
2069 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
2070 if (forward) {
2071 cluster_pos = found;
2072 break;
2073 }
2074 /* need last occurrence when searching backwards */
2075 if (found >= 0) {
2076 cluster_pos = gst_byte_reader_get_pos (&reader) + found;
2077 gst_byte_reader_skip (&reader, found + 4);
2078 } else {
2079 break;
2080 }
2081 }
2082
2083 if (cluster_pos >= 0) {
2084 newpos += cluster_pos;
2085 GST_DEBUG_OBJECT (demux,
2086 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
2087 /* extra checks whether we really sync'ed to a cluster:
2088 * - either it is the first and only cluster
2089 * - either there is a cluster after this one
2090 * - either cluster length is undefined
2091 */
2092 /* ok if first cluster (there may not a subsequent one) */
2093 if (newpos == demux->first_cluster_offset) {
2094 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
2095 break;
2096 }
2097 demux->common.offset = newpos;
2098 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2099 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2100 if (ret != GST_FLOW_OK) {
2101 GST_DEBUG_OBJECT (demux, "need more data -> continue");
2102 goto next;
2103 }
2104 g_assert (id == GST_MATROSKA_ID_CLUSTER);
2105 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
2106 length, needed);
2107 /* ok if undefined length or first cluster */
2108 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
2109 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
2110 break;
2111 }
2112 /* skip cluster */
2113 demux->common.offset += length + needed;
2114 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2115 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2116 if (ret != GST_FLOW_OK)
2117 goto next;
2118 GST_DEBUG_OBJECT (demux, "next element is %scluster",
2119 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
2120 if (id == GST_MATROSKA_ID_CLUSTER)
2121 break;
2122 next:
2123 if (forward)
2124 newpos += 1;
2125 } else {
2126 /* partial cluster id may have been in tail of buffer */
2127 newpos +=
2128 forward ? MAX (gst_byte_reader_get_remaining (&reader), 4) - 3 : 3;
2129 }
2130 }
2131
2132 if (buf) {
2133 gst_buffer_unmap (buf, &map);
2134 gst_buffer_unref (buf);
2135 buf = NULL;
2136 }
2137
2138 exit:
2139 demux->common.offset = orig_offset;
2140 *pos = newpos;
2141 return ret;
2142 }
2143
2144 /* Three states to express: starts with I-frame, starts with delta, don't know */
2145 typedef enum
2146 {
2147 CLUSTER_STATUS_NONE = 0,
2148 CLUSTER_STATUS_STARTS_WITH_KEYFRAME,
2149 CLUSTER_STATUS_STARTS_WITH_DELTAUNIT,
2150 } ClusterStatus;
2151
2152 typedef struct
2153 {
2154 guint64 offset;
2155 guint64 size;
2156 guint64 prev_size;
2157 GstClockTime time;
2158 ClusterStatus status;
2159 } ClusterInfo;
2160
2161 static const gchar *
cluster_status_get_nick(ClusterStatus status)2162 cluster_status_get_nick (ClusterStatus status)
2163 {
2164 switch (status) {
2165 case CLUSTER_STATUS_NONE:
2166 return "none";
2167 case CLUSTER_STATUS_STARTS_WITH_KEYFRAME:
2168 return "key";
2169 case CLUSTER_STATUS_STARTS_WITH_DELTAUNIT:
2170 return "delta";
2171 }
2172 return "???";
2173 }
2174
2175 /* Skip ebml-coded number:
2176 * 1xxx.. = 1 byte
2177 * 01xx.. = 2 bytes
2178 * 001x.. = 3 bytes, etc.
2179 */
2180 static gboolean
bit_reader_skip_ebml_num(GstBitReader * br)2181 bit_reader_skip_ebml_num (GstBitReader * br)
2182 {
2183 guint8 i, v = 0;
2184
2185 if (!gst_bit_reader_peek_bits_uint8 (br, &v, 8))
2186 return FALSE;
2187
2188 for (i = 0; i < 8; i++) {
2189 if ((v & (0x80 >> i)) != 0)
2190 break;
2191 }
2192 return gst_bit_reader_skip (br, (i + 1) * 8);
2193 }
2194
2195 /* Don't probe more than that many bytes into the cluster for keyframe info
2196 * (random value, mostly for sanity checking) */
2197 #define MAX_CLUSTER_INFO_PROBE_LENGTH 256
2198
2199 static gboolean
gst_matroska_demux_peek_cluster_info(GstMatroskaDemux * demux,ClusterInfo * cluster,guint64 offset)2200 gst_matroska_demux_peek_cluster_info (GstMatroskaDemux * demux,
2201 ClusterInfo * cluster, guint64 offset)
2202 {
2203 demux->common.offset = offset;
2204 demux->cluster_time = GST_CLOCK_TIME_NONE;
2205
2206 cluster->offset = offset;
2207 cluster->size = 0;
2208 cluster->prev_size = 0;
2209 cluster->time = GST_CLOCK_TIME_NONE;
2210 cluster->status = CLUSTER_STATUS_NONE;
2211
2212 /* parse first few elements in cluster */
2213 do {
2214 GstFlowReturn flow;
2215 guint64 length;
2216 guint32 id;
2217 guint needed;
2218
2219 flow = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2220 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2221
2222 if (flow != GST_FLOW_OK)
2223 break;
2224
2225 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2226 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
2227 length, needed);
2228
2229 /* Reached start of next cluster without finding data, stop processing */
2230 if (id == GST_MATROSKA_ID_CLUSTER && cluster->offset != offset)
2231 break;
2232
2233 /* Not going to parse into these for now, stop processing */
2234 if (id == GST_MATROSKA_ID_ENCRYPTEDBLOCK
2235 || id == GST_MATROSKA_ID_BLOCKGROUP || id == GST_MATROSKA_ID_BLOCK)
2236 break;
2237
2238 /* SimpleBlock: peek at headers to check if it's a keyframe */
2239 if (id == GST_MATROSKA_ID_SIMPLEBLOCK) {
2240 GstBitReader br;
2241 guint8 *d, hdr_len, v = 0;
2242
2243 GST_DEBUG_OBJECT (demux, "SimpleBlock found");
2244
2245 /* SimpleBlock header is max. 21 bytes */
2246 hdr_len = MIN (21, length);
2247
2248 flow = gst_matroska_read_common_peek_bytes (&demux->common,
2249 demux->common.offset, hdr_len, NULL, &d);
2250
2251 if (flow != GST_FLOW_OK)
2252 break;
2253
2254 gst_bit_reader_init (&br, d, hdr_len);
2255
2256 /* skip prefix: ebml id (SimpleBlock) + element length */
2257 if (!gst_bit_reader_skip (&br, 8 * needed))
2258 break;
2259
2260 /* skip track number (ebml coded) */
2261 if (!bit_reader_skip_ebml_num (&br))
2262 break;
2263
2264 /* skip Timecode */
2265 if (!gst_bit_reader_skip (&br, 16))
2266 break;
2267
2268 /* read flags */
2269 if (!gst_bit_reader_get_bits_uint8 (&br, &v, 8))
2270 break;
2271
2272 if ((v & 0x80) != 0)
2273 cluster->status = CLUSTER_STATUS_STARTS_WITH_KEYFRAME;
2274 else
2275 cluster->status = CLUSTER_STATUS_STARTS_WITH_DELTAUNIT;
2276
2277 break;
2278 }
2279
2280 flow = gst_matroska_demux_parse_id (demux, id, length, needed);
2281
2282 if (flow != GST_FLOW_OK)
2283 break;
2284
2285 switch (id) {
2286 case GST_MATROSKA_ID_CLUSTER:
2287 if (length == G_MAXUINT64)
2288 cluster->size = 0;
2289 else
2290 cluster->size = length + needed;
2291 break;
2292 case GST_MATROSKA_ID_PREVSIZE:
2293 cluster->prev_size = demux->cluster_prevsize;
2294 break;
2295 case GST_MATROSKA_ID_CLUSTERTIMECODE:
2296 cluster->time = demux->cluster_time * demux->common.time_scale;
2297 break;
2298 case GST_MATROSKA_ID_SILENTTRACKS:
2299 /* ignore and continue */
2300 break;
2301 default:
2302 GST_WARNING_OBJECT (demux, "Unknown ebml id 0x%08x (possibly garbage), "
2303 "bailing out", id);
2304 goto out;
2305 }
2306 } while (demux->common.offset - offset < MAX_CLUSTER_INFO_PROBE_LENGTH);
2307
2308 out:
2309
2310 GST_INFO_OBJECT (demux, "Cluster @ %" G_GUINT64_FORMAT ": "
2311 "time %" GST_TIME_FORMAT ", size %" G_GUINT64_FORMAT ", "
2312 "prev_size %" G_GUINT64_FORMAT ", %s", cluster->offset,
2313 GST_TIME_ARGS (cluster->time), cluster->size, cluster->prev_size,
2314 cluster_status_get_nick (cluster->status));
2315
2316 /* return success as long as we could extract the minimum useful information */
2317 return cluster->time != GST_CLOCK_TIME_NONE;
2318 }
2319
2320 /* returns TRUE if the cluster offset was updated */
2321 static gboolean
gst_matroska_demux_scan_back_for_keyframe_cluster(GstMatroskaDemux * demux,gint64 * cluster_offset,GstClockTime * cluster_time)2322 gst_matroska_demux_scan_back_for_keyframe_cluster (GstMatroskaDemux * demux,
2323 gint64 * cluster_offset, GstClockTime * cluster_time)
2324 {
2325 GstClockTime stream_start_time = demux->stream_start_time;
2326 guint64 first_cluster_offset = demux->first_cluster_offset;
2327 gint64 off = *cluster_offset;
2328 ClusterInfo cluster = { 0, };
2329
2330 GST_INFO_OBJECT (demux, "Checking if cluster starts with keyframe");
2331 while (off > first_cluster_offset) {
2332 if (!gst_matroska_demux_peek_cluster_info (demux, &cluster, off)) {
2333 GST_LOG_OBJECT (demux,
2334 "Couldn't get info on cluster @ %" G_GUINT64_FORMAT, off);
2335 break;
2336 }
2337
2338 /* Keyframe? Then we're done */
2339 if (cluster.status == CLUSTER_STATUS_STARTS_WITH_KEYFRAME) {
2340 GST_LOG_OBJECT (demux,
2341 "Found keyframe at start of cluster @ %" G_GUINT64_FORMAT, off);
2342 break;
2343 }
2344
2345 /* We only scan back if we *know* we landed on a cluster that
2346 * starts with a delta frame. */
2347 if (cluster.status != CLUSTER_STATUS_STARTS_WITH_DELTAUNIT) {
2348 GST_LOG_OBJECT (demux,
2349 "No delta frame at start of cluster @ %" G_GUINT64_FORMAT, off);
2350 break;
2351 }
2352
2353 GST_DEBUG_OBJECT (demux, "Cluster starts with delta frame, backtracking");
2354
2355 /* Don't scan back more than this much in time from the cluster we
2356 * originally landed on. This is mostly a sanity check in case a file
2357 * always has keyframes in the middle of clusters and never at the
2358 * beginning. Without this we would always scan back to the beginning
2359 * of the file in that case. */
2360 if (cluster.time != GST_CLOCK_TIME_NONE) {
2361 GstClockTimeDiff distance = GST_CLOCK_DIFF (cluster.time, *cluster_time);
2362
2363 if (distance < 0 || distance > demux->max_backtrack_distance * GST_SECOND) {
2364 GST_DEBUG_OBJECT (demux, "Haven't found cluster with keyframe within "
2365 "%u secs of original seek target cluster, stopping",
2366 demux->max_backtrack_distance);
2367 break;
2368 }
2369 }
2370
2371 /* If we have cluster prev_size we can skip back efficiently. If not,
2372 * we'll just do a brute force search for a cluster identifier */
2373 if (cluster.prev_size > 0 && off >= cluster.prev_size) {
2374 off -= cluster.prev_size;
2375 } else {
2376 GstFlowReturn flow;
2377
2378 GST_LOG_OBJECT (demux, "Cluster has no or invalid prev size, searching "
2379 "for previous cluster instead then");
2380
2381 flow = gst_matroska_demux_search_cluster (demux, &off, FALSE);
2382 if (flow != GST_FLOW_OK) {
2383 GST_DEBUG_OBJECT (demux, "cluster search yielded flow %s, stopping",
2384 gst_flow_get_name (flow));
2385 break;
2386 }
2387 }
2388
2389 if (off <= first_cluster_offset) {
2390 GST_LOG_OBJECT (demux, "Reached first cluster, stopping");
2391 *cluster_offset = first_cluster_offset;
2392 *cluster_time = stream_start_time;
2393 return TRUE;
2394 }
2395 GST_LOG_OBJECT (demux, "Trying prev cluster @ %" G_GUINT64_FORMAT, off);
2396 }
2397
2398 /* If we found a cluster starting with a keyframe jump to that instead,
2399 * otherwise leave everything as it was before */
2400 if (cluster.time != GST_CLOCK_TIME_NONE
2401 && (cluster.offset == first_cluster_offset
2402 || cluster.status == CLUSTER_STATUS_STARTS_WITH_KEYFRAME)) {
2403 *cluster_offset = cluster.offset;
2404 *cluster_time = cluster.time;
2405 return TRUE;
2406 }
2407
2408 return FALSE;
2409 }
2410
2411 /* bisect and scan through file for cluster starting before @time,
2412 * returns fake index entry with corresponding info on cluster */
2413 static GstMatroskaIndex *
gst_matroska_demux_search_pos(GstMatroskaDemux * demux,GstClockTime time)2414 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
2415 {
2416 GstMatroskaIndex *entry = NULL;
2417 GstMatroskaReadState current_state;
2418 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
2419 GstClockTime atime;
2420 gint64 opos, newpos, current_offset;
2421 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
2422 gint64 apos, maxpos;
2423 guint64 cluster_size = 0;
2424 GstFlowReturn ret;
2425 guint64 length;
2426 guint32 id;
2427 guint needed;
2428
2429 /* estimate new position, resync using cluster ebml id,
2430 * and bisect further or scan forward to appropriate cluster */
2431
2432 /* save some current global state which will be touched by our scanning */
2433 current_state = demux->common.state;
2434 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
2435
2436 current_cluster_offset = demux->cluster_offset;
2437 current_cluster_time = demux->cluster_time;
2438 current_offset = demux->common.offset;
2439
2440 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
2441
2442 /* estimate using start and last known cluster */
2443 GST_OBJECT_LOCK (demux);
2444 apos = demux->first_cluster_offset;
2445 atime = demux->stream_start_time;
2446 opos = demux->last_cluster_offset;
2447 otime = demux->stream_last_time;
2448 GST_OBJECT_UNLOCK (demux);
2449
2450 /* sanitize */
2451 time = MAX (time, atime);
2452 otime = MAX (otime, atime);
2453 opos = MAX (opos, apos);
2454
2455 maxpos = gst_matroska_read_common_get_length (&demux->common);
2456
2457 /* invariants;
2458 * apos <= opos
2459 * atime <= otime
2460 * apos always refer to a cluster before target time;
2461 * opos may or may not be after target time, but if it is once so,
2462 * then also in next iteration
2463 * */
2464
2465 retry:
2466 GST_LOG_OBJECT (demux,
2467 "apos: %" G_GUINT64_FORMAT ", atime: %" GST_TIME_FORMAT ", %"
2468 GST_TIME_FORMAT " in stream time, "
2469 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
2470 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
2471 GST_TIME_FORMAT, apos, GST_TIME_ARGS (atime),
2472 GST_TIME_ARGS (atime - demux->stream_start_time), opos,
2473 GST_TIME_ARGS (otime), GST_TIME_ARGS (otime - demux->stream_start_time),
2474 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
2475
2476 g_assert (atime <= otime);
2477 g_assert (apos <= opos);
2478 if (time == GST_CLOCK_TIME_NONE) {
2479 GST_DEBUG_OBJECT (demux, "searching last cluster");
2480 newpos = maxpos;
2481 if (newpos == -1) {
2482 GST_DEBUG_OBJECT (demux, "unknown file size; bailing out");
2483 goto exit;
2484 }
2485 } else if (otime <= atime) {
2486 newpos = apos;
2487 } else {
2488 newpos = apos +
2489 gst_util_uint64_scale (opos - apos, time - atime, otime - atime);
2490 if (maxpos != -1 && newpos > maxpos)
2491 newpos = maxpos;
2492 }
2493
2494 GST_DEBUG_OBJECT (demux,
2495 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
2496 GST_TIME_ARGS (time), newpos);
2497
2498 /* search backwards */
2499 if (newpos > apos) {
2500 ret = gst_matroska_demux_search_cluster (demux, &newpos, FALSE);
2501 if (ret != GST_FLOW_OK)
2502 goto exit;
2503 }
2504
2505 /* then start scanning and parsing for cluster time,
2506 * re-estimate if possible, otherwise next cluster and so on */
2507 /* note that each re-estimate is entered with a change in apos or opos,
2508 * avoiding infinite loop */
2509 demux->common.offset = newpos;
2510 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
2511 cluster_size = 0;
2512 prev_cluster_time = GST_CLOCK_TIME_NONE;
2513 while (1) {
2514 /* peek and parse some elements */
2515 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2516 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2517 if (ret != GST_FLOW_OK)
2518 goto error;
2519 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2520 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
2521 length, needed);
2522 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
2523 if (ret != GST_FLOW_OK)
2524 goto error;
2525
2526 if (id == GST_MATROSKA_ID_CLUSTER) {
2527 cluster_time = GST_CLOCK_TIME_NONE;
2528 if (length == G_MAXUINT64)
2529 cluster_size = 0;
2530 else
2531 cluster_size = length + needed;
2532 }
2533 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
2534 cluster_time == GST_CLOCK_TIME_NONE) {
2535 cluster_time = demux->cluster_time * demux->common.time_scale;
2536 cluster_offset = demux->cluster_offset;
2537 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
2538 " with time %" GST_TIME_FORMAT, cluster_offset,
2539 GST_TIME_ARGS (cluster_time));
2540 if (time == GST_CLOCK_TIME_NONE) {
2541 GST_DEBUG_OBJECT (demux, "found last cluster");
2542 prev_cluster_time = cluster_time;
2543 prev_cluster_offset = cluster_offset;
2544 break;
2545 }
2546 if (cluster_time > time) {
2547 GST_DEBUG_OBJECT (demux, "overshot target");
2548 /* cluster overshoots */
2549 if (cluster_offset == demux->first_cluster_offset) {
2550 /* but no prev one */
2551 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
2552 prev_cluster_time = cluster_time;
2553 prev_cluster_offset = cluster_offset;
2554 break;
2555 }
2556 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
2557 /* prev cluster did not overshoot, so prev cluster is target */
2558 break;
2559 } else {
2560 /* re-estimate using this new position info */
2561 opos = cluster_offset;
2562 otime = cluster_time;
2563 goto retry;
2564 }
2565 } else {
2566 /* cluster undershoots */
2567 GST_DEBUG_OBJECT (demux, "undershot target");
2568 /* ok if close enough */
2569 if (GST_CLOCK_DIFF (cluster_time, time) < 5 * GST_SECOND) {
2570 GST_DEBUG_OBJECT (demux, "target close enough");
2571 prev_cluster_time = cluster_time;
2572 prev_cluster_offset = cluster_offset;
2573 break;
2574 }
2575 if (otime > time) {
2576 /* we are in between atime and otime => can bisect if worthwhile */
2577 if (prev_cluster_time != GST_CLOCK_TIME_NONE &&
2578 cluster_time > prev_cluster_time &&
2579 (GST_CLOCK_DIFF (prev_cluster_time, cluster_time) * 10 <
2580 GST_CLOCK_DIFF (cluster_time, time))) {
2581 /* we moved at least one cluster forward,
2582 * and it looks like target is still far away,
2583 * let's estimate again */
2584 GST_DEBUG_OBJECT (demux, "bisecting with new apos");
2585 apos = cluster_offset;
2586 atime = cluster_time;
2587 goto retry;
2588 }
2589 }
2590 /* cluster undershoots, goto next one */
2591 prev_cluster_time = cluster_time;
2592 prev_cluster_offset = cluster_offset;
2593 /* skip cluster if length is defined,
2594 * otherwise will be skippingly parsed into */
2595 if (cluster_size) {
2596 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
2597 demux->common.offset = cluster_offset + cluster_size;
2598 demux->cluster_time = GST_CLOCK_TIME_NONE;
2599 } else {
2600 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
2601 }
2602 }
2603 }
2604 continue;
2605
2606 error:
2607 if (ret == GST_FLOW_EOS) {
2608 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
2609 break;
2610 }
2611 goto exit;
2612 }
2613
2614 /* In the bisect loop above we always undershoot and then jump forward
2615 * cluster-by-cluster until we overshoot, so if we get here we've gone
2616 * over and the previous cluster is where we need to go to. */
2617 cluster_offset = prev_cluster_offset;
2618 cluster_time = prev_cluster_time;
2619
2620 /* If we have video and can easily backtrack, check if we landed on a cluster
2621 * that starts with a keyframe - and if not backtrack until we find one that
2622 * does. */
2623 if (demux->have_nonintraonly_v_streams && demux->max_backtrack_distance > 0) {
2624 if (gst_matroska_demux_scan_back_for_keyframe_cluster (demux,
2625 &cluster_offset, &cluster_time)) {
2626 GST_INFO_OBJECT (demux, "Adjusted cluster to %" GST_TIME_FORMAT " @ "
2627 "%" G_GUINT64_FORMAT, GST_TIME_ARGS (cluster_time), cluster_offset);
2628 }
2629 }
2630
2631 entry = g_new0 (GstMatroskaIndex, 1);
2632 entry->time = cluster_time;
2633 entry->pos = cluster_offset - demux->common.ebml_segment_start;
2634 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
2635 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
2636
2637 exit:
2638
2639 /* restore some state */
2640 demux->cluster_offset = current_cluster_offset;
2641 demux->cluster_time = current_cluster_time;
2642 demux->common.offset = current_offset;
2643 demux->common.state = current_state;
2644
2645 return entry;
2646 }
2647
2648 static gboolean
gst_matroska_demux_handle_seek_event(GstMatroskaDemux * demux,GstPad * pad,GstEvent * event)2649 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
2650 GstPad * pad, GstEvent * event)
2651 {
2652 GstMatroskaIndex *entry = NULL;
2653 GstMatroskaIndex scan_entry;
2654 GstSeekFlags flags;
2655 GstSeekType cur_type, stop_type;
2656 GstFormat format;
2657 gboolean flush, keyunit, before, after, snap_next;
2658 gdouble rate;
2659 gint64 cur, stop;
2660 GstMatroskaTrackContext *track = NULL;
2661 GstSegment seeksegment = { 0, };
2662 gboolean update = TRUE;
2663 gboolean pad_locked = FALSE;
2664 guint32 seqnum;
2665 GstSearchMode snap_dir;
2666
2667 g_return_val_if_fail (event != NULL, FALSE);
2668
2669 if (pad)
2670 track = gst_pad_get_element_private (pad);
2671
2672 GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
2673
2674 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2675 &stop_type, &stop);
2676 seqnum = gst_event_get_seqnum (event);
2677
2678 /* we can only seek on time */
2679 if (format != GST_FORMAT_TIME) {
2680 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2681 return FALSE;
2682 }
2683
2684 /* copy segment, we need this because we still need the old
2685 * segment when we close the current segment. */
2686 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
2687
2688 /* pull mode without index means that the actual duration is not known,
2689 * we might be playing a file that's still being recorded
2690 * so, invalidate our current duration, which is only a moving target,
2691 * and should not be used to clamp anything */
2692 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
2693 seeksegment.duration = GST_CLOCK_TIME_NONE;
2694 }
2695
2696 GST_DEBUG_OBJECT (demux, "configuring seek");
2697 /* Subtract stream_start_time so we always seek on a segment
2698 * in stream time */
2699 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2700 seeksegment.start -= demux->stream_start_time;
2701 seeksegment.position -= demux->stream_start_time;
2702 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2703 seeksegment.stop -= demux->stream_start_time;
2704 else
2705 seeksegment.stop = seeksegment.duration;
2706 }
2707
2708 gst_segment_do_seek (&seeksegment, rate, format, flags,
2709 cur_type, cur, stop_type, stop, &update);
2710
2711 /* Restore the clip timestamp offset */
2712 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2713 seeksegment.position += demux->stream_start_time;
2714 seeksegment.start += demux->stream_start_time;
2715 if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2716 seeksegment.stop = seeksegment.duration;
2717 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2718 seeksegment.stop += demux->stream_start_time;
2719 }
2720
2721 /* restore segment duration (if any effect),
2722 * would be determined again when parsing, but anyway ... */
2723 seeksegment.duration = demux->common.segment.duration;
2724
2725 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2726 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2727 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
2728 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
2729
2730 /* always do full update if flushing,
2731 * otherwise problems might arise downstream with missing keyframes etc */
2732 update = update || flush;
2733
2734 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2735
2736 /* check sanity before we start flushing and all that */
2737 snap_next = after && !before;
2738 if (seeksegment.rate < 0)
2739 snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
2740 else
2741 snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
2742
2743 GST_OBJECT_LOCK (demux);
2744 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2745 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2746 seeksegment.position, &demux->seek_index, &demux->seek_entry,
2747 snap_dir)) == NULL) {
2748 /* pull mode without index can scan later on */
2749 if (demux->streaming) {
2750 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2751 GST_OBJECT_UNLOCK (demux);
2752 return FALSE;
2753 } else if (rate < 0.0) {
2754 /* FIXME: We should build an index during playback or when scanning
2755 * that can be used here. The reverse playback code requires seek_index
2756 * and seek_entry to be set!
2757 */
2758 GST_DEBUG_OBJECT (demux,
2759 "No matching seek entry in index, needed for reverse playback");
2760 GST_OBJECT_UNLOCK (demux);
2761 return FALSE;
2762 }
2763 }
2764 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2765 GST_OBJECT_UNLOCK (demux);
2766
2767 if (!update) {
2768 /* only have to update some segment,
2769 * but also still have to honour flush and so on */
2770 GST_DEBUG_OBJECT (demux, "... no update");
2771 /* bad goto, bad ... */
2772 goto next;
2773 }
2774
2775 if (demux->streaming)
2776 goto finish;
2777
2778 next:
2779 if (flush) {
2780 GstEvent *flush_event = gst_event_new_flush_start ();
2781 gst_event_set_seqnum (flush_event, seqnum);
2782 GST_DEBUG_OBJECT (demux, "Starting flush");
2783 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2784 gst_matroska_demux_send_event (demux, flush_event);
2785 } else {
2786 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2787 gst_pad_pause_task (demux->common.sinkpad);
2788 }
2789 /* ouch */
2790 if (!update) {
2791 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2792 pad_locked = TRUE;
2793 goto exit;
2794 }
2795
2796 /* now grab the stream lock so that streaming cannot continue, for
2797 * non flushing seeks when the element is in PAUSED this could block
2798 * forever. */
2799 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2800 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2801 pad_locked = TRUE;
2802
2803 /* pull mode without index can do some scanning */
2804 if (!demux->streaming && !entry) {
2805 GstEvent *flush_event;
2806
2807 /* need to stop flushing upstream as we need it next */
2808 if (flush) {
2809 flush_event = gst_event_new_flush_stop (TRUE);
2810 gst_event_set_seqnum (flush_event, seqnum);
2811 gst_pad_push_event (demux->common.sinkpad, flush_event);
2812 }
2813 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2814 /* keep local copy */
2815 if (entry) {
2816 scan_entry = *entry;
2817 g_free (entry);
2818 entry = &scan_entry;
2819 } else {
2820 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2821 if (flush) {
2822 flush_event = gst_event_new_flush_stop (TRUE);
2823 gst_event_set_seqnum (flush_event, seqnum);
2824 gst_matroska_demux_send_event (demux, flush_event);
2825 }
2826 goto seek_error;
2827 }
2828 }
2829
2830 finish:
2831 if (keyunit && seeksegment.rate > 0) {
2832 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2833 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2834 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2835 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2836 seeksegment.position = seeksegment.start;
2837 seeksegment.time = seeksegment.start - demux->stream_start_time;
2838 } else if (keyunit) {
2839 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment stop from %"
2840 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2841 GST_TIME_ARGS (seeksegment.stop), GST_TIME_ARGS (entry->time));
2842 seeksegment.stop = MAX (entry->time, demux->stream_start_time);
2843 seeksegment.position = seeksegment.stop;
2844 }
2845
2846 if (demux->streaming) {
2847 GST_OBJECT_LOCK (demux);
2848 /* track real position we should start at */
2849 GST_DEBUG_OBJECT (demux, "storing segment start");
2850 demux->requested_seek_time = seeksegment.position;
2851 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2852 GST_OBJECT_UNLOCK (demux);
2853 /* need to seek to cluster start to pick up cluster time */
2854 /* upstream takes care of flushing and all that
2855 * ... and newsegment event handling takes care of the rest */
2856 return perform_seek_to_offset (demux, rate,
2857 entry->pos + demux->common.ebml_segment_start, seqnum, flags);
2858 }
2859
2860 exit:
2861 if (flush) {
2862 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2863 gst_event_set_seqnum (flush_event, seqnum);
2864 GST_DEBUG_OBJECT (demux, "Stopping flush");
2865 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2866 gst_matroska_demux_send_event (demux, flush_event);
2867 }
2868
2869 GST_OBJECT_LOCK (demux);
2870 /* now update the real segment info */
2871 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2872 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2873 GST_OBJECT_UNLOCK (demux);
2874
2875 /* update some (segment) state */
2876 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2877 goto seek_error;
2878
2879 /* notify start of new segment */
2880 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2881 GstMessage *msg;
2882
2883 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2884 GST_FORMAT_TIME, demux->common.segment.start);
2885 gst_message_set_seqnum (msg, seqnum);
2886 gst_element_post_message (GST_ELEMENT (demux), msg);
2887 }
2888
2889 GST_OBJECT_LOCK (demux);
2890 if (demux->new_segment)
2891 gst_event_unref (demux->new_segment);
2892
2893 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2894 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2895 gst_event_set_seqnum (demux->new_segment, seqnum);
2896 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2897 demux->to_time = demux->common.segment.position;
2898 else
2899 demux->to_time = GST_CLOCK_TIME_NONE;
2900 demux->segment_seqnum = seqnum;
2901 GST_OBJECT_UNLOCK (demux);
2902
2903 /* restart our task since it might have been stopped when we did the
2904 * flush. */
2905 gst_pad_start_task (demux->common.sinkpad,
2906 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2907
2908 /* streaming can continue now */
2909 if (pad_locked) {
2910 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2911 }
2912
2913 return TRUE;
2914
2915 seek_error:
2916 {
2917 if (pad_locked) {
2918 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2919 }
2920 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2921 return FALSE;
2922 }
2923 }
2924
2925 /*
2926 * Handle whether we can perform the seek event or if we have to let the chain
2927 * function handle seeks to build the seek indexes first.
2928 */
2929 static gboolean
gst_matroska_demux_handle_seek_push(GstMatroskaDemux * demux,GstPad * pad,GstEvent * event)2930 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2931 GstEvent * event)
2932 {
2933 GstSeekFlags flags;
2934 GstSeekType cur_type, stop_type;
2935 GstFormat format;
2936 gdouble rate;
2937 gint64 cur, stop;
2938
2939 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2940 &stop_type, &stop);
2941
2942 /* sanity checks */
2943
2944 /* we can only seek on time */
2945 if (format != GST_FORMAT_TIME) {
2946 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2947 return FALSE;
2948 }
2949
2950 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2951 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2952 return FALSE;
2953 }
2954
2955 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2956 GST_DEBUG_OBJECT (demux,
2957 "Non-flushing seek not supported in streaming mode");
2958 return FALSE;
2959 }
2960
2961 if (flags & GST_SEEK_FLAG_SEGMENT) {
2962 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2963 return FALSE;
2964 }
2965
2966 /* check for having parsed index already */
2967 if (!demux->common.index_parsed) {
2968 gboolean building_index;
2969 guint64 offset = 0;
2970
2971 if (!demux->index_offset) {
2972 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2973 return FALSE;
2974 }
2975
2976 GST_OBJECT_LOCK (demux);
2977 /* handle the seek event in the chain function */
2978 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2979 /* no more seek can be issued until state reset to _DATA */
2980
2981 /* copy the event */
2982 if (demux->seek_event)
2983 gst_event_unref (demux->seek_event);
2984 demux->seek_event = gst_event_ref (event);
2985
2986 /* set the building_index flag so that only one thread can setup the
2987 * structures for index seeking. */
2988 building_index = demux->building_index;
2989 if (!building_index) {
2990 demux->building_index = TRUE;
2991 offset = demux->index_offset;
2992 }
2993 GST_OBJECT_UNLOCK (demux);
2994
2995 if (!building_index) {
2996 /* seek to the first subindex or legacy index */
2997 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2998 return perform_seek_to_offset (demux, rate, offset,
2999 gst_event_get_seqnum (event), GST_SEEK_FLAG_NONE);
3000 }
3001
3002 /* well, we are handling it already */
3003 return TRUE;
3004 }
3005
3006 /* delegate to tweaked regular seek */
3007 return gst_matroska_demux_handle_seek_event (demux, pad, event);
3008 }
3009
3010 static gboolean
gst_matroska_demux_handle_src_event(GstPad * pad,GstObject * parent,GstEvent * event)3011 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
3012 GstEvent * event)
3013 {
3014 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
3015 gboolean res = TRUE;
3016
3017 switch (GST_EVENT_TYPE (event)) {
3018 case GST_EVENT_SEEK:
3019 /* no seeking until we are (safely) ready */
3020 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
3021 GST_DEBUG_OBJECT (demux,
3022 "not ready for seeking yet, deferring seek event: %" GST_PTR_FORMAT,
3023 event);
3024 if (demux->deferred_seek_event)
3025 gst_event_unref (demux->deferred_seek_event);
3026 demux->deferred_seek_event = event;
3027 demux->deferred_seek_pad = pad;
3028 return TRUE;
3029 }
3030
3031 {
3032 guint32 seqnum = gst_event_get_seqnum (event);
3033 if (seqnum == demux->segment_seqnum) {
3034 GST_LOG_OBJECT (pad,
3035 "Drop duplicated SEEK event seqnum %" G_GUINT32_FORMAT, seqnum);
3036 gst_event_unref (event);
3037 return TRUE;
3038 }
3039 }
3040
3041 if (!demux->streaming)
3042 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
3043 else
3044 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
3045 gst_event_unref (event);
3046 break;
3047
3048 case GST_EVENT_QOS:
3049 {
3050 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
3051 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3052 GstMatroskaTrackVideoContext *videocontext =
3053 (GstMatroskaTrackVideoContext *) context;
3054 gdouble proportion;
3055 GstClockTimeDiff diff;
3056 GstClockTime timestamp;
3057
3058 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
3059
3060 GST_OBJECT_LOCK (demux);
3061 videocontext->earliest_time = timestamp + diff;
3062 GST_OBJECT_UNLOCK (demux);
3063 }
3064 res = TRUE;
3065 gst_event_unref (event);
3066 break;
3067 }
3068
3069 case GST_EVENT_TOC_SELECT:
3070 {
3071 char *uid = NULL;
3072 GstTocEntry *entry = NULL;
3073 GstEvent *seek_event;
3074 gint64 start_pos;
3075
3076 if (!demux->common.toc) {
3077 GST_DEBUG_OBJECT (demux, "no TOC to select");
3078 return FALSE;
3079 } else {
3080 gst_event_parse_toc_select (event, &uid);
3081 if (uid != NULL) {
3082 GST_OBJECT_LOCK (demux);
3083 entry = gst_toc_find_entry (demux->common.toc, uid);
3084 if (entry == NULL) {
3085 GST_OBJECT_UNLOCK (demux);
3086 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
3087 res = FALSE;
3088 } else {
3089 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
3090 GST_OBJECT_UNLOCK (demux);
3091 seek_event = gst_event_new_seek (1.0,
3092 GST_FORMAT_TIME,
3093 GST_SEEK_FLAG_FLUSH,
3094 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
3095 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
3096 gst_event_unref (seek_event);
3097 }
3098 g_free (uid);
3099 } else {
3100 GST_WARNING_OBJECT (demux, "received empty TOC select event");
3101 res = FALSE;
3102 }
3103 }
3104 gst_event_unref (event);
3105 break;
3106 }
3107
3108 /* events we don't need to handle */
3109 case GST_EVENT_NAVIGATION:
3110 gst_event_unref (event);
3111 res = FALSE;
3112 break;
3113
3114 case GST_EVENT_LATENCY:
3115 default:
3116 res = gst_pad_push_event (demux->common.sinkpad, event);
3117 break;
3118 }
3119
3120 return res;
3121 }
3122
3123 static gboolean
gst_matroska_demux_handle_sink_query(GstPad * pad,GstObject * parent,GstQuery * query)3124 gst_matroska_demux_handle_sink_query (GstPad * pad, GstObject * parent,
3125 GstQuery * query)
3126 {
3127 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
3128 gboolean res = FALSE;
3129
3130 switch (GST_QUERY_TYPE (query)) {
3131 case GST_QUERY_BITRATE:
3132 {
3133 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
3134 demux->common.offset >= demux->cached_length)) {
3135 demux->cached_length =
3136 gst_matroska_read_common_get_length (&demux->common);
3137 }
3138
3139 if (demux->cached_length < G_MAXUINT64
3140 && demux->common.segment.duration > 0) {
3141 /* TODO: better results based on ranges/index tables */
3142 guint bitrate =
3143 gst_util_uint64_scale (8 * demux->cached_length, GST_SECOND,
3144 demux->common.segment.duration);
3145
3146 GST_LOG_OBJECT (demux, "bitrate query byte length: %" G_GUINT64_FORMAT
3147 " duration %" GST_TIME_FORMAT " resulting in a bitrate of %u",
3148 demux->cached_length,
3149 GST_TIME_ARGS (demux->common.segment.duration), bitrate);
3150
3151 gst_query_set_bitrate (query, bitrate);
3152 res = TRUE;
3153 }
3154 break;
3155 }
3156 default:
3157 res = gst_pad_query_default (pad, (GstObject *) demux, query);
3158 break;
3159 }
3160
3161 return res;
3162 }
3163
3164 static GstFlowReturn
gst_matroska_demux_seek_to_previous_keyframe(GstMatroskaDemux * demux)3165 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
3166 {
3167 GstFlowReturn ret = GST_FLOW_EOS;
3168 gboolean done = TRUE;
3169 gint i;
3170
3171 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
3172 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
3173 GST_FLOW_EOS);
3174
3175 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
3176
3177 if (!demux->seek_entry) {
3178 GST_DEBUG_OBJECT (demux, "no earlier index entry");
3179 goto exit;
3180 }
3181
3182 for (i = 0; i < demux->common.src->len; i++) {
3183 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
3184
3185 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
3186 ", stream %d at %" GST_TIME_FORMAT,
3187 GST_TIME_ARGS (demux->common.segment.start), stream->index,
3188 GST_TIME_ARGS (stream->from_time));
3189 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
3190 if (stream->from_time > demux->common.segment.start) {
3191 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
3192 done = FALSE;
3193 }
3194 } else {
3195 /* nothing pushed for this stream;
3196 * likely seek entry did not start at keyframe, so all was skipped.
3197 * So we need an earlier entry */
3198 done = FALSE;
3199 }
3200 }
3201
3202 if (!done) {
3203 GstMatroskaIndex *entry;
3204
3205 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
3206 --demux->seek_entry);
3207 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
3208 goto exit;
3209
3210 ret = GST_FLOW_OK;
3211 }
3212
3213 exit:
3214 return ret;
3215 }
3216
3217 static GstFlowReturn
gst_matroska_demux_parse_tracks(GstMatroskaDemux * demux,GstEbmlRead * ebml)3218 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3219 {
3220 GstFlowReturn ret = GST_FLOW_OK;
3221 guint32 id;
3222
3223 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
3224
3225 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3226 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3227 return ret;
3228 }
3229
3230 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3231 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3232 break;
3233
3234 switch (id) {
3235 /* one track within the "all-tracks" header */
3236 case GST_MATROSKA_ID_TRACKENTRY:{
3237 GstMatroskaTrackContext *track;
3238 ret = gst_matroska_demux_parse_stream (demux, ebml, &track);
3239 if (track != NULL) {
3240 if (gst_matroska_read_common_tracknumber_unique (&demux->common,
3241 track->num)) {
3242 gst_matroska_demux_add_stream (demux, track);
3243 } else {
3244 GST_ERROR_OBJECT (demux,
3245 "TrackNumber %" G_GUINT64_FORMAT " is not unique", track->num);
3246 ret = GST_FLOW_ERROR;
3247 gst_matroska_track_free (track);
3248 track = NULL;
3249 }
3250 }
3251 break;
3252 }
3253
3254 default:
3255 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3256 "Track", id);
3257 break;
3258 }
3259 }
3260 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3261
3262 demux->tracks_parsed = TRUE;
3263 GST_DEBUG_OBJECT (demux, "signaling no more pads");
3264 gst_element_no_more_pads (GST_ELEMENT (demux));
3265
3266 return ret;
3267 }
3268
3269 static GstFlowReturn
gst_matroska_demux_update_tracks(GstMatroskaDemux * demux,GstEbmlRead * ebml)3270 gst_matroska_demux_update_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3271 {
3272 GstFlowReturn ret = GST_FLOW_OK;
3273 guint num_tracks_found = 0;
3274 guint32 id;
3275
3276 GST_INFO_OBJECT (demux, "Reparsing Tracks element");
3277
3278 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
3279
3280 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3281 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3282 return ret;
3283 }
3284
3285 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3286 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3287 break;
3288
3289 switch (id) {
3290 /* one track within the "all-tracks" header */
3291 case GST_MATROSKA_ID_TRACKENTRY:{
3292 GstMatroskaTrackContext *new_track;
3293 gint old_track_index;
3294 GstMatroskaTrackContext *old_track;
3295 ret = gst_matroska_demux_parse_stream (demux, ebml, &new_track);
3296 if (new_track == NULL)
3297 break;
3298 num_tracks_found++;
3299
3300 if (gst_matroska_read_common_tracknumber_unique (&demux->common,
3301 new_track->num)) {
3302 GST_ERROR_OBJECT (demux,
3303 "Unexpected new TrackNumber: %" G_GUINT64_FORMAT, new_track->num);
3304 goto track_mismatch_error;
3305 }
3306
3307 old_track_index =
3308 gst_matroska_read_common_stream_from_num (&demux->common,
3309 new_track->num);
3310 g_assert (old_track_index != -1);
3311 old_track = g_ptr_array_index (demux->common.src, old_track_index);
3312
3313 if (old_track->type != new_track->type) {
3314 GST_ERROR_OBJECT (demux,
3315 "Mismatch reparsing track %" G_GUINT64_FORMAT
3316 " on track type. Expected %d, found %d", new_track->num,
3317 old_track->type, new_track->type);
3318 goto track_mismatch_error;
3319 }
3320
3321 if (g_strcmp0 (old_track->codec_id, new_track->codec_id) != 0) {
3322 GST_ERROR_OBJECT (demux,
3323 "Mismatch reparsing track %" G_GUINT64_FORMAT
3324 " on codec id. Expected '%s', found '%s'", new_track->num,
3325 old_track->codec_id, new_track->codec_id);
3326 goto track_mismatch_error;
3327 }
3328
3329 /* The new track matches the old track. No problems on our side.
3330 * Let's make it replace the old track. */
3331 new_track->pad = old_track->pad;
3332 new_track->index = old_track->index;
3333 new_track->pos = old_track->pos;
3334 g_ptr_array_index (demux->common.src, old_track_index) = new_track;
3335 gst_pad_set_element_private (new_track->pad, new_track);
3336
3337 if (!gst_caps_is_equal (old_track->caps, new_track->caps)) {
3338 gst_pad_set_caps (new_track->pad, new_track->caps);
3339 }
3340 gst_caps_replace (&old_track->caps, NULL);
3341
3342 if (!gst_tag_list_is_equal (old_track->tags, new_track->tags)) {
3343 GST_DEBUG_OBJECT (old_track->pad, "Sending tags %p: %"
3344 GST_PTR_FORMAT, new_track->tags, new_track->tags);
3345 gst_pad_push_event (new_track->pad,
3346 gst_event_new_tag (gst_tag_list_copy (new_track->tags)));
3347 }
3348
3349 gst_matroska_track_free (old_track);
3350 break;
3351
3352 track_mismatch_error:
3353 gst_matroska_track_free (new_track);
3354 new_track = NULL;
3355 ret = GST_FLOW_ERROR;
3356 break;
3357 }
3358
3359 default:
3360 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3361 "Track", id);
3362 break;
3363 }
3364 }
3365 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3366
3367 if (ret != GST_FLOW_ERROR && demux->common.num_streams != num_tracks_found) {
3368 GST_ERROR_OBJECT (demux,
3369 "Mismatch on the number of tracks. Expected %du tracks, found %du",
3370 demux->common.num_streams, num_tracks_found);
3371 ret = GST_FLOW_ERROR;
3372 }
3373
3374 return ret;
3375 }
3376
3377 /*
3378 * Read signed/unsigned "EBML" numbers.
3379 * Return: number of bytes processed.
3380 */
3381
3382 static gint
gst_matroska_ebmlnum_uint(guint8 * data,guint size,guint64 * num)3383 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
3384 {
3385 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
3386 guint64 total;
3387
3388 if (size <= 0) {
3389 return -1;
3390 }
3391
3392 total = data[0];
3393 while (read <= 8 && !(total & len_mask)) {
3394 read++;
3395 len_mask >>= 1;
3396 }
3397 if (read > 8)
3398 return -1;
3399
3400 if ((total &= (len_mask - 1)) == len_mask - 1)
3401 num_ffs++;
3402 if (size < read)
3403 return -1;
3404 while (n < read) {
3405 if (data[n] == 0xff)
3406 num_ffs++;
3407 total = (total << 8) | data[n];
3408 n++;
3409 }
3410
3411 if (read == num_ffs && total != 0)
3412 *num = G_MAXUINT64;
3413 else
3414 *num = total;
3415
3416 return read;
3417 }
3418
3419 static gint
gst_matroska_ebmlnum_sint(guint8 * data,guint size,gint64 * num)3420 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
3421 {
3422 guint64 unum;
3423 gint res;
3424
3425 /* read as unsigned number first */
3426 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
3427 return -1;
3428
3429 /* make signed */
3430 if (unum == G_MAXUINT64)
3431 *num = G_MAXINT64;
3432 else
3433 *num = unum - ((1 << ((7 * res) - 1)) - 1);
3434
3435 return res;
3436 }
3437
3438 /*
3439 * Mostly used for subtitles. We add void filler data for each
3440 * lagging stream to make sure we don't deadlock.
3441 */
3442
3443 static void
gst_matroska_demux_sync_streams(GstMatroskaDemux * demux)3444 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
3445 {
3446 GstClockTime gap_threshold;
3447 gint stream_nr;
3448
3449 GST_OBJECT_LOCK (demux);
3450
3451 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
3452 GST_TIME_ARGS (demux->common.segment.position));
3453
3454 g_assert (demux->common.num_streams == demux->common.src->len);
3455 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
3456 GstMatroskaTrackContext *context;
3457
3458 context = g_ptr_array_index (demux->common.src, stream_nr);
3459
3460 GST_LOG_OBJECT (demux,
3461 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
3462 GST_TIME_ARGS (context->pos));
3463
3464 /* Only send gap events on non-subtitle streams if lagging way behind.
3465 * The 0.5 second threshold for subtitle streams is also quite random. */
3466 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
3467 gap_threshold = GST_SECOND / 2;
3468 else
3469 gap_threshold = 3 * GST_SECOND;
3470
3471 /* Lag need only be considered if we have advanced into requested segment */
3472 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
3473 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3474 demux->common.segment.position > demux->common.segment.start &&
3475 context->pos + gap_threshold < demux->common.segment.position) {
3476
3477 GstEvent *event;
3478 guint64 start = context->pos;
3479 guint64 stop = demux->common.segment.position - gap_threshold;
3480
3481 GST_DEBUG_OBJECT (demux,
3482 "Synchronizing stream %d with other by advancing time from %"
3483 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
3484 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
3485
3486 context->pos = stop;
3487
3488 event = gst_event_new_gap (start, stop - start);
3489 GST_OBJECT_UNLOCK (demux);
3490 gst_pad_push_event (context->pad, event);
3491 GST_OBJECT_LOCK (demux);
3492 }
3493 }
3494
3495 GST_OBJECT_UNLOCK (demux);
3496 }
3497
3498 static GstFlowReturn
gst_matroska_demux_push_stream_headers(GstMatroskaDemux * demux,GstMatroskaTrackContext * stream)3499 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
3500 GstMatroskaTrackContext * stream)
3501 {
3502 GstFlowReturn ret = GST_FLOW_OK;
3503 gint i, num;
3504
3505 num = gst_buffer_list_length (stream->stream_headers);
3506 for (i = 0; i < num; ++i) {
3507 GstBuffer *buf;
3508
3509 buf = gst_buffer_list_get (stream->stream_headers, i);
3510 buf = gst_buffer_copy (buf);
3511
3512 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
3513
3514 if (stream->set_discont) {
3515 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
3516 stream->set_discont = FALSE;
3517 } else {
3518 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
3519 }
3520
3521 /* push out all headers in one go and use last flow return */
3522 ret = gst_pad_push (stream->pad, buf);
3523 }
3524
3525 /* don't need these any longer */
3526 gst_buffer_list_unref (stream->stream_headers);
3527 stream->stream_headers = NULL;
3528
3529 /* combine flows */
3530 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3531
3532 return ret;
3533 }
3534
3535 static void
gst_matroska_demux_push_dvd_clut_change_event(GstMatroskaDemux * demux,GstMatroskaTrackContext * stream)3536 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
3537 GstMatroskaTrackContext * stream)
3538 {
3539 gchar *buf, *start;
3540
3541 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
3542
3543 if (!stream->codec_priv)
3544 return;
3545
3546 /* ideally, VobSub private data should be parsed and stored more convenient
3547 * elsewhere, but for now, only interested in a small part */
3548
3549 /* make sure we have terminating 0 */
3550 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
3551
3552 /* just locate and parse palette part */
3553 start = strstr (buf, "palette:");
3554 if (start) {
3555 gint i;
3556 guint32 clut[16];
3557 guint32 col;
3558 guint8 r, g, b, y, u, v;
3559
3560 start += 8;
3561 while (g_ascii_isspace (*start))
3562 start++;
3563 for (i = 0; i < 16; i++) {
3564 if (sscanf (start, "%06x", &col) != 1)
3565 break;
3566 start += 6;
3567 while ((*start == ',') || g_ascii_isspace (*start))
3568 start++;
3569 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
3570 r = (col >> 16) & 0xff;
3571 g = (col >> 8) & 0xff;
3572 b = col & 0xff;
3573 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
3574 255);
3575 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
3576 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
3577 clut[i] = (y << 16) | (u << 8) | v;
3578 }
3579
3580 /* got them all without problems; build and send event */
3581 if (i == 16) {
3582 GstStructure *s;
3583
3584 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
3585 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
3586 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
3587 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
3588 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
3589 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
3590 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
3591 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
3592 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
3593 G_TYPE_INT, clut[15], NULL);
3594
3595 gst_pad_push_event (stream->pad,
3596 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
3597 }
3598 }
3599 g_free (buf);
3600 }
3601
3602 static void
gst_matroska_demux_push_codec_data_all(GstMatroskaDemux * demux)3603 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
3604 {
3605 gint stream_nr;
3606
3607 g_assert (demux->common.num_streams == demux->common.src->len);
3608 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
3609 GstMatroskaTrackContext *stream;
3610
3611 stream = g_ptr_array_index (demux->common.src, stream_nr);
3612
3613 if (stream->send_stream_headers) {
3614 if (stream->stream_headers != NULL) {
3615 gst_matroska_demux_push_stream_headers (demux, stream);
3616 } else {
3617 /* FIXME: perhaps we can just disable and skip this stream then */
3618 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
3619 ("Failed to extract stream headers from codec private data"));
3620 }
3621 stream->send_stream_headers = FALSE;
3622 }
3623
3624 if (stream->send_dvd_event) {
3625 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
3626 /* FIXME: should we send this event again after (flushing) seek ? */
3627 stream->send_dvd_event = FALSE;
3628 }
3629 }
3630
3631 }
3632
3633 static GstFlowReturn
gst_matroska_demux_add_mpeg_seq_header(GstElement * element,GstMatroskaTrackContext * stream,GstBuffer ** buf)3634 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
3635 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3636 {
3637 guint8 *seq_header;
3638 guint seq_header_len;
3639 guint32 header, tmp;
3640
3641 if (stream->codec_state) {
3642 seq_header = stream->codec_state;
3643 seq_header_len = stream->codec_state_size;
3644 } else if (stream->codec_priv) {
3645 seq_header = stream->codec_priv;
3646 seq_header_len = stream->codec_priv_size;
3647 } else {
3648 return GST_FLOW_OK;
3649 }
3650
3651 /* Sequence header only needed for keyframes */
3652 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
3653 return GST_FLOW_OK;
3654
3655 if (gst_buffer_get_size (*buf) < 4)
3656 return GST_FLOW_OK;
3657
3658 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
3659 header = GUINT32_FROM_BE (tmp);
3660
3661 /* Sequence start code, if not found prepend */
3662 if (header != 0x000001b3) {
3663 GstBuffer *newbuf;
3664
3665 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
3666
3667 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
3668 seq_header_len);
3669
3670 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
3671 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
3672 gst_buffer_get_size (*buf));
3673
3674 gst_buffer_unref (*buf);
3675 *buf = newbuf;
3676 }
3677
3678 return GST_FLOW_OK;
3679 }
3680
3681 static GstFlowReturn
gst_matroska_demux_add_wvpk_header(GstElement * element,GstMatroskaTrackContext * stream,GstBuffer ** buf)3682 gst_matroska_demux_add_wvpk_header (GstElement * element,
3683 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3684 {
3685 GstMatroskaTrackAudioContext *audiocontext =
3686 (GstMatroskaTrackAudioContext *) stream;
3687 GstBuffer *newbuf = NULL;
3688 GstMapInfo map, outmap;
3689 guint8 *buf_data, *data;
3690 Wavpack4Header wvh;
3691
3692 wvh.ck_id[0] = 'w';
3693 wvh.ck_id[1] = 'v';
3694 wvh.ck_id[2] = 'p';
3695 wvh.ck_id[3] = 'k';
3696
3697 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
3698 wvh.track_no = 0;
3699 wvh.index_no = 0;
3700 wvh.total_samples = -1;
3701 wvh.block_index = audiocontext->wvpk_block_index;
3702
3703 if (audiocontext->channels <= 2) {
3704 guint32 block_samples, tmp;
3705 gsize size = gst_buffer_get_size (*buf);
3706
3707 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
3708 block_samples = GUINT32_FROM_LE (tmp);
3709 /* we need to reconstruct the header of the wavpack block */
3710
3711 /* -20 because ck_size is the size of the wavpack block -8
3712 * and lace_size is the size of the wavpack block + 12
3713 * (the three guint32 of the header that already are in the buffer) */
3714 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
3715
3716 /* block_samples, flags and crc are already in the buffer */
3717 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
3718
3719 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3720 data = outmap.data;
3721 data[0] = 'w';
3722 data[1] = 'v';
3723 data[2] = 'p';
3724 data[3] = 'k';
3725 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
3726 GST_WRITE_UINT16_LE (data + 8, wvh.version);
3727 GST_WRITE_UINT8 (data + 10, wvh.track_no);
3728 GST_WRITE_UINT8 (data + 11, wvh.index_no);
3729 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
3730 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
3731 gst_buffer_unmap (newbuf, &outmap);
3732
3733 /* Append data from buf: */
3734 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
3735 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
3736
3737 gst_buffer_unref (*buf);
3738 *buf = newbuf;
3739 audiocontext->wvpk_block_index += block_samples;
3740 } else {
3741 guint8 *outdata = NULL;
3742 guint outpos = 0;
3743 gsize buf_size, size, out_size = 0;
3744 guint32 block_samples, flags, crc, blocksize;
3745
3746 gst_buffer_map (*buf, &map, GST_MAP_READ);
3747 buf_data = map.data;
3748 buf_size = map.size;
3749
3750 if (buf_size < 4) {
3751 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
3752 gst_buffer_unmap (*buf, &map);
3753 return GST_FLOW_ERROR;
3754 }
3755
3756 data = buf_data;
3757 size = buf_size;
3758
3759 block_samples = GST_READ_UINT32_LE (data);
3760 data += 4;
3761 size -= 4;
3762
3763 while (size > 12) {
3764 flags = GST_READ_UINT32_LE (data);
3765 data += 4;
3766 size -= 4;
3767 crc = GST_READ_UINT32_LE (data);
3768 data += 4;
3769 size -= 4;
3770 blocksize = GST_READ_UINT32_LE (data);
3771 data += 4;
3772 size -= 4;
3773
3774 if (blocksize == 0 || size < blocksize)
3775 break;
3776
3777 g_assert ((newbuf == NULL) == (outdata == NULL));
3778
3779 if (newbuf == NULL) {
3780 out_size = sizeof (Wavpack4Header) + blocksize;
3781 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
3782
3783 gst_buffer_copy_into (newbuf, *buf,
3784 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
3785
3786 outpos = 0;
3787 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3788 outdata = outmap.data;
3789 } else {
3790 gst_buffer_unmap (newbuf, &outmap);
3791 out_size += sizeof (Wavpack4Header) + blocksize;
3792 gst_buffer_set_size (newbuf, out_size);
3793 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3794 outdata = outmap.data;
3795 }
3796
3797 outdata[outpos] = 'w';
3798 outdata[outpos + 1] = 'v';
3799 outdata[outpos + 2] = 'p';
3800 outdata[outpos + 3] = 'k';
3801 outpos += 4;
3802
3803 GST_WRITE_UINT32_LE (outdata + outpos,
3804 blocksize + sizeof (Wavpack4Header) - 8);
3805 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
3806 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
3807 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
3808 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
3809 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
3810 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
3811 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
3812 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
3813 outpos += 28;
3814
3815 memmove (outdata + outpos, data, blocksize);
3816 outpos += blocksize;
3817 data += blocksize;
3818 size -= blocksize;
3819 }
3820 gst_buffer_unmap (*buf, &map);
3821 gst_buffer_unref (*buf);
3822
3823 if (newbuf)
3824 gst_buffer_unmap (newbuf, &outmap);
3825
3826 *buf = newbuf;
3827 audiocontext->wvpk_block_index += block_samples;
3828 }
3829
3830 return GST_FLOW_OK;
3831 }
3832
3833 static GstFlowReturn
gst_matroska_demux_add_prores_header(GstElement * element,GstMatroskaTrackContext * stream,GstBuffer ** buf)3834 gst_matroska_demux_add_prores_header (GstElement * element,
3835 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3836 {
3837 GstBuffer *newbuf = gst_buffer_new_allocate (NULL, 8, NULL);
3838 GstMapInfo map;
3839 guint32 frame_size;
3840
3841 if (!gst_buffer_map (newbuf, &map, GST_MAP_WRITE)) {
3842 GST_ERROR ("Failed to map newly allocated buffer");
3843 return GST_FLOW_ERROR;
3844 }
3845
3846 frame_size = gst_buffer_get_size (*buf);
3847
3848 GST_WRITE_UINT32_BE (map.data, frame_size);
3849 map.data[4] = 'i';
3850 map.data[5] = 'c';
3851 map.data[6] = 'p';
3852 map.data[7] = 'f';
3853
3854 gst_buffer_unmap (newbuf, &map);
3855 *buf = gst_buffer_append (newbuf, *buf);
3856
3857 return GST_FLOW_OK;
3858 }
3859
3860 /* @text must be null-terminated */
3861 static gboolean
gst_matroska_demux_subtitle_chunk_has_tag(GstElement * element,const gchar * text)3862 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
3863 const gchar * text)
3864 {
3865 gchar *tag;
3866
3867 g_return_val_if_fail (text != NULL, FALSE);
3868
3869 /* yes, this might all lead to false positives ... */
3870 tag = (gchar *) text;
3871 while ((tag = strchr (tag, '<'))) {
3872 tag++;
3873 if (*tag != '\0' && *(tag + 1) == '>') {
3874 /* some common convenience ones */
3875 /* maybe any character will do here ? */
3876 switch (*tag) {
3877 case 'b':
3878 case 'i':
3879 case 'u':
3880 case 's':
3881 return TRUE;
3882 default:
3883 return FALSE;
3884 }
3885 }
3886 }
3887
3888 if (strstr (text, "<span"))
3889 return TRUE;
3890
3891 return FALSE;
3892 }
3893
3894 static GstFlowReturn
gst_matroska_demux_check_subtitle_buffer(GstElement * element,GstMatroskaTrackContext * stream,GstBuffer ** buf)3895 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
3896 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3897 {
3898 GstMatroskaTrackSubtitleContext *sub_stream;
3899 const gchar *encoding;
3900 GError *err = NULL;
3901 GstBuffer *newbuf;
3902 gchar *utf8;
3903 GstMapInfo map;
3904 gboolean needs_unmap = TRUE;
3905
3906 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3907
3908 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
3909 return GST_FLOW_OK;
3910
3911 /* The subtitle buffer we push out should not include a NUL terminator as
3912 * part of the data. */
3913 if (map.data[map.size - 1] == '\0') {
3914 gst_buffer_set_size (*buf, map.size - 1);
3915 gst_buffer_unmap (*buf, &map);
3916 gst_buffer_map (*buf, &map, GST_MAP_READ);
3917 }
3918
3919 if (!sub_stream->invalid_utf8) {
3920 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
3921 goto next;
3922 }
3923 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
3924 " is not valid UTF-8, this is broken according to the matroska"
3925 " specification", stream->num);
3926 sub_stream->invalid_utf8 = TRUE;
3927 }
3928
3929 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3930 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3931 if (encoding == NULL || *encoding == '\0') {
3932 /* if local encoding is UTF-8 and no encoding specified
3933 * via the environment variable, assume ISO-8859-15 */
3934 if (g_get_charset (&encoding)) {
3935 encoding = "ISO-8859-15";
3936 }
3937 }
3938
3939 utf8 =
3940 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3941 (char *) "*", NULL, NULL, &err);
3942
3943 if (err) {
3944 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3945 encoding, err->message);
3946 g_error_free (err);
3947 g_free (utf8);
3948
3949 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3950 encoding = "ISO-8859-15";
3951 utf8 =
3952 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3953 encoding, (char *) "*", NULL, NULL, NULL);
3954 }
3955
3956 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3957 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3958
3959 if (utf8 == NULL)
3960 utf8 = g_strdup ("invalid subtitle");
3961
3962 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3963 gst_buffer_unmap (*buf, &map);
3964 gst_buffer_copy_into (newbuf, *buf,
3965 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3966 0, -1);
3967 gst_buffer_unref (*buf);
3968
3969 *buf = newbuf;
3970 gst_buffer_map (*buf, &map, GST_MAP_READ);
3971
3972 next:
3973
3974 if (sub_stream->check_markup) {
3975 /* caps claim markup text, so we need to escape text,
3976 * except if text is already markup and then needs no further escaping */
3977 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3978 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3979
3980 if (!sub_stream->seen_markup_tag) {
3981 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3982
3983 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3984 gst_buffer_unmap (*buf, &map);
3985 gst_buffer_copy_into (newbuf, *buf,
3986 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3987 GST_BUFFER_COPY_META, 0, -1);
3988 gst_buffer_unref (*buf);
3989
3990 *buf = newbuf;
3991 needs_unmap = FALSE;
3992 }
3993 }
3994
3995 if (needs_unmap)
3996 gst_buffer_unmap (*buf, &map);
3997
3998 return GST_FLOW_OK;
3999 }
4000
4001 static GstFlowReturn
gst_matroska_demux_check_aac(GstElement * element,GstMatroskaTrackContext * stream,GstBuffer ** buf)4002 gst_matroska_demux_check_aac (GstElement * element,
4003 GstMatroskaTrackContext * stream, GstBuffer ** buf)
4004 {
4005 guint8 data[2];
4006 guint size;
4007
4008 gst_buffer_extract (*buf, 0, data, 2);
4009 size = gst_buffer_get_size (*buf);
4010
4011 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
4012 GstStructure *s;
4013
4014 /* tss, ADTS data, remove codec_data
4015 * still assume it is at least parsed */
4016 stream->caps = gst_caps_make_writable (stream->caps);
4017 s = gst_caps_get_structure (stream->caps, 0);
4018 g_assert (s);
4019 gst_structure_remove_field (s, "codec_data");
4020 gst_pad_set_caps (stream->pad, stream->caps);
4021 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
4022 "new caps: %" GST_PTR_FORMAT, stream->caps);
4023 }
4024
4025 /* disable subsequent checking */
4026 stream->postprocess_frame = NULL;
4027
4028 return GST_FLOW_OK;
4029 }
4030
4031 static GstBuffer *
gst_matroska_demux_align_buffer(GstMatroskaDemux * demux,GstBuffer * buffer,gsize alignment)4032 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
4033 GstBuffer * buffer, gsize alignment)
4034 {
4035 GstMapInfo map;
4036
4037 gst_buffer_map (buffer, &map, GST_MAP_READ);
4038
4039 if (map.size < sizeof (guintptr)) {
4040 gst_buffer_unmap (buffer, &map);
4041 return buffer;
4042 }
4043
4044 if (((guintptr) map.data) & (alignment - 1)) {
4045 GstBuffer *new_buffer;
4046 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
4047
4048 new_buffer = gst_buffer_new_allocate (NULL,
4049 gst_buffer_get_size (buffer), ¶ms);
4050
4051 /* Copy data "by hand", so ensure alignment is kept: */
4052 gst_buffer_fill (new_buffer, 0, map.data, map.size);
4053
4054 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
4055 GST_DEBUG_OBJECT (demux,
4056 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
4057 alignment);
4058
4059 gst_buffer_unmap (buffer, &map);
4060 gst_buffer_unref (buffer);
4061
4062 return new_buffer;
4063 }
4064
4065 gst_buffer_unmap (buffer, &map);
4066 return buffer;
4067 }
4068
4069 static GstFlowReturn
gst_matroska_demux_parse_blockgroup_or_simpleblock(GstMatroskaDemux * demux,GstEbmlRead * ebml,guint64 cluster_time,guint64 cluster_offset,gboolean is_simpleblock)4070 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
4071 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
4072 gboolean is_simpleblock)
4073 {
4074 GstMatroskaTrackContext *stream = NULL;
4075 GstFlowReturn ret = GST_FLOW_OK;
4076 gboolean readblock = FALSE;
4077 guint32 id;
4078 guint64 block_duration = -1;
4079 gint64 block_discardpadding = 0;
4080 GstBuffer *buf = NULL;
4081 GstMapInfo map;
4082 gint stream_num = -1, n, laces = 0;
4083 guint size = 0;
4084 gint *lace_size = NULL;
4085 gint64 time = 0;
4086 gint flags = 0;
4087 gint64 referenceblock = 0;
4088 gint64 offset;
4089 GstClockTime buffer_timestamp;
4090
4091 offset = gst_ebml_read_get_offset (ebml);
4092
4093 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4094 if (!is_simpleblock) {
4095 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
4096 goto data_error;
4097 }
4098 } else {
4099 id = GST_MATROSKA_ID_SIMPLEBLOCK;
4100 }
4101
4102 switch (id) {
4103 /* one block inside the group. Note, block parsing is one
4104 * of the harder things, so this code is a bit complicated.
4105 * See http://www.matroska.org/ for documentation. */
4106 case GST_MATROSKA_ID_SIMPLEBLOCK:
4107 case GST_MATROSKA_ID_BLOCK:
4108 {
4109 guint64 num;
4110 guint8 *data;
4111
4112 if (buf) {
4113 gst_buffer_unmap (buf, &map);
4114 gst_buffer_unref (buf);
4115 buf = NULL;
4116 }
4117 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
4118 break;
4119
4120 gst_buffer_map (buf, &map, GST_MAP_READ);
4121 data = map.data;
4122 size = map.size;
4123
4124 /* first byte(s): blocknum */
4125 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
4126 goto data_error;
4127 data += n;
4128 size -= n;
4129
4130 /* fetch stream from num */
4131 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
4132 num);
4133 if (G_UNLIKELY (size < 3)) {
4134 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
4135 /* non-fatal, try next block(group) */
4136 ret = GST_FLOW_OK;
4137 goto done;
4138 } else if (G_UNLIKELY (stream_num < 0 ||
4139 stream_num >= demux->common.num_streams)) {
4140 /* let's not give up on a stray invalid track number */
4141 GST_WARNING_OBJECT (demux,
4142 "Invalid stream %d for track number %" G_GUINT64_FORMAT
4143 "; ignoring block", stream_num, num);
4144 goto done;
4145 }
4146
4147 stream = g_ptr_array_index (demux->common.src, stream_num);
4148
4149 /* time (relative to cluster time) */
4150 time = ((gint16) GST_READ_UINT16_BE (data));
4151 data += 2;
4152 size -= 2;
4153 flags = GST_READ_UINT8 (data);
4154 data += 1;
4155 size -= 1;
4156
4157 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
4158 flags);
4159
4160 switch ((flags & 0x06) >> 1) {
4161 case 0x0: /* no lacing */
4162 laces = 1;
4163 lace_size = g_new (gint, 1);
4164 lace_size[0] = size;
4165 break;
4166
4167 case 0x1: /* xiph lacing */
4168 case 0x2: /* fixed-size lacing */
4169 case 0x3: /* EBML lacing */
4170 if (size == 0)
4171 goto invalid_lacing;
4172 laces = GST_READ_UINT8 (data) + 1;
4173 data += 1;
4174 size -= 1;
4175 lace_size = g_new0 (gint, laces);
4176
4177 switch ((flags & 0x06) >> 1) {
4178 case 0x1: /* xiph lacing */ {
4179 guint temp, total = 0;
4180
4181 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
4182 while (1) {
4183 if (size == 0)
4184 goto invalid_lacing;
4185 temp = GST_READ_UINT8 (data);
4186 lace_size[n] += temp;
4187 data += 1;
4188 size -= 1;
4189 if (temp != 0xff)
4190 break;
4191 }
4192 total += lace_size[n];
4193 }
4194 lace_size[n] = size - total;
4195 break;
4196 }
4197
4198 case 0x2: /* fixed-size lacing */
4199 for (n = 0; n < laces; n++)
4200 lace_size[n] = size / laces;
4201 break;
4202
4203 case 0x3: /* EBML lacing */ {
4204 guint total;
4205
4206 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
4207 goto data_error;
4208 data += n;
4209 size -= n;
4210 total = lace_size[0] = num;
4211 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
4212 gint64 snum;
4213 gint r;
4214
4215 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
4216 goto data_error;
4217 data += r;
4218 size -= r;
4219 lace_size[n] = lace_size[n - 1] + snum;
4220 total += lace_size[n];
4221 }
4222 if (n < laces)
4223 lace_size[n] = size - total;
4224 break;
4225 }
4226 }
4227 break;
4228 }
4229
4230 if (ret != GST_FLOW_OK)
4231 break;
4232
4233 readblock = TRUE;
4234 break;
4235 }
4236
4237 case GST_MATROSKA_ID_BLOCKDURATION:{
4238 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
4239 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
4240 block_duration);
4241 break;
4242 }
4243
4244 case GST_MATROSKA_ID_DISCARDPADDING:{
4245 ret = gst_ebml_read_sint (ebml, &id, &block_discardpadding);
4246 GST_DEBUG_OBJECT (demux, "DiscardPadding: %" GST_STIME_FORMAT,
4247 GST_STIME_ARGS (block_discardpadding));
4248 break;
4249 }
4250
4251 case GST_MATROSKA_ID_REFERENCEBLOCK:{
4252 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
4253 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
4254 referenceblock);
4255 break;
4256 }
4257
4258 case GST_MATROSKA_ID_CODECSTATE:{
4259 guint8 *data;
4260 guint64 data_len = 0;
4261
4262 if ((ret =
4263 gst_ebml_read_binary (ebml, &id, &data,
4264 &data_len)) != GST_FLOW_OK)
4265 break;
4266
4267 if (G_UNLIKELY (stream == NULL)) {
4268 GST_WARNING_OBJECT (demux,
4269 "Unexpected CodecState subelement - ignoring");
4270 break;
4271 }
4272
4273 g_free (stream->codec_state);
4274 stream->codec_state = data;
4275 stream->codec_state_size = data_len;
4276
4277 /* Decode if necessary */
4278 if (stream->encodings && stream->encodings->len > 0
4279 && stream->codec_state && stream->codec_state_size > 0) {
4280 if (!gst_matroska_decode_data (stream->encodings,
4281 &stream->codec_state, &stream->codec_state_size,
4282 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
4283 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
4284 }
4285 }
4286
4287 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
4288 stream->codec_state_size);
4289 break;
4290 }
4291
4292 default:
4293 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
4294 "BlockGroup", id);
4295 break;
4296
4297 case GST_MATROSKA_ID_BLOCKVIRTUAL:
4298 case GST_MATROSKA_ID_BLOCKADDITIONS:
4299 case GST_MATROSKA_ID_REFERENCEPRIORITY:
4300 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
4301 case GST_MATROSKA_ID_SLICES:
4302 GST_DEBUG_OBJECT (demux,
4303 "Skipping BlockGroup subelement 0x%x - ignoring", id);
4304 ret = gst_ebml_read_skip (ebml);
4305 break;
4306 }
4307
4308 if (is_simpleblock)
4309 break;
4310 }
4311
4312 /* reading a number or so could have failed */
4313 if (ret != GST_FLOW_OK)
4314 goto data_error;
4315
4316 if (ret == GST_FLOW_OK && readblock) {
4317 gboolean invisible_frame = FALSE;
4318 gboolean delta_unit = FALSE;
4319 guint64 duration = 0;
4320 gint64 lace_time = 0;
4321 GstEvent *protect_event;
4322
4323 stream = g_ptr_array_index (demux->common.src, stream_num);
4324
4325 if (cluster_time != GST_CLOCK_TIME_NONE) {
4326 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
4327 * Drop unless the lace contains timestamp 0? */
4328 if (time < 0 && (-time) > cluster_time) {
4329 lace_time = 0;
4330 } else {
4331 if (stream->timecodescale == 1.0)
4332 lace_time = (cluster_time + time) * demux->common.time_scale;
4333 else
4334 lace_time =
4335 gst_util_guint64_to_gdouble ((cluster_time + time) *
4336 demux->common.time_scale) * stream->timecodescale;
4337 }
4338 } else {
4339 lace_time = GST_CLOCK_TIME_NONE;
4340 }
4341 /* Send the GST_PROTECTION event */
4342 while ((protect_event = g_queue_pop_head (&stream->protection_event_queue))) {
4343 GST_TRACE_OBJECT (demux, "pushing protection event for stream %d:%s",
4344 stream->index, GST_STR_NULL (stream->name));
4345 gst_pad_push_event (stream->pad, protect_event);
4346 }
4347
4348 /* need to refresh segment info ASAP */
4349 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
4350 GstSegment *segment = &demux->common.segment;
4351 guint64 clace_time;
4352 GstEvent *segment_event;
4353
4354 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
4355 demux->stream_start_time = lace_time;
4356 GST_DEBUG_OBJECT (demux,
4357 "Setting stream start time to %" GST_TIME_FORMAT,
4358 GST_TIME_ARGS (lace_time));
4359 }
4360 clace_time = MAX (lace_time, demux->stream_start_time);
4361 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
4362 demux->common.segment.position != 0) {
4363 GST_DEBUG_OBJECT (demux,
4364 "using stored seek position %" GST_TIME_FORMAT,
4365 GST_TIME_ARGS (demux->common.segment.position));
4366 clace_time = demux->common.segment.position;
4367 segment->position = GST_CLOCK_TIME_NONE;
4368 }
4369 segment->start = clace_time;
4370 segment->stop = GST_CLOCK_TIME_NONE;
4371 segment->time = segment->start - demux->stream_start_time;
4372 segment->position = segment->start - demux->stream_start_time;
4373 GST_DEBUG_OBJECT (demux,
4374 "generated segment starting at %" GST_TIME_FORMAT ": %"
4375 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
4376 /* now convey our segment notion downstream */
4377 segment_event = gst_event_new_segment (segment);
4378 if (demux->segment_seqnum)
4379 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
4380 gst_matroska_demux_send_event (demux, segment_event);
4381 demux->need_segment = FALSE;
4382 demux->segment_seqnum = 0;
4383 }
4384
4385 /* send pending codec data headers for all streams,
4386 * before we perform sync across all streams */
4387 gst_matroska_demux_push_codec_data_all (demux);
4388
4389 if (block_duration != -1) {
4390 if (stream->timecodescale == 1.0)
4391 duration = gst_util_uint64_scale (block_duration,
4392 demux->common.time_scale, 1);
4393 else
4394 duration =
4395 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
4396 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
4397 1)) * stream->timecodescale);
4398 } else if (stream->default_duration) {
4399 duration = stream->default_duration * laces;
4400 }
4401 /* else duration is diff between timecode of this and next block */
4402
4403 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
4404 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
4405 a ReferenceBlock implies that this is not a keyframe. In either
4406 case, it only makes sense for video streams. */
4407 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
4408 delta_unit = TRUE;
4409 invisible_frame = ((flags & 0x08)) &&
4410 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
4411 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9) ||
4412 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_AV1));
4413 }
4414
4415 /* If we're doing a keyframe-only trickmode, only push keyframes on video
4416 * streams */
4417 if (delta_unit
4418 && demux->common.segment.
4419 flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) {
4420 GST_LOG_OBJECT (demux, "Skipping non-keyframe on stream %d",
4421 stream->index);
4422 ret = GST_FLOW_OK;
4423 goto done;
4424 }
4425 }
4426
4427 for (n = 0; n < laces; n++) {
4428 GstBuffer *sub;
4429
4430 if (G_UNLIKELY (lace_size[n] > size)) {
4431 GST_WARNING_OBJECT (demux, "Invalid lace size");
4432 break;
4433 }
4434
4435 /* QoS for video track with an index. the assumption is that
4436 index entries point to keyframes, but if that is not true we
4437 will instad skip until the next keyframe. */
4438 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
4439 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
4440 stream->index_table && demux->common.segment.rate > 0.0) {
4441 GstMatroskaTrackVideoContext *videocontext =
4442 (GstMatroskaTrackVideoContext *) stream;
4443 GstClockTime earliest_time;
4444 GstClockTime earliest_stream_time;
4445
4446 GST_OBJECT_LOCK (demux);
4447 earliest_time = videocontext->earliest_time;
4448 GST_OBJECT_UNLOCK (demux);
4449 earliest_stream_time =
4450 gst_segment_position_from_running_time (&demux->common.segment,
4451 GST_FORMAT_TIME, earliest_time);
4452
4453 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
4454 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
4455 lace_time <= earliest_stream_time) {
4456 /* find index entry (keyframe) <= earliest_stream_time */
4457 GstMatroskaIndex *entry =
4458 gst_util_array_binary_search (stream->index_table->data,
4459 stream->index_table->len, sizeof (GstMatroskaIndex),
4460 (GCompareDataFunc) gst_matroska_index_seek_find,
4461 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
4462
4463 /* if that entry (keyframe) is after the current the current
4464 buffer, we can skip pushing (and thus decoding) all
4465 buffers until that keyframe. */
4466 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
4467 entry->time > lace_time) {
4468 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
4469 stream->set_discont = TRUE;
4470 goto next_lace;
4471 }
4472 }
4473 }
4474
4475 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
4476 gst_buffer_get_size (buf) - size, lace_size[n]);
4477 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
4478
4479 if (delta_unit)
4480 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4481 else
4482 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4483
4484 if (invisible_frame)
4485 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
4486
4487 if (stream->encodings != NULL && stream->encodings->len > 0)
4488 sub = gst_matroska_decode_buffer (stream, sub);
4489
4490 if (sub == NULL) {
4491 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
4492 goto next_lace;
4493 }
4494
4495 if (!stream->dts_only) {
4496 GST_BUFFER_PTS (sub) = lace_time;
4497 } else {
4498 GST_BUFFER_DTS (sub) = lace_time;
4499 if (stream->intra_only)
4500 GST_BUFFER_PTS (sub) = lace_time;
4501 }
4502
4503 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
4504
4505 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
4506 GstClockTime last_stop_end;
4507
4508 /* Check if this stream is after segment stop */
4509 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
4510 lace_time >= demux->common.segment.stop) {
4511 GST_DEBUG_OBJECT (demux,
4512 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
4513 GST_TIME_ARGS (demux->common.segment.stop));
4514 gst_buffer_unref (sub);
4515 goto eos;
4516 }
4517 if (offset >= stream->to_offset
4518 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
4519 && lace_time > demux->to_time)) {
4520 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
4521 stream->index);
4522 gst_buffer_unref (sub);
4523 goto eos;
4524 }
4525
4526 /* handle gaps, e.g. non-zero start-time, or an cue index entry
4527 * that landed us with timestamps not quite intended */
4528 GST_OBJECT_LOCK (demux);
4529 if (demux->max_gap_time &&
4530 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
4531 demux->common.segment.rate > 0.0) {
4532 GstClockTimeDiff diff;
4533
4534 /* only send segments with increasing start times,
4535 * otherwise if these go back and forth downstream (sinks) increase
4536 * accumulated time and running_time */
4537 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
4538 if (diff > 0 && diff > demux->max_gap_time
4539 && lace_time > demux->common.segment.start
4540 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
4541 || lace_time < demux->common.segment.stop)) {
4542 GstEvent *event;
4543 GST_DEBUG_OBJECT (demux,
4544 "Gap of %" G_GINT64_FORMAT " ns detected in"
4545 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
4546 "Sending updated SEGMENT events", diff,
4547 stream->index, GST_TIME_ARGS (stream->pos),
4548 GST_TIME_ARGS (lace_time));
4549
4550 event = gst_event_new_gap (demux->last_stop_end, diff);
4551 GST_OBJECT_UNLOCK (demux);
4552 gst_pad_push_event (stream->pad, event);
4553 GST_OBJECT_LOCK (demux);
4554 }
4555 }
4556
4557 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
4558 || demux->common.segment.position < lace_time) {
4559 demux->common.segment.position = lace_time;
4560 }
4561 GST_OBJECT_UNLOCK (demux);
4562
4563 last_stop_end = lace_time;
4564 if (duration) {
4565 GST_BUFFER_DURATION (sub) = duration / laces;
4566 last_stop_end += GST_BUFFER_DURATION (sub);
4567 }
4568
4569 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
4570 demux->last_stop_end < last_stop_end)
4571 demux->last_stop_end = last_stop_end;
4572
4573 GST_OBJECT_LOCK (demux);
4574 if (demux->common.segment.duration == -1 ||
4575 demux->stream_start_time + demux->common.segment.duration <
4576 last_stop_end) {
4577 demux->common.segment.duration =
4578 last_stop_end - demux->stream_start_time;
4579 GST_OBJECT_UNLOCK (demux);
4580 if (!demux->invalid_duration) {
4581 gst_element_post_message (GST_ELEMENT_CAST (demux),
4582 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
4583 demux->invalid_duration = TRUE;
4584 }
4585 } else {
4586 GST_OBJECT_UNLOCK (demux);
4587 }
4588 }
4589
4590 stream->pos = lace_time;
4591
4592 gst_matroska_demux_sync_streams (demux);
4593
4594 if (stream->set_discont) {
4595 GST_DEBUG_OBJECT (demux, "marking DISCONT");
4596 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
4597 stream->set_discont = FALSE;
4598 } else {
4599 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
4600 }
4601
4602 /* reverse playback book-keeping */
4603 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
4604 stream->from_time = lace_time;
4605 if (stream->from_offset == -1)
4606 stream->from_offset = offset;
4607
4608 GST_DEBUG_OBJECT (demux,
4609 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
4610 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
4611 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
4612 GST_TIME_ARGS (buffer_timestamp),
4613 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
4614
4615 #if 0
4616 if (demux->common.element_index) {
4617 if (stream->index_writer_id == -1)
4618 gst_index_get_writer_id (demux->common.element_index,
4619 GST_OBJECT (stream->pad), &stream->index_writer_id);
4620
4621 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4622 G_GUINT64_FORMAT " for writer id %d",
4623 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
4624 stream->index_writer_id);
4625 gst_index_add_association (demux->common.element_index,
4626 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
4627 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
4628 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
4629 NULL);
4630 }
4631 #endif
4632
4633 /* Postprocess the buffers depending on the codec used */
4634 if (stream->postprocess_frame) {
4635 GST_LOG_OBJECT (demux, "running post process");
4636 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
4637 }
4638
4639 /* At this point, we have a sub-buffer pointing at data within a larger
4640 buffer. This data might not be aligned with anything. If the data is
4641 raw samples though, we want it aligned to the raw type (eg, 4 bytes
4642 for 32 bit samples, etc), or bad things will happen downstream as
4643 elements typically assume minimal alignment.
4644 Therefore, create an aligned copy if necessary. */
4645 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
4646
4647 if (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
4648 guint64 start_clip = 0, end_clip = 0;
4649
4650 /* Codec delay is part of the timestamps */
4651 if (GST_BUFFER_PTS_IS_VALID (sub) && stream->codec_delay) {
4652 if (GST_BUFFER_PTS (sub) > stream->codec_delay) {
4653 GST_BUFFER_PTS (sub) -= stream->codec_delay;
4654 } else {
4655 GST_BUFFER_PTS (sub) = 0;
4656
4657 /* Opus GstAudioClippingMeta units are scaled by 48000/sample_rate.
4658 That is, if a Opus track has audio encoded at 24000 Hz and 132
4659 samples need to be clipped, GstAudioClippingMeta.start will be
4660 set to 264. (This is also the case for buffer offsets.)
4661 Opus sample rates are always divisors of 48000 Hz, which is the
4662 maximum allowed sample rate. */
4663 start_clip =
4664 gst_util_uint64_scale_round (stream->codec_delay, 48000,
4665 GST_SECOND);
4666
4667 if (GST_BUFFER_DURATION_IS_VALID (sub)) {
4668 if (GST_BUFFER_DURATION (sub) > stream->codec_delay)
4669 GST_BUFFER_DURATION (sub) -= stream->codec_delay;
4670 else
4671 GST_BUFFER_DURATION (sub) = 0;
4672 }
4673 }
4674 }
4675
4676 if (block_discardpadding) {
4677 end_clip =
4678 gst_util_uint64_scale_round (block_discardpadding, 48000,
4679 GST_SECOND);
4680 }
4681
4682 if (start_clip || end_clip) {
4683 gst_buffer_add_audio_clipping_meta (sub, GST_FORMAT_DEFAULT,
4684 start_clip, end_clip);
4685 }
4686 }
4687
4688 if (GST_BUFFER_PTS_IS_VALID (sub)) {
4689 stream->pos = GST_BUFFER_PTS (sub);
4690 if (GST_BUFFER_DURATION_IS_VALID (sub))
4691 stream->pos += GST_BUFFER_DURATION (sub);
4692 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
4693 stream->pos = GST_BUFFER_DTS (sub);
4694 if (GST_BUFFER_DURATION_IS_VALID (sub))
4695 stream->pos += GST_BUFFER_DURATION (sub);
4696 }
4697
4698 ret = gst_pad_push (stream->pad, sub);
4699
4700 if (demux->common.segment.rate < 0) {
4701 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
4702 /* In reverse playback we can get a GST_FLOW_EOS when
4703 * we are at the end of the segment, so we just need to jump
4704 * back to the previous section. */
4705 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
4706 ret = GST_FLOW_OK;
4707 }
4708 }
4709 /* combine flows */
4710 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
4711 stream->pad, ret);
4712
4713 next_lace:
4714 size -= lace_size[n];
4715 if (lace_time != GST_CLOCK_TIME_NONE && duration)
4716 lace_time += duration / laces;
4717 else
4718 lace_time = GST_CLOCK_TIME_NONE;
4719 }
4720 }
4721
4722 done:
4723 if (buf) {
4724 gst_buffer_unmap (buf, &map);
4725 gst_buffer_unref (buf);
4726 }
4727 g_free (lace_size);
4728
4729 return ret;
4730
4731 /* EXITS */
4732 eos:
4733 {
4734 stream->eos = TRUE;
4735 ret = GST_FLOW_OK;
4736 /* combine flows */
4737 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
4738 ret);
4739 goto done;
4740 }
4741 invalid_lacing:
4742 {
4743 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
4744 /* non-fatal, try next block(group) */
4745 ret = GST_FLOW_OK;
4746 goto done;
4747 }
4748 data_error:
4749 {
4750 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
4751 /* non-fatal, try next block(group) */
4752 ret = GST_FLOW_OK;
4753 goto done;
4754 }
4755 }
4756
4757 /* return FALSE if block(group) should be skipped (due to a seek) */
4758 static inline gboolean
gst_matroska_demux_seek_block(GstMatroskaDemux * demux)4759 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
4760 {
4761 if (G_UNLIKELY (demux->seek_block)) {
4762 if (!(--demux->seek_block)) {
4763 return TRUE;
4764 } else {
4765 GST_LOG_OBJECT (demux, "should skip block due to seek");
4766 return FALSE;
4767 }
4768 } else {
4769 return TRUE;
4770 }
4771 }
4772
4773 static GstFlowReturn
gst_matroska_demux_parse_contents_seekentry(GstMatroskaDemux * demux,GstEbmlRead * ebml)4774 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
4775 GstEbmlRead * ebml)
4776 {
4777 GstFlowReturn ret;
4778 guint64 seek_pos = (guint64) - 1;
4779 guint32 seek_id = 0;
4780 guint32 id;
4781
4782 DEBUG_ELEMENT_START (demux, ebml, "Seek");
4783
4784 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4785 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4786 return ret;
4787 }
4788
4789 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4790 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4791 break;
4792
4793 switch (id) {
4794 case GST_MATROSKA_ID_SEEKID:
4795 {
4796 guint64 t;
4797
4798 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4799 break;
4800
4801 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
4802 seek_id = t;
4803 break;
4804 }
4805
4806 case GST_MATROSKA_ID_SEEKPOSITION:
4807 {
4808 guint64 t;
4809
4810 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4811 break;
4812
4813 if (t > G_MAXINT64) {
4814 GST_WARNING_OBJECT (demux,
4815 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
4816 break;
4817 }
4818
4819 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
4820 seek_pos = t;
4821 break;
4822 }
4823
4824 default:
4825 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
4826 "SeekHead", id);
4827 break;
4828 }
4829 }
4830
4831 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
4832 return ret;
4833
4834 if (!seek_id || seek_pos == (guint64) - 1) {
4835 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
4836 G_GUINT64_FORMAT ")", seek_id, seek_pos);
4837 return GST_FLOW_OK;
4838 }
4839
4840 switch (seek_id) {
4841 case GST_MATROSKA_ID_SEEKHEAD:
4842 {
4843 }
4844 case GST_MATROSKA_ID_CUES:
4845 case GST_MATROSKA_ID_TAGS:
4846 case GST_MATROSKA_ID_TRACKS:
4847 case GST_MATROSKA_ID_SEGMENTINFO:
4848 case GST_MATROSKA_ID_ATTACHMENTS:
4849 case GST_MATROSKA_ID_CHAPTERS:
4850 {
4851 guint64 before_pos, length;
4852 guint needed;
4853
4854 /* remember */
4855 length = gst_matroska_read_common_get_length (&demux->common);
4856 before_pos = demux->common.offset;
4857
4858 if (length == (guint64) - 1) {
4859 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
4860 break;
4861 }
4862
4863 /* check for validity */
4864 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
4865 GST_WARNING_OBJECT (demux,
4866 "SeekHead reference lies outside file!" " (%"
4867 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
4868 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
4869 length);
4870 break;
4871 }
4872
4873 /* only pick up index location when streaming */
4874 if (demux->streaming) {
4875 if (seek_id == GST_MATROSKA_ID_CUES) {
4876 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
4877 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
4878 demux->index_offset);
4879 }
4880 break;
4881 }
4882
4883 /* seek */
4884 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
4885
4886 /* check ID */
4887 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4888 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
4889 GST_FLOW_OK)
4890 goto finish;
4891
4892 if (id != seek_id) {
4893 GST_WARNING_OBJECT (demux,
4894 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
4895 seek_id, id, seek_pos + demux->common.ebml_segment_start);
4896 } else {
4897 /* now parse */
4898 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4899 }
4900
4901 finish:
4902 /* seek back */
4903 demux->common.offset = before_pos;
4904 break;
4905 }
4906
4907 case GST_MATROSKA_ID_CLUSTER:
4908 {
4909 guint64 pos = seek_pos + demux->common.ebml_segment_start;
4910
4911 GST_LOG_OBJECT (demux, "Cluster position");
4912 if (G_UNLIKELY (!demux->clusters))
4913 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
4914 g_array_append_val (demux->clusters, pos);
4915 break;
4916 }
4917
4918 default:
4919 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
4920 break;
4921 }
4922 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4923
4924 return ret;
4925 }
4926
4927 static GstFlowReturn
gst_matroska_demux_parse_contents(GstMatroskaDemux * demux,GstEbmlRead * ebml)4928 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4929 {
4930 GstFlowReturn ret = GST_FLOW_OK;
4931 guint32 id;
4932
4933 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4934
4935 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4936 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4937 return ret;
4938 }
4939
4940 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4941 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4942 break;
4943
4944 switch (id) {
4945 case GST_MATROSKA_ID_SEEKENTRY:
4946 {
4947 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
4948 /* Ignore EOS and errors here */
4949 if (ret != GST_FLOW_OK) {
4950 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4951 ret = GST_FLOW_OK;
4952 }
4953 break;
4954 }
4955
4956 default:
4957 ret = gst_matroska_read_common_parse_skip (&demux->common,
4958 ebml, "SeekHead", id);
4959 break;
4960 }
4961 }
4962
4963 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4964
4965 /* Sort clusters by position for easier searching */
4966 if (demux->clusters)
4967 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4968
4969 return ret;
4970 }
4971
4972 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
4973
4974 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4975
4976 static inline GstFlowReturn
gst_matroska_demux_check_read_size(GstMatroskaDemux * demux,guint64 bytes)4977 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4978 {
4979 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4980 /* only a few blocks are expected/allowed to be large,
4981 * and will be recursed into, whereas others will be read and must fit */
4982 if (demux->streaming) {
4983 /* fatal in streaming case, as we can't step over easily */
4984 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4985 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4986 "file might be corrupt.", bytes));
4987 return GST_FLOW_ERROR;
4988 } else {
4989 /* indicate higher level to quietly give up */
4990 GST_DEBUG_OBJECT (demux,
4991 "too large block of size %" G_GUINT64_FORMAT, bytes);
4992 return GST_FLOW_ERROR;
4993 }
4994 } else {
4995 return GST_FLOW_OK;
4996 }
4997 }
4998
4999 /* returns TRUE if we truely are in error state, and should give up */
5000 static inline GstFlowReturn
gst_matroska_demux_check_parse_error(GstMatroskaDemux * demux)5001 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
5002 {
5003 if (!demux->streaming && demux->next_cluster_offset > 0) {
5004 /* just repositioning to where next cluster should be and try from there */
5005 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
5006 G_GUINT64_FORMAT, demux->next_cluster_offset);
5007 demux->common.offset = demux->next_cluster_offset;
5008 demux->next_cluster_offset = 0;
5009 return GST_FLOW_OK;
5010 } else {
5011 gint64 pos;
5012 GstFlowReturn ret;
5013
5014 /* sigh, one last attempt above and beyond call of duty ...;
5015 * search for cluster mark following current pos */
5016 pos = demux->common.offset;
5017 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
5018 if ((ret = gst_matroska_demux_search_cluster (demux, &pos, TRUE)) !=
5019 GST_FLOW_OK) {
5020 /* did not work, give up */
5021 return ret;
5022 } else {
5023 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
5024 /* try that position */
5025 demux->common.offset = pos;
5026 return GST_FLOW_OK;
5027 }
5028 }
5029 }
5030
5031 static inline GstFlowReturn
gst_matroska_demux_flush(GstMatroskaDemux * demux,guint flush)5032 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
5033 {
5034 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
5035 demux->common.offset += flush;
5036 if (demux->streaming) {
5037 GstFlowReturn ret;
5038
5039 /* hard to skip large blocks when streaming */
5040 ret = gst_matroska_demux_check_read_size (demux, flush);
5041 if (ret != GST_FLOW_OK)
5042 return ret;
5043 if (flush <= gst_adapter_available (demux->common.adapter))
5044 gst_adapter_flush (demux->common.adapter, flush);
5045 else
5046 return GST_FLOW_EOS;
5047 }
5048 return GST_FLOW_OK;
5049 }
5050
5051 /* initializes @ebml with @bytes from input stream at current offset.
5052 * Returns EOS if insufficient available,
5053 * ERROR if too much was attempted to read. */
5054 static inline GstFlowReturn
gst_matroska_demux_take(GstMatroskaDemux * demux,guint64 bytes,GstEbmlRead * ebml)5055 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
5056 GstEbmlRead * ebml)
5057 {
5058 GstBuffer *buffer = NULL;
5059 GstFlowReturn ret = GST_FLOW_OK;
5060
5061 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
5062 bytes);
5063 ret = gst_matroska_demux_check_read_size (demux, bytes);
5064 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
5065 if (!demux->streaming) {
5066 /* in pull mode, we can skip */
5067 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
5068 ret = GST_FLOW_OVERFLOW;
5069 } else {
5070 /* otherwise fatal */
5071 ret = GST_FLOW_ERROR;
5072 }
5073 goto exit;
5074 }
5075 if (demux->streaming) {
5076 if (gst_adapter_available (demux->common.adapter) >= bytes)
5077 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
5078 else
5079 ret = GST_FLOW_EOS;
5080 } else
5081 ret = gst_matroska_read_common_peek_bytes (&demux->common,
5082 demux->common.offset, bytes, &buffer, NULL);
5083 if (G_LIKELY (buffer)) {
5084 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
5085 demux->common.offset);
5086 demux->common.offset += bytes;
5087 }
5088 exit:
5089 return ret;
5090 }
5091
5092 static void
gst_matroska_demux_check_seekability(GstMatroskaDemux * demux)5093 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
5094 {
5095 GstQuery *query;
5096 gboolean seekable = FALSE;
5097 gint64 start = -1, stop = -1;
5098
5099 query = gst_query_new_seeking (GST_FORMAT_BYTES);
5100 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
5101 GST_DEBUG_OBJECT (demux, "seeking query failed");
5102 goto done;
5103 }
5104
5105 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
5106
5107 /* try harder to query upstream size if we didn't get it the first time */
5108 if (seekable && stop == -1) {
5109 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
5110 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
5111 &stop);
5112 }
5113
5114 /* if upstream doesn't know the size, it's likely that it's not seekable in
5115 * practice even if it technically may be seekable */
5116 if (seekable && (start != 0 || stop <= start)) {
5117 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
5118 seekable = FALSE;
5119 }
5120
5121 done:
5122 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
5123 G_GUINT64_FORMAT ")", seekable, start, stop);
5124 demux->seekable = seekable;
5125
5126 gst_query_unref (query);
5127 }
5128
5129 static GstFlowReturn
gst_matroska_demux_find_tracks(GstMatroskaDemux * demux)5130 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
5131 {
5132 guint32 id;
5133 guint64 before_pos;
5134 guint64 length;
5135 guint needed;
5136 GstFlowReturn ret = GST_FLOW_OK;
5137
5138 GST_WARNING_OBJECT (demux,
5139 "Found Cluster element before Tracks, searching Tracks");
5140
5141 /* remember */
5142 before_pos = demux->common.offset;
5143
5144 /* Search Tracks element */
5145 while (TRUE) {
5146 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
5147 GST_ELEMENT_CAST (demux), &id, &length, &needed);
5148 if (ret != GST_FLOW_OK)
5149 break;
5150
5151 if (id != GST_MATROSKA_ID_TRACKS) {
5152 /* we may be skipping large cluster here, so forego size check etc */
5153 /* ... but we can't skip undefined size; force error */
5154 if (length == G_MAXUINT64) {
5155 ret = gst_matroska_demux_check_read_size (demux, length);
5156 break;
5157 } else {
5158 demux->common.offset += needed;
5159 demux->common.offset += length;
5160 }
5161 continue;
5162 }
5163
5164 /* will lead to track parsing ... */
5165 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5166 break;
5167 }
5168
5169 /* seek back */
5170 demux->common.offset = before_pos;
5171
5172 return ret;
5173 }
5174
5175 #define GST_READ_CHECK(stmt) \
5176 G_STMT_START { \
5177 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
5178 if (ret == GST_FLOW_OVERFLOW) { \
5179 ret = GST_FLOW_OK; \
5180 } \
5181 goto read_error; \
5182 } \
5183 } G_STMT_END
5184
5185 static GstFlowReturn
gst_matroska_demux_parse_id(GstMatroskaDemux * demux,guint32 id,guint64 length,guint needed)5186 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
5187 guint64 length, guint needed)
5188 {
5189 GstEbmlRead ebml = { 0, };
5190 GstFlowReturn ret = GST_FLOW_OK;
5191 guint64 read;
5192
5193 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
5194 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
5195
5196 /* if we plan to read and parse this element, we need prefix (id + length)
5197 * and the contents */
5198 /* mind about overflow wrap-around when dealing with undefined size */
5199 read = length;
5200 if (G_LIKELY (length != G_MAXUINT64))
5201 read += needed;
5202
5203 switch (demux->common.state) {
5204 case GST_MATROSKA_READ_STATE_START:
5205 switch (id) {
5206 case GST_EBML_ID_HEADER:
5207 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5208 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
5209 if (ret != GST_FLOW_OK)
5210 goto parse_failed;
5211 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
5212 gst_matroska_demux_check_seekability (demux);
5213 break;
5214 default:
5215 goto invalid_header;
5216 break;
5217 }
5218 break;
5219 case GST_MATROSKA_READ_STATE_SEGMENT:
5220 switch (id) {
5221 case GST_MATROSKA_ID_SEGMENT:
5222 /* eat segment prefix */
5223 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
5224 GST_DEBUG_OBJECT (demux,
5225 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
5226 G_GUINT64_FORMAT, demux->common.offset, length);
5227 /* seeks are from the beginning of the segment,
5228 * after the segment ID/length */
5229 demux->common.ebml_segment_start = demux->common.offset;
5230 if (length == 0)
5231 length = G_MAXUINT64;
5232 demux->common.ebml_segment_length = length;
5233 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
5234 break;
5235 default:
5236 GST_WARNING_OBJECT (demux,
5237 "Expected a Segment ID (0x%x), but received 0x%x!",
5238 GST_MATROSKA_ID_SEGMENT, id);
5239 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5240 break;
5241 }
5242 break;
5243 case GST_MATROSKA_READ_STATE_SCANNING:
5244 if (id != GST_MATROSKA_ID_CLUSTER &&
5245 id != GST_MATROSKA_ID_PREVSIZE &&
5246 id != GST_MATROSKA_ID_CLUSTERTIMECODE) {
5247 if (demux->common.start_resync_offset != -1) {
5248 /* we need to skip byte per byte if we are scanning for a new cluster
5249 * after invalid data is found
5250 */
5251 read = 1;
5252 }
5253 goto skip;
5254 } else {
5255 if (demux->common.start_resync_offset != -1) {
5256 GST_LOG_OBJECT (demux, "Resync done, new cluster found!");
5257 demux->common.start_resync_offset = -1;
5258 demux->common.state = demux->common.state_to_restore;
5259 }
5260 }
5261 /* fall-through */
5262 case GST_MATROSKA_READ_STATE_HEADER:
5263 case GST_MATROSKA_READ_STATE_DATA:
5264 case GST_MATROSKA_READ_STATE_SEEK:
5265 switch (id) {
5266 case GST_EBML_ID_HEADER:
5267 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5268 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
5269 gst_matroska_demux_check_seekability (demux);
5270 break;
5271 case GST_MATROSKA_ID_SEGMENTINFO:
5272 if (!demux->common.segmentinfo_parsed) {
5273 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5274 ret = gst_matroska_read_common_parse_info (&demux->common,
5275 GST_ELEMENT_CAST (demux), &ebml);
5276 if (ret == GST_FLOW_OK)
5277 gst_matroska_demux_send_tags (demux);
5278 } else {
5279 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5280 }
5281 break;
5282 case GST_MATROSKA_ID_TRACKS:
5283 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5284 if (!demux->tracks_parsed) {
5285 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
5286 } else {
5287 ret = gst_matroska_demux_update_tracks (demux, &ebml);
5288 }
5289 break;
5290 case GST_MATROSKA_ID_CLUSTER:
5291 if (G_UNLIKELY (!demux->tracks_parsed)) {
5292 if (demux->streaming) {
5293 GST_DEBUG_OBJECT (demux, "Cluster before Track");
5294 goto not_streamable;
5295 } else {
5296 ret = gst_matroska_demux_find_tracks (demux);
5297 if (!demux->tracks_parsed)
5298 goto no_tracks;
5299 }
5300 }
5301 if (demux->common.state == GST_MATROSKA_READ_STATE_HEADER) {
5302 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
5303 demux->first_cluster_offset = demux->common.offset;
5304
5305 if (!demux->streaming &&
5306 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.duration)) {
5307 GstMatroskaIndex *last = NULL;
5308
5309 GST_DEBUG_OBJECT (demux,
5310 "estimating duration using last cluster");
5311 if ((last = gst_matroska_demux_search_pos (demux,
5312 GST_CLOCK_TIME_NONE)) != NULL) {
5313 demux->last_cluster_offset =
5314 last->pos + demux->common.ebml_segment_start;
5315 demux->stream_last_time = last->time;
5316 demux->common.segment.duration =
5317 demux->stream_last_time - demux->stream_start_time;
5318 /* above estimate should not be taken all too strongly */
5319 demux->invalid_duration = TRUE;
5320 GST_DEBUG_OBJECT (demux,
5321 "estimated duration as %" GST_TIME_FORMAT,
5322 GST_TIME_ARGS (demux->common.segment.duration));
5323
5324 g_free (last);
5325 }
5326 }
5327
5328 /* Peek at second cluster in order to figure out if we have cluster
5329 * prev_size or not (which is never set on the first cluster for
5330 * obvious reasons). This is useful in case someone initiates a
5331 * seek or direction change before we reach the second cluster. */
5332 if (!demux->streaming) {
5333 ClusterInfo cluster = { 0, };
5334
5335 if (gst_matroska_demux_peek_cluster_info (demux, &cluster,
5336 demux->first_cluster_offset) && cluster.size > 0) {
5337 gst_matroska_demux_peek_cluster_info (demux, &cluster,
5338 demux->first_cluster_offset + cluster.size);
5339 }
5340 demux->common.offset = demux->first_cluster_offset;
5341 }
5342
5343 if (demux->deferred_seek_event) {
5344 GstEvent *seek_event;
5345 GstPad *seek_pad;
5346 seek_event = demux->deferred_seek_event;
5347 seek_pad = demux->deferred_seek_pad;
5348 demux->deferred_seek_event = NULL;
5349 demux->deferred_seek_pad = NULL;
5350 GST_DEBUG_OBJECT (demux,
5351 "Handling deferred seek event: %" GST_PTR_FORMAT, seek_event);
5352 gst_matroska_demux_handle_seek_event (demux, seek_pad,
5353 seek_event);
5354 gst_event_unref (seek_event);
5355 }
5356
5357 /* send initial segment - we wait till we know the first
5358 incoming timestamp, so we can properly set the start of
5359 the segment. */
5360 demux->need_segment = TRUE;
5361 }
5362 demux->cluster_time = GST_CLOCK_TIME_NONE;
5363 demux->cluster_offset = demux->common.offset;
5364 demux->cluster_prevsize = 0;
5365 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
5366 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
5367 " not found in Cluster, trying next Cluster's first block instead",
5368 demux->seek_block);
5369 demux->seek_block = 0;
5370 }
5371 demux->seek_first = FALSE;
5372 /* record next cluster for recovery */
5373 if (read != G_MAXUINT64)
5374 demux->next_cluster_offset = demux->cluster_offset + read;
5375 /* eat cluster prefix */
5376 gst_matroska_demux_flush (demux, needed);
5377 break;
5378 case GST_MATROSKA_ID_CLUSTERTIMECODE:
5379 {
5380 guint64 num;
5381
5382 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5383 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
5384 goto parse_failed;
5385 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
5386 demux->cluster_time = num;
5387 /* track last cluster */
5388 if (demux->cluster_offset > demux->last_cluster_offset) {
5389 demux->last_cluster_offset = demux->cluster_offset;
5390 demux->stream_last_time =
5391 demux->cluster_time * demux->common.time_scale;
5392 }
5393 #if 0
5394 if (demux->common.element_index) {
5395 if (demux->common.element_index_writer_id == -1)
5396 gst_index_get_writer_id (demux->common.element_index,
5397 GST_OBJECT (demux), &demux->common.element_index_writer_id);
5398 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
5399 G_GUINT64_FORMAT " for writer id %d",
5400 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
5401 demux->common.element_index_writer_id);
5402 gst_index_add_association (demux->common.element_index,
5403 demux->common.element_index_writer_id,
5404 GST_ASSOCIATION_FLAG_KEY_UNIT,
5405 GST_FORMAT_TIME, demux->cluster_time,
5406 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
5407 }
5408 #endif
5409 break;
5410 }
5411 case GST_MATROSKA_ID_BLOCKGROUP:
5412 if (!gst_matroska_demux_seek_block (demux))
5413 goto skip;
5414 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5415 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
5416 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
5417 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
5418 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
5419 }
5420 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
5421 break;
5422 case GST_MATROSKA_ID_SIMPLEBLOCK:
5423 if (!gst_matroska_demux_seek_block (demux))
5424 goto skip;
5425 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5426 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
5427 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
5428 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
5429 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
5430 break;
5431 case GST_MATROSKA_ID_ATTACHMENTS:
5432 if (!demux->common.attachments_parsed) {
5433 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5434 ret = gst_matroska_read_common_parse_attachments (&demux->common,
5435 GST_ELEMENT_CAST (demux), &ebml);
5436 if (ret == GST_FLOW_OK)
5437 gst_matroska_demux_send_tags (demux);
5438 } else {
5439 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5440 }
5441 break;
5442 case GST_MATROSKA_ID_TAGS:
5443 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5444 ret = gst_matroska_read_common_parse_metadata (&demux->common,
5445 GST_ELEMENT_CAST (demux), &ebml);
5446 if (ret == GST_FLOW_OK)
5447 gst_matroska_demux_send_tags (demux);
5448 break;
5449 case GST_MATROSKA_ID_CHAPTERS:
5450 if (!demux->common.chapters_parsed) {
5451 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5452 ret =
5453 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
5454
5455 if (demux->common.toc) {
5456 gst_matroska_demux_send_event (demux,
5457 gst_event_new_toc (demux->common.toc, FALSE));
5458 }
5459 } else
5460 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5461 break;
5462 case GST_MATROSKA_ID_SEEKHEAD:
5463 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5464 ret = gst_matroska_demux_parse_contents (demux, &ebml);
5465 break;
5466 case GST_MATROSKA_ID_CUES:
5467 if (demux->common.index_parsed) {
5468 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5469 break;
5470 }
5471 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5472 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
5473 /* only push based; delayed index building */
5474 if (ret == GST_FLOW_OK
5475 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
5476 GstEvent *event;
5477
5478 GST_OBJECT_LOCK (demux);
5479 event = demux->seek_event;
5480 demux->seek_event = NULL;
5481 GST_OBJECT_UNLOCK (demux);
5482
5483 g_assert (event);
5484 /* unlikely to fail, since we managed to seek to this point */
5485 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
5486 gst_event_unref (event);
5487 goto seek_failed;
5488 }
5489 gst_event_unref (event);
5490 /* resume data handling, main thread clear to seek again */
5491 GST_OBJECT_LOCK (demux);
5492 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
5493 GST_OBJECT_UNLOCK (demux);
5494 }
5495 break;
5496 case GST_MATROSKA_ID_PREVSIZE:{
5497 guint64 num;
5498
5499 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5500 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
5501 goto parse_failed;
5502 GST_LOG_OBJECT (demux, "ClusterPrevSize: %" G_GUINT64_FORMAT, num);
5503 demux->cluster_prevsize = num;
5504 demux->seen_cluster_prevsize = TRUE;
5505 break;
5506 }
5507 case GST_MATROSKA_ID_POSITION:
5508 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
5509 /* The WebM doesn't support the EncryptedBlock element.
5510 * The Matroska spec doesn't give us more detail, how to parse this element,
5511 * for example the field TransformID isn't specified yet.*/
5512 case GST_MATROSKA_ID_SILENTTRACKS:
5513 GST_DEBUG_OBJECT (demux,
5514 "Skipping Cluster subelement 0x%x - ignoring", id);
5515 /* fall-through */
5516 default:
5517 skip:
5518 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
5519 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5520 break;
5521 }
5522 break;
5523 }
5524
5525 if (ret == GST_FLOW_PARSE)
5526 goto parse_failed;
5527
5528 exit:
5529 gst_ebml_read_clear (&ebml);
5530 return ret;
5531
5532 /* ERRORS */
5533 read_error:
5534 {
5535 /* simply exit, maybe not enough data yet */
5536 /* no ebml to clear if read error */
5537 return ret;
5538 }
5539 parse_failed:
5540 {
5541 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5542 ("Failed to parse Element 0x%x", id));
5543 ret = GST_FLOW_ERROR;
5544 goto exit;
5545 }
5546 not_streamable:
5547 {
5548 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5549 ("File layout does not permit streaming"));
5550 ret = GST_FLOW_ERROR;
5551 goto exit;
5552 }
5553 no_tracks:
5554 {
5555 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5556 ("No Tracks element found"));
5557 ret = GST_FLOW_ERROR;
5558 goto exit;
5559 }
5560 invalid_header:
5561 {
5562 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
5563 ret = GST_FLOW_ERROR;
5564 goto exit;
5565 }
5566 seek_failed:
5567 {
5568 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
5569 ret = GST_FLOW_ERROR;
5570 goto exit;
5571 }
5572 }
5573
5574 static void
gst_matroska_demux_loop(GstPad * pad)5575 gst_matroska_demux_loop (GstPad * pad)
5576 {
5577 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
5578 GstFlowReturn ret;
5579 guint32 id;
5580 guint64 length;
5581 guint needed;
5582
5583 /* If we have to close a segment, send a new segment to do this now */
5584 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
5585 if (G_UNLIKELY (demux->new_segment)) {
5586 gst_matroska_demux_send_event (demux, demux->new_segment);
5587 demux->new_segment = NULL;
5588 }
5589 }
5590
5591 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
5592 GST_ELEMENT_CAST (demux), &id, &length, &needed);
5593 if (ret == GST_FLOW_EOS) {
5594 goto eos;
5595 } else if (ret == GST_FLOW_FLUSHING) {
5596 goto pause;
5597 } else if (ret != GST_FLOW_OK) {
5598 ret = gst_matroska_demux_check_parse_error (demux);
5599
5600 /* Only handle EOS as no error if we're outside the segment already */
5601 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
5602 && demux->common.offset >=
5603 demux->common.ebml_segment_start +
5604 demux->common.ebml_segment_length))
5605 goto eos;
5606 else if (ret != GST_FLOW_OK)
5607 goto pause;
5608 else
5609 return;
5610 }
5611
5612 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
5613 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
5614 length, needed);
5615
5616 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5617 if (ret == GST_FLOW_EOS)
5618 goto eos;
5619 if (ret != GST_FLOW_OK)
5620 goto pause;
5621
5622 /* check if we're at the end of a configured segment */
5623 if (G_LIKELY (demux->common.src->len)) {
5624 guint i;
5625
5626 g_assert (demux->common.num_streams == demux->common.src->len);
5627 for (i = 0; i < demux->common.src->len; i++) {
5628 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
5629 i);
5630 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
5631 GST_TIME_ARGS (context->pos));
5632 if (context->eos == FALSE)
5633 goto next;
5634 }
5635
5636 GST_INFO_OBJECT (demux, "All streams are EOS");
5637 ret = GST_FLOW_EOS;
5638 goto eos;
5639 }
5640
5641 next:
5642 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
5643 demux->common.offset >= demux->cached_length)) {
5644 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
5645 if (demux->common.offset == demux->cached_length) {
5646 GST_LOG_OBJECT (demux, "Reached end of stream");
5647 ret = GST_FLOW_EOS;
5648 goto eos;
5649 }
5650 }
5651
5652 return;
5653
5654 /* ERRORS */
5655 eos:
5656 {
5657 if (demux->common.segment.rate < 0.0) {
5658 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
5659 if (ret == GST_FLOW_OK)
5660 return;
5661 }
5662 /* fall-through */
5663 }
5664 pause:
5665 {
5666 const gchar *reason = gst_flow_get_name (ret);
5667 gboolean push_eos = FALSE;
5668
5669 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
5670 gst_pad_pause_task (demux->common.sinkpad);
5671
5672 if (ret == GST_FLOW_EOS) {
5673 /* perform EOS logic */
5674
5675 /* If we were in the headers, make sure we send no-more-pads.
5676 This will ensure decodebin does not get stuck thinking
5677 the chain is not complete yet, and waiting indefinitely. */
5678 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
5679 if (demux->common.src->len == 0) {
5680 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
5681 ("No pads created"));
5682 } else {
5683 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
5684 ("Failed to finish reading headers"));
5685 }
5686 gst_element_no_more_pads (GST_ELEMENT (demux));
5687 }
5688
5689 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
5690 GstEvent *event;
5691 GstMessage *msg;
5692 gint64 stop;
5693
5694 /* for segment playback we need to post when (in stream time)
5695 * we stopped, this is either stop (when set) or the duration. */
5696 if ((stop = demux->common.segment.stop) == -1)
5697 stop = demux->last_stop_end;
5698
5699 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
5700 msg = gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
5701 stop);
5702 if (demux->segment_seqnum)
5703 gst_message_set_seqnum (msg, demux->segment_seqnum);
5704 gst_element_post_message (GST_ELEMENT (demux), msg);
5705
5706 event = gst_event_new_segment_done (GST_FORMAT_TIME, stop);
5707 if (demux->segment_seqnum)
5708 gst_event_set_seqnum (event, demux->segment_seqnum);
5709 gst_matroska_demux_send_event (demux, event);
5710 } else {
5711 push_eos = TRUE;
5712 }
5713 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
5714 /* for fatal errors we post an error message */
5715 GST_ELEMENT_FLOW_ERROR (demux, ret);
5716 push_eos = TRUE;
5717 }
5718 if (push_eos) {
5719 GstEvent *event;
5720
5721 /* send EOS, and prevent hanging if no streams yet */
5722 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
5723 event = gst_event_new_eos ();
5724 if (demux->segment_seqnum)
5725 gst_event_set_seqnum (event, demux->segment_seqnum);
5726 if (!gst_matroska_demux_send_event (demux, event) &&
5727 (ret == GST_FLOW_EOS)) {
5728 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5729 (NULL), ("got eos but no streams (yet)"));
5730 }
5731 }
5732 return;
5733 }
5734 }
5735
5736 /*
5737 * Create and push a flushing seek event upstream
5738 */
5739 static gboolean
perform_seek_to_offset(GstMatroskaDemux * demux,gdouble rate,guint64 offset,guint32 seqnum,GstSeekFlags flags)5740 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
5741 guint32 seqnum, GstSeekFlags flags)
5742 {
5743 GstEvent *event;
5744 gboolean res = 0;
5745
5746 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
5747
5748 event =
5749 gst_event_new_seek (rate, GST_FORMAT_BYTES,
5750 flags | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
5751 GST_SEEK_TYPE_SET, offset, GST_SEEK_TYPE_NONE, -1);
5752 gst_event_set_seqnum (event, seqnum);
5753
5754 res = gst_pad_push_event (demux->common.sinkpad, event);
5755
5756 /* segment event will update offset */
5757 return res;
5758 }
5759
5760 static GstFlowReturn
gst_matroska_demux_chain(GstPad * pad,GstObject * parent,GstBuffer * buffer)5761 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
5762 {
5763 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5764 guint available;
5765 GstFlowReturn ret = GST_FLOW_OK;
5766 guint needed = 0;
5767 guint32 id;
5768 guint64 length;
5769
5770 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
5771 GST_DEBUG_OBJECT (demux, "got DISCONT");
5772 gst_adapter_clear (demux->common.adapter);
5773 GST_OBJECT_LOCK (demux);
5774 gst_matroska_read_common_reset_streams (&demux->common,
5775 GST_CLOCK_TIME_NONE, FALSE);
5776 GST_OBJECT_UNLOCK (demux);
5777 }
5778
5779 gst_adapter_push (demux->common.adapter, buffer);
5780 buffer = NULL;
5781
5782 next:
5783 available = gst_adapter_available (demux->common.adapter);
5784
5785 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
5786 GST_ELEMENT_CAST (demux), &id, &length, &needed);
5787 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
5788 if (demux->common.ebml_segment_length != G_MAXUINT64
5789 && demux->common.offset >=
5790 demux->common.ebml_segment_start + demux->common.ebml_segment_length) {
5791 return GST_FLOW_OK;
5792 } else {
5793 gint64 bytes_scanned;
5794 if (demux->common.start_resync_offset == -1) {
5795 demux->common.start_resync_offset = demux->common.offset;
5796 demux->common.state_to_restore = demux->common.state;
5797 }
5798 bytes_scanned = demux->common.offset - demux->common.start_resync_offset;
5799 if (bytes_scanned <= INVALID_DATA_THRESHOLD) {
5800 GST_WARNING_OBJECT (demux,
5801 "parse error, looking for next cluster, actual offset %"
5802 G_GUINT64_FORMAT ", start resync offset %" G_GUINT64_FORMAT,
5803 demux->common.offset, demux->common.start_resync_offset);
5804 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
5805 ret = GST_FLOW_OK;
5806 } else {
5807 GST_WARNING_OBJECT (demux,
5808 "unrecoverable parse error, next cluster not found and threshold "
5809 "exceeded, bytes scanned %" G_GINT64_FORMAT, bytes_scanned);
5810 return ret;
5811 }
5812 }
5813 }
5814
5815 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
5816 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
5817 demux->common.offset, id, length, needed, available);
5818
5819 if (needed > available)
5820 return GST_FLOW_OK;
5821
5822 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5823 if (ret == GST_FLOW_EOS) {
5824 /* need more data */
5825 return GST_FLOW_OK;
5826 } else if (ret != GST_FLOW_OK) {
5827 return ret;
5828 } else
5829 goto next;
5830 }
5831
5832 static gboolean
gst_matroska_demux_handle_sink_event(GstPad * pad,GstObject * parent,GstEvent * event)5833 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
5834 GstEvent * event)
5835 {
5836 gboolean res = TRUE;
5837 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5838
5839 GST_DEBUG_OBJECT (demux,
5840 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
5841
5842 switch (GST_EVENT_TYPE (event)) {
5843 case GST_EVENT_SEGMENT:
5844 {
5845 const GstSegment *segment;
5846
5847 /* some debug output */
5848 gst_event_parse_segment (event, &segment);
5849 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
5850 GST_DEBUG_OBJECT (demux,
5851 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
5852 segment);
5853
5854 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
5855 GST_DEBUG_OBJECT (demux, "still starting");
5856 goto exit;
5857 }
5858
5859 /* we only expect a BYTE segment, e.g. following a seek */
5860 if (segment->format != GST_FORMAT_BYTES) {
5861 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
5862 goto exit;
5863 }
5864
5865 GST_DEBUG_OBJECT (demux, "clearing segment state");
5866 GST_OBJECT_LOCK (demux);
5867 /* clear current segment leftover */
5868 gst_adapter_clear (demux->common.adapter);
5869 /* and some streaming setup */
5870 demux->common.offset = segment->start;
5871 /* accumulate base based on current position */
5872 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
5873 demux->common.segment.base +=
5874 (MAX (demux->common.segment.position, demux->stream_start_time)
5875 - demux->stream_start_time) / fabs (demux->common.segment.rate);
5876 /* do not know where we are;
5877 * need to come across a cluster and generate segment */
5878 demux->common.segment.position = GST_CLOCK_TIME_NONE;
5879 demux->cluster_time = GST_CLOCK_TIME_NONE;
5880 demux->cluster_offset = 0;
5881 demux->cluster_prevsize = 0;
5882 demux->need_segment = TRUE;
5883 demux->segment_seqnum = gst_event_get_seqnum (event);
5884 /* but keep some of the upstream segment */
5885 demux->common.segment.rate = segment->rate;
5886 demux->common.segment.flags = segment->flags;
5887 /* also check if need to keep some of the requested seek position */
5888 if (demux->seek_offset == segment->start) {
5889 GST_DEBUG_OBJECT (demux, "position matches requested seek");
5890 demux->common.segment.position = demux->requested_seek_time;
5891 } else {
5892 GST_DEBUG_OBJECT (demux, "unexpected segment position");
5893 }
5894 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
5895 demux->seek_offset = -1;
5896 GST_OBJECT_UNLOCK (demux);
5897 exit:
5898 /* chain will send initial segment after pads have been added,
5899 * or otherwise come up with one */
5900 GST_DEBUG_OBJECT (demux, "eating event");
5901 gst_event_unref (event);
5902 res = TRUE;
5903 break;
5904 }
5905 case GST_EVENT_EOS:
5906 {
5907 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA
5908 && demux->common.state != GST_MATROSKA_READ_STATE_SCANNING) {
5909 gst_event_unref (event);
5910 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5911 (NULL), ("got eos and didn't receive a complete header object"));
5912 } else if (demux->common.num_streams == 0) {
5913 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5914 (NULL), ("got eos but no streams (yet)"));
5915 } else {
5916 gst_matroska_demux_send_event (demux, event);
5917 }
5918 break;
5919 }
5920 case GST_EVENT_FLUSH_STOP:
5921 {
5922 guint64 dur;
5923
5924 gst_adapter_clear (demux->common.adapter);
5925 GST_OBJECT_LOCK (demux);
5926 gst_matroska_read_common_reset_streams (&demux->common,
5927 GST_CLOCK_TIME_NONE, TRUE);
5928 gst_flow_combiner_reset (demux->flowcombiner);
5929 dur = demux->common.segment.duration;
5930 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
5931 demux->common.segment.duration = dur;
5932 demux->cluster_time = GST_CLOCK_TIME_NONE;
5933 demux->cluster_offset = 0;
5934 demux->cluster_prevsize = 0;
5935 GST_OBJECT_UNLOCK (demux);
5936 /* fall-through */
5937 }
5938 default:
5939 res = gst_pad_event_default (pad, parent, event);
5940 break;
5941 }
5942
5943 return res;
5944 }
5945
5946 static gboolean
gst_matroska_demux_sink_activate(GstPad * sinkpad,GstObject * parent)5947 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
5948 {
5949 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5950 GstQuery *query;
5951 gboolean pull_mode = FALSE;
5952
5953 query = gst_query_new_scheduling ();
5954
5955 if (gst_pad_peer_query (sinkpad, query))
5956 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
5957 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
5958
5959 gst_query_unref (query);
5960
5961 if (pull_mode) {
5962 GST_DEBUG ("going to pull mode");
5963 demux->streaming = FALSE;
5964 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
5965 } else {
5966 GST_DEBUG ("going to push (streaming) mode");
5967 demux->streaming = TRUE;
5968 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
5969 }
5970 }
5971
5972 static gboolean
gst_matroska_demux_sink_activate_mode(GstPad * sinkpad,GstObject * parent,GstPadMode mode,gboolean active)5973 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
5974 GstPadMode mode, gboolean active)
5975 {
5976 switch (mode) {
5977 case GST_PAD_MODE_PULL:
5978 if (active) {
5979 /* if we have a scheduler we can start the task */
5980 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
5981 sinkpad, NULL);
5982 } else {
5983 gst_pad_stop_task (sinkpad);
5984 }
5985 return TRUE;
5986 case GST_PAD_MODE_PUSH:
5987 return TRUE;
5988 default:
5989 return FALSE;
5990 }
5991 }
5992
5993 static GstCaps *
gst_matroska_demux_video_caps(GstMatroskaTrackVideoContext * videocontext,const gchar * codec_id,guint8 * data,guint size,gchar ** codec_name,guint32 * riff_fourcc)5994 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
5995 videocontext, const gchar * codec_id, guint8 * data, guint size,
5996 gchar ** codec_name, guint32 * riff_fourcc)
5997 {
5998 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
5999 GstCaps *caps = NULL;
6000
6001 g_assert (videocontext != NULL);
6002 g_assert (codec_name != NULL);
6003
6004 if (riff_fourcc)
6005 *riff_fourcc = 0;
6006
6007 /* TODO: check if we have all codec types from matroska-ids.h
6008 * check if we have to do more special things with codec_private
6009 *
6010 * Add support for
6011 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
6012 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
6013 */
6014
6015 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
6016 gst_riff_strf_vids *vids = NULL;
6017
6018 if (data) {
6019 GstBuffer *buf = NULL;
6020
6021 vids = (gst_riff_strf_vids *) data;
6022
6023 /* assure size is big enough */
6024 if (size < 24) {
6025 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
6026 return NULL;
6027 }
6028 if (size < sizeof (gst_riff_strf_vids)) {
6029 vids = g_new (gst_riff_strf_vids, 1);
6030 memcpy (vids, data, size);
6031 }
6032
6033 context->dts_only = TRUE; /* VFW files only store DTS */
6034
6035 /* little-endian -> byte-order */
6036 vids->size = GUINT32_FROM_LE (vids->size);
6037 vids->width = GUINT32_FROM_LE (vids->width);
6038 vids->height = GUINT32_FROM_LE (vids->height);
6039 vids->planes = GUINT16_FROM_LE (vids->planes);
6040 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
6041 vids->compression = GUINT32_FROM_LE (vids->compression);
6042 vids->image_size = GUINT32_FROM_LE (vids->image_size);
6043 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
6044 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
6045 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
6046 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
6047
6048 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
6049 gsize offset = sizeof (gst_riff_strf_vids);
6050
6051 buf =
6052 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
6053 size - offset), size - offset);
6054 }
6055
6056 if (riff_fourcc)
6057 *riff_fourcc = vids->compression;
6058
6059 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
6060 buf, NULL, codec_name);
6061
6062 if (caps == NULL) {
6063 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
6064 GST_FOURCC_ARGS (vids->compression));
6065 } else {
6066 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
6067 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
6068 "video/x-compressed-yuv");
6069 context->intra_only =
6070 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
6071 }
6072
6073 if (buf)
6074 gst_buffer_unref (buf);
6075
6076 if (vids != (gst_riff_strf_vids *) data)
6077 g_free (vids);
6078 }
6079 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
6080 GstVideoInfo info;
6081 GstVideoFormat format;
6082
6083 gst_video_info_init (&info);
6084 switch (videocontext->fourcc) {
6085 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
6086 format = GST_VIDEO_FORMAT_I420;
6087 break;
6088 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
6089 format = GST_VIDEO_FORMAT_YUY2;
6090 break;
6091 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
6092 format = GST_VIDEO_FORMAT_YV12;
6093 break;
6094 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
6095 format = GST_VIDEO_FORMAT_UYVY;
6096 break;
6097 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
6098 format = GST_VIDEO_FORMAT_AYUV;
6099 break;
6100 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
6101 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
6102 format = GST_VIDEO_FORMAT_GRAY8;
6103 break;
6104 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
6105 format = GST_VIDEO_FORMAT_RGB;
6106 break;
6107 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
6108 format = GST_VIDEO_FORMAT_BGR;
6109 break;
6110 default:
6111 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
6112 GST_FOURCC_ARGS (videocontext->fourcc));
6113 return NULL;
6114 }
6115
6116 context->intra_only = TRUE;
6117
6118 gst_video_info_set_format (&info, format, videocontext->pixel_width,
6119 videocontext->pixel_height);
6120 caps = gst_video_info_to_caps (&info);
6121 *codec_name = gst_pb_utils_get_codec_description (caps);
6122 context->alignment = 32;
6123 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
6124 caps = gst_caps_new_simple ("video/x-divx",
6125 "divxversion", G_TYPE_INT, 4, NULL);
6126 *codec_name = g_strdup ("MPEG-4 simple profile");
6127 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
6128 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
6129 caps = gst_caps_new_simple ("video/mpeg",
6130 "mpegversion", G_TYPE_INT, 4,
6131 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
6132 if (data) {
6133 GstBuffer *priv;
6134
6135 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
6136 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6137 gst_buffer_unref (priv);
6138
6139 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
6140 }
6141 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
6142 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
6143 else
6144 *codec_name = g_strdup ("MPEG-4 advanced profile");
6145 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
6146 #if 0
6147 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
6148 "divxversion", G_TYPE_INT, 3, NULL),
6149 gst_structure_new ("video/x-msmpeg",
6150 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
6151 #endif
6152 caps = gst_caps_new_simple ("video/x-msmpeg",
6153 "msmpegversion", G_TYPE_INT, 43, NULL);
6154 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
6155 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
6156 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
6157 gint mpegversion;
6158
6159 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
6160 mpegversion = 1;
6161 else
6162 mpegversion = 2;
6163
6164 caps = gst_caps_new_simple ("video/mpeg",
6165 "systemstream", G_TYPE_BOOLEAN, FALSE,
6166 "mpegversion", G_TYPE_INT, mpegversion, NULL);
6167 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
6168 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
6169 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
6170 caps = gst_caps_new_empty_simple ("image/jpeg");
6171 *codec_name = g_strdup ("Motion-JPEG");
6172 context->intra_only = TRUE;
6173 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
6174 caps = gst_caps_new_empty_simple ("video/x-h264");
6175 if (data) {
6176 GstBuffer *priv;
6177
6178 /* First byte is the version, second is the profile indication, and third
6179 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
6180 * level indication. */
6181 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
6182 size - 1);
6183
6184 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
6185 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6186 gst_buffer_unref (priv);
6187
6188 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
6189 "alignment", G_TYPE_STRING, "au", NULL);
6190 } else {
6191 GST_WARNING ("No codec data found, assuming output is byte-stream");
6192 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
6193 NULL);
6194 }
6195 *codec_name = g_strdup ("H264");
6196 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
6197 caps = gst_caps_new_empty_simple ("video/x-h265");
6198 if (data) {
6199 GstBuffer *priv;
6200
6201 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
6202 size - 1);
6203
6204 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
6205 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6206 gst_buffer_unref (priv);
6207
6208 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
6209 "alignment", G_TYPE_STRING, "au", NULL);
6210 } else {
6211 GST_WARNING ("No codec data found, assuming output is byte-stream");
6212 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
6213 NULL);
6214 }
6215 *codec_name = g_strdup ("HEVC");
6216 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
6217 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
6218 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
6219 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
6220 gint rmversion = -1;
6221
6222 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
6223 rmversion = 1;
6224 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
6225 rmversion = 2;
6226 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
6227 rmversion = 3;
6228 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
6229 rmversion = 4;
6230
6231 caps = gst_caps_new_simple ("video/x-pn-realvideo",
6232 "rmversion", G_TYPE_INT, rmversion, NULL);
6233 GST_DEBUG ("data:%p, size:0x%x", data, size);
6234 /* We need to extract the extradata ! */
6235 if (data && (size >= 0x22)) {
6236 GstBuffer *priv;
6237 guint rformat;
6238 guint subformat;
6239
6240 subformat = GST_READ_UINT32_BE (data + 0x1a);
6241 rformat = GST_READ_UINT32_BE (data + 0x1e);
6242
6243 priv =
6244 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
6245 size - 0x1a);
6246 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
6247 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
6248 gst_buffer_unref (priv);
6249
6250 }
6251 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
6252 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
6253 caps = gst_caps_new_empty_simple ("video/x-theora");
6254 context->stream_headers =
6255 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6256 context->codec_priv_size);
6257 /* FIXME: mark stream as broken and skip if there are no stream headers */
6258 context->send_stream_headers = TRUE;
6259 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
6260 caps = gst_caps_new_empty_simple ("video/x-dirac");
6261 *codec_name = g_strdup_printf ("Dirac");
6262 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
6263 caps = gst_caps_new_empty_simple ("video/x-vp8");
6264 *codec_name = g_strdup_printf ("On2 VP8");
6265 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
6266 caps = gst_caps_new_empty_simple ("video/x-vp9");
6267 *codec_name = g_strdup_printf ("On2 VP9");
6268 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_AV1)) {
6269 caps = gst_caps_new_empty_simple ("video/x-av1");
6270 if (data) {
6271 GstBuffer *priv;
6272
6273 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
6274 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6275 gst_buffer_unref (priv);
6276 } else {
6277 GST_WARNING ("No AV1 codec data found!");
6278 }
6279 *codec_name = g_strdup_printf ("AOM AV1");
6280 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
6281 guint32 fourcc;
6282 const gchar *variant, *variant_descr = "";
6283
6284 /* Expect a fourcc in the codec private data */
6285 if (!data || size < 4) {
6286 GST_WARNING ("No or too small PRORESS fourcc (%d bytes)", size);
6287 return NULL;
6288 }
6289
6290 fourcc = GST_STR_FOURCC (data);
6291 switch (fourcc) {
6292 case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
6293 variant_descr = " 4:2:2 LT";
6294 variant = "lt";
6295 break;
6296 case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
6297 variant = "hq";
6298 variant_descr = " 4:2:2 HQ";
6299 break;
6300 case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
6301 variant = "4444";
6302 variant_descr = " 4:4:4:4";
6303 break;
6304 case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
6305 variant = "proxy";
6306 variant_descr = " 4:2:2 Proxy";
6307 break;
6308 case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
6309 default:
6310 variant = "standard";
6311 variant_descr = " 4:2:2 SD";
6312 break;
6313 }
6314
6315 GST_LOG ("Prores video, codec fourcc %" GST_FOURCC_FORMAT,
6316 GST_FOURCC_ARGS (fourcc));
6317
6318 caps = gst_caps_new_simple ("video/x-prores",
6319 "format", G_TYPE_STRING, variant, NULL);
6320 *codec_name = g_strdup_printf ("Apple ProRes%s", variant_descr);
6321 context->postprocess_frame = gst_matroska_demux_add_prores_header;
6322 } else {
6323 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6324 return NULL;
6325 }
6326
6327 if (caps != NULL) {
6328 int i;
6329 GstStructure *structure;
6330
6331 for (i = 0; i < gst_caps_get_size (caps); i++) {
6332 structure = gst_caps_get_structure (caps, i);
6333
6334 /* FIXME: use the real unit here! */
6335 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
6336 videocontext->pixel_width,
6337 videocontext->pixel_height,
6338 videocontext->display_width, videocontext->display_height);
6339
6340 /* pixel width and height are the w and h of the video in pixels */
6341 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
6342 gint w = videocontext->pixel_width;
6343 gint h = videocontext->pixel_height;
6344
6345 gst_structure_set (structure,
6346 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
6347 }
6348
6349 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
6350 int n, d;
6351
6352 if (videocontext->display_width <= 0)
6353 videocontext->display_width = videocontext->pixel_width;
6354 if (videocontext->display_height <= 0)
6355 videocontext->display_height = videocontext->pixel_height;
6356
6357 /* calculate the pixel aspect ratio using the display and pixel w/h */
6358 n = videocontext->display_width * videocontext->pixel_height;
6359 d = videocontext->display_height * videocontext->pixel_width;
6360 GST_DEBUG ("setting PAR to %d/%d", n, d);
6361 gst_structure_set (structure, "pixel-aspect-ratio",
6362 GST_TYPE_FRACTION,
6363 videocontext->display_width * videocontext->pixel_height,
6364 videocontext->display_height * videocontext->pixel_width, NULL);
6365 }
6366
6367 if (videocontext->default_fps > 0.0) {
6368 gint fps_n, fps_d;
6369
6370 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
6371
6372 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
6373
6374 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
6375 fps_d, NULL);
6376 } else if (context->default_duration > 0) {
6377 int fps_n, fps_d;
6378
6379 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
6380
6381 GST_INFO ("using default duration %" G_GUINT64_FORMAT
6382 " framerate %d/%d", context->default_duration, fps_n, fps_d);
6383
6384 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
6385 fps_n, fps_d, NULL);
6386 } else {
6387 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
6388 0, 1, NULL);
6389 }
6390
6391 switch (videocontext->interlace_mode) {
6392 case GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE:
6393 gst_structure_set (structure,
6394 "interlace-mode", G_TYPE_STRING, "progressive", NULL);
6395 break;
6396 case GST_MATROSKA_INTERLACE_MODE_INTERLACED:
6397 gst_structure_set (structure,
6398 "interlace-mode", G_TYPE_STRING, "mixed", NULL);
6399 break;
6400 default:
6401 break;
6402 }
6403 }
6404 if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
6405 if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
6406 videocontext->pixel_width, videocontext->pixel_height,
6407 videocontext->display_width * videocontext->pixel_height,
6408 videocontext->display_height * videocontext->pixel_width)) {
6409 videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
6410 }
6411 gst_caps_set_simple (caps,
6412 "multiview-mode", G_TYPE_STRING,
6413 gst_video_multiview_mode_to_caps_string
6414 (videocontext->multiview_mode), "multiview-flags",
6415 GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
6416 GST_FLAG_SET_MASK_EXACT, NULL);
6417 }
6418
6419 if (videocontext->colorimetry.range != GST_VIDEO_COLOR_RANGE_UNKNOWN ||
6420 videocontext->colorimetry.matrix != GST_VIDEO_COLOR_MATRIX_UNKNOWN ||
6421 videocontext->colorimetry.transfer != GST_VIDEO_TRANSFER_UNKNOWN ||
6422 videocontext->colorimetry.primaries !=
6423 GST_VIDEO_COLOR_PRIMARIES_UNKNOWN) {
6424 gchar *colorimetry =
6425 gst_video_colorimetry_to_string (&videocontext->colorimetry);
6426 gst_caps_set_simple (caps, "colorimetry", G_TYPE_STRING, colorimetry,
6427 NULL);
6428 GST_DEBUG ("setting colorimetry to %s", colorimetry);
6429 g_free (colorimetry);
6430 }
6431
6432 caps = gst_caps_simplify (caps);
6433 }
6434
6435 return caps;
6436 }
6437
6438 /*
6439 * Some AAC specific code... *sigh*
6440 * FIXME: maybe we should use '15' and code the sample rate explicitly
6441 * if the sample rate doesn't match the predefined rates exactly? (tpm)
6442 */
6443
6444 static gint
aac_rate_idx(gint rate)6445 aac_rate_idx (gint rate)
6446 {
6447 if (92017 <= rate)
6448 return 0;
6449 else if (75132 <= rate)
6450 return 1;
6451 else if (55426 <= rate)
6452 return 2;
6453 else if (46009 <= rate)
6454 return 3;
6455 else if (37566 <= rate)
6456 return 4;
6457 else if (27713 <= rate)
6458 return 5;
6459 else if (23004 <= rate)
6460 return 6;
6461 else if (18783 <= rate)
6462 return 7;
6463 else if (13856 <= rate)
6464 return 8;
6465 else if (11502 <= rate)
6466 return 9;
6467 else if (9391 <= rate)
6468 return 10;
6469 else
6470 return 11;
6471 }
6472
6473 static gint
aac_profile_idx(const gchar * codec_id)6474 aac_profile_idx (const gchar * codec_id)
6475 {
6476 gint profile;
6477
6478 if (strlen (codec_id) <= 12)
6479 profile = 3;
6480 else if (!strncmp (&codec_id[12], "MAIN", 4))
6481 profile = 0;
6482 else if (!strncmp (&codec_id[12], "LC", 2))
6483 profile = 1;
6484 else if (!strncmp (&codec_id[12], "SSR", 3))
6485 profile = 2;
6486 else
6487 profile = 3;
6488
6489 return profile;
6490 }
6491
6492 static guint
round_up_pow2(guint n)6493 round_up_pow2 (guint n)
6494 {
6495 n = n - 1;
6496 n = n | (n >> 1);
6497 n = n | (n >> 2);
6498 n = n | (n >> 4);
6499 n = n | (n >> 8);
6500 n = n | (n >> 16);
6501 return n + 1;
6502 }
6503
6504 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
6505
6506 static GstCaps *
gst_matroska_demux_audio_caps(GstMatroskaTrackAudioContext * audiocontext,const gchar * codec_id,guint8 * data,guint size,gchar ** codec_name,guint16 * riff_audio_fmt)6507 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
6508 audiocontext, const gchar * codec_id, guint8 * data, guint size,
6509 gchar ** codec_name, guint16 * riff_audio_fmt)
6510 {
6511 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
6512 GstCaps *caps = NULL;
6513
6514 g_assert (audiocontext != NULL);
6515 g_assert (codec_name != NULL);
6516
6517 if (riff_audio_fmt)
6518 *riff_audio_fmt = 0;
6519
6520 /* TODO: check if we have all codec types from matroska-ids.h
6521 * check if we have to do more special things with codec_private
6522 * check if we need bitdepth in different places too
6523 * implement channel position magic
6524 * Add support for:
6525 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
6526 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
6527 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
6528 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
6529 */
6530
6531 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
6532 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
6533 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
6534 gint layer;
6535
6536 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
6537 layer = 1;
6538 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
6539 layer = 2;
6540 else
6541 layer = 3;
6542
6543 caps = gst_caps_new_simple ("audio/mpeg",
6544 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
6545 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
6546 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
6547 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
6548 gboolean sign;
6549 gint endianness;
6550 GstAudioFormat format;
6551
6552 sign = (audiocontext->bitdepth != 8);
6553 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
6554 endianness = G_BIG_ENDIAN;
6555 else
6556 endianness = G_LITTLE_ENDIAN;
6557
6558 format = gst_audio_format_build_integer (sign, endianness,
6559 audiocontext->bitdepth, audiocontext->bitdepth);
6560
6561 /* FIXME: Channel mask and reordering */
6562 caps = gst_caps_new_simple ("audio/x-raw",
6563 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
6564 "layout", G_TYPE_STRING, "interleaved",
6565 "channel-mask", GST_TYPE_BITMASK,
6566 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
6567
6568 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
6569 audiocontext->bitdepth);
6570 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
6571 context->alignment = round_up_pow2 (context->alignment);
6572 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
6573 const gchar *format;
6574 if (audiocontext->bitdepth == 32)
6575 format = "F32LE";
6576 else
6577 format = "F64LE";
6578 /* FIXME: Channel mask and reordering */
6579 caps = gst_caps_new_simple ("audio/x-raw",
6580 "format", G_TYPE_STRING, format,
6581 "layout", G_TYPE_STRING, "interleaved",
6582 "channel-mask", GST_TYPE_BITMASK,
6583 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
6584 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
6585 audiocontext->bitdepth);
6586 context->alignment = audiocontext->bitdepth / 8;
6587 context->alignment = round_up_pow2 (context->alignment);
6588 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
6589 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
6590 caps = gst_caps_new_simple ("audio/x-ac3",
6591 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6592 *codec_name = g_strdup ("AC-3 audio");
6593 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
6594 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
6595 caps = gst_caps_new_simple ("audio/x-eac3",
6596 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6597 *codec_name = g_strdup ("E-AC-3 audio");
6598 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
6599 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
6600 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
6601 *codec_name = g_strdup ("Dolby TrueHD");
6602 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
6603 caps = gst_caps_new_empty_simple ("audio/x-dts");
6604 *codec_name = g_strdup ("DTS audio");
6605 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
6606 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
6607 context->stream_headers =
6608 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6609 context->codec_priv_size);
6610 /* FIXME: mark stream as broken and skip if there are no stream headers */
6611 context->send_stream_headers = TRUE;
6612 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
6613 caps = gst_caps_new_empty_simple ("audio/x-flac");
6614 context->stream_headers =
6615 gst_matroska_parse_flac_stream_headers (context->codec_priv,
6616 context->codec_priv_size);
6617 /* FIXME: mark stream as broken and skip if there are no stream headers */
6618 context->send_stream_headers = TRUE;
6619 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
6620 caps = gst_caps_new_empty_simple ("audio/x-speex");
6621 context->stream_headers =
6622 gst_matroska_parse_speex_stream_headers (context->codec_priv,
6623 context->codec_priv_size);
6624 /* FIXME: mark stream as broken and skip if there are no stream headers */
6625 context->send_stream_headers = TRUE;
6626 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
6627 GstBuffer *tmp;
6628
6629 if (context->codec_priv_size >= 19) {
6630 if (audiocontext->samplerate)
6631 GST_WRITE_UINT32_LE ((guint8 *) context->codec_priv + 12,
6632 audiocontext->samplerate);
6633 if (context->codec_delay) {
6634 guint64 delay =
6635 gst_util_uint64_scale_round (context->codec_delay, 48000,
6636 GST_SECOND);
6637 GST_WRITE_UINT16_LE ((guint8 *) context->codec_priv + 10, delay);
6638 }
6639
6640 tmp =
6641 gst_buffer_new_wrapped (g_memdup (context->codec_priv,
6642 context->codec_priv_size), context->codec_priv_size);
6643 caps = gst_codec_utils_opus_create_caps_from_header (tmp, NULL);
6644 gst_buffer_unref (tmp);
6645 *codec_name = g_strdup ("Opus");
6646 } else if (context->codec_priv_size == 0) {
6647 GST_WARNING ("No Opus codec data found, trying to create one");
6648 if (audiocontext->channels <= 2) {
6649 guint8 streams, coupled, channels;
6650 guint32 samplerate;
6651
6652 samplerate =
6653 audiocontext->samplerate == 0 ? 48000 : audiocontext->samplerate;
6654 channels = audiocontext->channels == 0 ? 2 : audiocontext->channels;
6655 if (channels == 1) {
6656 streams = 1;
6657 coupled = 0;
6658 } else {
6659 streams = 1;
6660 coupled = 1;
6661 }
6662
6663 caps =
6664 gst_codec_utils_opus_create_caps (samplerate, channels, 0, streams,
6665 coupled, NULL);
6666 if (caps) {
6667 *codec_name = g_strdup ("Opus");
6668 } else {
6669 GST_WARNING ("Failed to create Opus caps from audio context");
6670 }
6671 } else {
6672 GST_WARNING ("No Opus codec data, and not enough info to create one");
6673 }
6674 } else {
6675 GST_WARNING ("Invalid Opus codec data size (got %" G_GSIZE_FORMAT
6676 ", expected 19)", context->codec_priv_size);
6677 }
6678 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
6679 gst_riff_strf_auds auds;
6680
6681 if (data && size >= 18) {
6682 GstBuffer *codec_data = NULL;
6683
6684 /* little-endian -> byte-order */
6685 auds.format = GST_READ_UINT16_LE (data);
6686 auds.channels = GST_READ_UINT16_LE (data + 2);
6687 auds.rate = GST_READ_UINT32_LE (data + 4);
6688 auds.av_bps = GST_READ_UINT32_LE (data + 8);
6689 auds.blockalign = GST_READ_UINT16_LE (data + 12);
6690 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
6691
6692 /* 18 is the waveformatex size */
6693 if (size > 18) {
6694 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
6695 data + 18, size - 18, 0, size - 18, NULL, NULL);
6696 }
6697
6698 if (riff_audio_fmt)
6699 *riff_audio_fmt = auds.format;
6700
6701 /* FIXME: Handle reorder map */
6702 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, codec_data,
6703 NULL, codec_name, NULL);
6704 if (codec_data)
6705 gst_buffer_unref (codec_data);
6706
6707 if (caps == NULL) {
6708 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
6709 }
6710 } else {
6711 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
6712 }
6713 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
6714 GstBuffer *priv = NULL;
6715 gint mpegversion;
6716 gint rate_idx, profile;
6717 guint8 *data = NULL;
6718
6719 /* unspecified AAC profile with opaque private codec data */
6720 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
6721 if (context->codec_priv_size >= 2) {
6722 guint obj_type, freq_index, explicit_freq_bytes = 0;
6723
6724 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6725 mpegversion = 4;
6726 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
6727 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
6728 if (freq_index == 15)
6729 explicit_freq_bytes = 3;
6730 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
6731 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
6732 context->codec_priv_size), context->codec_priv_size);
6733 /* assume SBR if samplerate <= 24kHz */
6734 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
6735 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
6736 audiocontext->samplerate *= 2;
6737 }
6738 } else {
6739 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
6740 /* this is pretty broken;
6741 * maybe we need to make up some default private,
6742 * or maybe ADTS data got dumped in.
6743 * Let's set up some private data now, and check actual data later */
6744 /* just try this and see what happens ... */
6745 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6746 context->postprocess_frame = gst_matroska_demux_check_aac;
6747 }
6748 }
6749
6750 /* make up decoder-specific data if it is not supplied */
6751 if (priv == NULL) {
6752 GstMapInfo map;
6753
6754 priv = gst_buffer_new_allocate (NULL, 5, NULL);
6755 gst_buffer_map (priv, &map, GST_MAP_WRITE);
6756 data = map.data;
6757 rate_idx = aac_rate_idx (audiocontext->samplerate);
6758 profile = aac_profile_idx (codec_id);
6759
6760 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
6761 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
6762
6763 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
6764 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
6765 mpegversion = 2;
6766 gst_buffer_unmap (priv, &map);
6767 gst_buffer_set_size (priv, 2);
6768 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
6769 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
6770 mpegversion = 4;
6771
6772 if (g_strrstr (codec_id, "SBR")) {
6773 /* HE-AAC (aka SBR AAC) */
6774 audiocontext->samplerate *= 2;
6775 rate_idx = aac_rate_idx (audiocontext->samplerate);
6776 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
6777 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
6778 data[4] = (1 << 7) | (rate_idx << 3);
6779 gst_buffer_unmap (priv, &map);
6780 } else {
6781 gst_buffer_unmap (priv, &map);
6782 gst_buffer_set_size (priv, 2);
6783 }
6784 } else {
6785 gst_buffer_unmap (priv, &map);
6786 gst_buffer_unref (priv);
6787 priv = NULL;
6788 GST_ERROR ("Unknown AAC profile and no codec private data");
6789 }
6790 }
6791
6792 if (priv) {
6793 caps = gst_caps_new_simple ("audio/mpeg",
6794 "mpegversion", G_TYPE_INT, mpegversion,
6795 "framed", G_TYPE_BOOLEAN, TRUE,
6796 "stream-format", G_TYPE_STRING, "raw", NULL);
6797 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6798 if (context->codec_priv && context->codec_priv_size > 0)
6799 gst_codec_utils_aac_caps_set_level_and_profile (caps,
6800 context->codec_priv, context->codec_priv_size);
6801 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
6802 gst_buffer_unref (priv);
6803 }
6804 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
6805 caps = gst_caps_new_simple ("audio/x-tta",
6806 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
6807 *codec_name = g_strdup ("TTA audio");
6808 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
6809 caps = gst_caps_new_simple ("audio/x-wavpack",
6810 "width", G_TYPE_INT, audiocontext->bitdepth,
6811 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6812 *codec_name = g_strdup ("Wavpack audio");
6813 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
6814 audiocontext->wvpk_block_index = 0;
6815 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
6816 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
6817 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
6818 gint raversion = -1;
6819
6820 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
6821 raversion = 1;
6822 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
6823 raversion = 8;
6824 else
6825 raversion = 2;
6826
6827 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
6828 "raversion", G_TYPE_INT, raversion, NULL);
6829 /* Extract extra information from caps, mapping varies based on codec */
6830 if (data && (size >= 0x50)) {
6831 GstBuffer *priv;
6832 guint flavor;
6833 guint packet_size;
6834 guint height;
6835 guint leaf_size;
6836 guint sample_width;
6837 guint extra_data_size;
6838
6839 GST_DEBUG ("real audio raversion:%d", raversion);
6840 if (raversion == 8) {
6841 /* COOK */
6842 flavor = GST_READ_UINT16_BE (data + 22);
6843 packet_size = GST_READ_UINT32_BE (data + 24);
6844 height = GST_READ_UINT16_BE (data + 40);
6845 leaf_size = GST_READ_UINT16_BE (data + 44);
6846 sample_width = GST_READ_UINT16_BE (data + 58);
6847 extra_data_size = GST_READ_UINT32_BE (data + 74);
6848
6849 GST_DEBUG
6850 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
6851 flavor, packet_size, height, leaf_size, sample_width,
6852 extra_data_size);
6853 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
6854 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
6855 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
6856
6857 if ((size - 78) >= extra_data_size) {
6858 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
6859 extra_data_size);
6860 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6861 gst_buffer_unref (priv);
6862 }
6863 }
6864 }
6865
6866 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
6867 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
6868 caps = gst_caps_new_empty_simple ("audio/x-sipro");
6869 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
6870 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
6871 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
6872 *codec_name = g_strdup ("Real Audio Lossless");
6873 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
6874 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
6875 *codec_name = g_strdup ("Sony ATRAC3");
6876 } else {
6877 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6878 return NULL;
6879 }
6880
6881 if (caps != NULL) {
6882 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
6883 gint i;
6884
6885 for (i = 0; i < gst_caps_get_size (caps); i++) {
6886 gst_structure_set (gst_caps_get_structure (caps, i),
6887 "channels", G_TYPE_INT, audiocontext->channels,
6888 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
6889 }
6890 }
6891
6892 caps = gst_caps_simplify (caps);
6893 }
6894
6895 return caps;
6896 }
6897
6898 static GstCaps *
gst_matroska_demux_subtitle_caps(GstMatroskaTrackSubtitleContext * subtitlecontext,const gchar * codec_id,gpointer data,guint size)6899 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
6900 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
6901 {
6902 GstCaps *caps = NULL;
6903 GstMatroskaTrackContext *context =
6904 (GstMatroskaTrackContext *) subtitlecontext;
6905
6906 /* for backwards compatibility */
6907 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
6908 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
6909 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
6910 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
6911 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
6912 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
6913 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
6914 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
6915
6916 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
6917 * Check if we have to do something with codec_private */
6918 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
6919 /* well, plain text simply does not have a lot of markup ... */
6920 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
6921 "pango-markup", NULL);
6922 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6923 subtitlecontext->check_markup = TRUE;
6924 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
6925 caps = gst_caps_new_empty_simple ("application/x-ssa");
6926 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6927 subtitlecontext->check_markup = FALSE;
6928 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
6929 caps = gst_caps_new_empty_simple ("application/x-ass");
6930 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6931 subtitlecontext->check_markup = FALSE;
6932 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
6933 caps = gst_caps_new_empty_simple ("application/x-usf");
6934 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6935 subtitlecontext->check_markup = FALSE;
6936 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
6937 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
6938 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
6939 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
6940 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
6941 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
6942 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
6943 context->stream_headers =
6944 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6945 context->codec_priv_size);
6946 /* FIXME: mark stream as broken and skip if there are no stream headers */
6947 context->send_stream_headers = TRUE;
6948 } else {
6949 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
6950 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
6951 }
6952
6953 if (data != NULL && size > 0) {
6954 GstBuffer *buf;
6955
6956 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
6957 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
6958 gst_buffer_unref (buf);
6959 }
6960
6961 return caps;
6962 }
6963
6964 #if 0
6965 static void
6966 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
6967 {
6968 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6969
6970 GST_OBJECT_LOCK (demux);
6971 if (demux->common.element_index)
6972 gst_object_unref (demux->common.element_index);
6973 demux->common.element_index = index ? gst_object_ref (index) : NULL;
6974 GST_OBJECT_UNLOCK (demux);
6975 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
6976 demux->common.element_index);
6977 }
6978
6979 static GstIndex *
6980 gst_matroska_demux_get_index (GstElement * element)
6981 {
6982 GstIndex *result = NULL;
6983 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6984
6985 GST_OBJECT_LOCK (demux);
6986 if (demux->common.element_index)
6987 result = gst_object_ref (demux->common.element_index);
6988 GST_OBJECT_UNLOCK (demux);
6989
6990 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
6991
6992 return result;
6993 }
6994 #endif
6995
6996 static GstStateChangeReturn
gst_matroska_demux_change_state(GstElement * element,GstStateChange transition)6997 gst_matroska_demux_change_state (GstElement * element,
6998 GstStateChange transition)
6999 {
7000 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
7001 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
7002
7003 /* handle upwards state changes here */
7004 switch (transition) {
7005 default:
7006 break;
7007 }
7008
7009 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
7010
7011 /* handle downwards state changes */
7012 switch (transition) {
7013 case GST_STATE_CHANGE_PAUSED_TO_READY:
7014 gst_matroska_demux_reset (GST_ELEMENT (demux));
7015 break;
7016 default:
7017 break;
7018 }
7019
7020 return ret;
7021 }
7022
7023 static void
gst_matroska_demux_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)7024 gst_matroska_demux_set_property (GObject * object,
7025 guint prop_id, const GValue * value, GParamSpec * pspec)
7026 {
7027 GstMatroskaDemux *demux;
7028
7029 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
7030 demux = GST_MATROSKA_DEMUX (object);
7031
7032 switch (prop_id) {
7033 case PROP_MAX_GAP_TIME:
7034 GST_OBJECT_LOCK (demux);
7035 demux->max_gap_time = g_value_get_uint64 (value);
7036 GST_OBJECT_UNLOCK (demux);
7037 break;
7038 case PROP_MAX_BACKTRACK_DISTANCE:
7039 GST_OBJECT_LOCK (demux);
7040 demux->max_backtrack_distance = g_value_get_uint (value);
7041 GST_OBJECT_UNLOCK (demux);
7042 break;
7043 default:
7044 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
7045 break;
7046 }
7047 }
7048
7049 static void
gst_matroska_demux_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)7050 gst_matroska_demux_get_property (GObject * object,
7051 guint prop_id, GValue * value, GParamSpec * pspec)
7052 {
7053 GstMatroskaDemux *demux;
7054
7055 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
7056 demux = GST_MATROSKA_DEMUX (object);
7057
7058 switch (prop_id) {
7059 case PROP_MAX_GAP_TIME:
7060 GST_OBJECT_LOCK (demux);
7061 g_value_set_uint64 (value, demux->max_gap_time);
7062 GST_OBJECT_UNLOCK (demux);
7063 break;
7064 case PROP_MAX_BACKTRACK_DISTANCE:
7065 GST_OBJECT_LOCK (demux);
7066 g_value_set_uint (value, demux->max_backtrack_distance);
7067 GST_OBJECT_UNLOCK (demux);
7068 break;
7069 default:
7070 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
7071 break;
7072 }
7073 }
7074
7075 static const gchar *
gst_matroska_track_encryption_algorithm_name(gint val)7076 gst_matroska_track_encryption_algorithm_name (gint val)
7077 {
7078 GEnumValue *en;
7079 GEnumClass *enum_class =
7080 g_type_class_ref (MATROSKA_TRACK_ENCRYPTION_ALGORITHM_TYPE);
7081 en = g_enum_get_value (G_ENUM_CLASS (enum_class), val);
7082 return en ? en->value_nick : NULL;
7083 }
7084
7085 static const gchar *
gst_matroska_track_encryption_cipher_mode_name(gint val)7086 gst_matroska_track_encryption_cipher_mode_name (gint val)
7087 {
7088 GEnumValue *en;
7089 GEnumClass *enum_class =
7090 g_type_class_ref (MATROSKA_TRACK_ENCRYPTION_CIPHER_MODE_TYPE);
7091 en = g_enum_get_value (G_ENUM_CLASS (enum_class), val);
7092 return en ? en->value_nick : NULL;
7093 }
7094
7095 static const gchar *
gst_matroska_track_encoding_scope_name(gint val)7096 gst_matroska_track_encoding_scope_name (gint val)
7097 {
7098 GEnumValue *en;
7099 GEnumClass *enum_class =
7100 g_type_class_ref (MATROSKA_TRACK_ENCODING_SCOPE_TYPE);
7101
7102 en = g_enum_get_value (G_ENUM_CLASS (enum_class), val);
7103 return en ? en->value_nick : NULL;
7104 }
7105
7106 gboolean
gst_matroska_demux_plugin_init(GstPlugin * plugin)7107 gst_matroska_demux_plugin_init (GstPlugin * plugin)
7108 {
7109 gst_riff_init ();
7110
7111 /* parser helper separate debug */
7112 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
7113 0, "EBML stream helper class");
7114
7115 /* create an elementfactory for the matroska_demux element */
7116 if (!gst_element_register (plugin, "matroskademux",
7117 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))
7118 return FALSE;
7119
7120 return TRUE;
7121 }
7122