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