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