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>
7 * matroska-demux.c: matroska file/stream demuxer
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.
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.
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.
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
35 * SECTION:element-matroskademux
36 * @title: matroskademux
38 * matroskademux demuxes a Matroska file into the different contained streams.
40 * ## Example launch line
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.
54 #include <glib/gprintf.h>
56 #include <gst/base/base.h>
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>
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>
70 #include "gstmatroskaelements.h"
71 #include "matroska-demux.h"
72 #include "matroska-ids.h"
74 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
75 #define GST_CAT_DEFAULT matroskademux_debug
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))
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))
91 PROP_MAX_BACKTRACK_DISTANCE
94 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
95 #define DEFAULT_MAX_BACKTRACK_DISTANCE 30
96 #define INVALID_DATA_THRESHOLD (2 * 1024 * 1024)
98 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
101 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
102 "video/x-matroska-3d; audio/webm; video/webm")
105 /* TODO: fill in caps! */
107 static GstStaticPadTemplate audio_src_templ =
108 GST_STATIC_PAD_TEMPLATE ("audio_%u",
111 GST_STATIC_CAPS ("ANY")
114 static GstStaticPadTemplate video_src_templ =
115 GST_STATIC_PAD_TEMPLATE ("video_%u",
118 GST_STATIC_CAPS ("ANY")
121 static GstStaticPadTemplate subtitle_src_templ =
122 GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
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")
130 static GQuark matroska_block_additional_quark;
132 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
133 guint32 id, guint64 length, guint needed);
135 /* element functions */
136 static void gst_matroska_demux_loop (GstPad * pad);
138 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
140 static gboolean gst_matroska_demux_element_query (GstElement * element,
144 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad,
146 static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
147 GstObject * parent, GstPadMode mode, gboolean active);
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);
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);
165 static GstStateChangeReturn
166 gst_matroska_demux_change_state (GstElement * element,
167 GstStateChange transition);
170 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
171 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
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);
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);
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);
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);
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);
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");
209 GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (matroskademux, "matroskademux",
210 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX, _do_init);
213 gst_matroska_demux_finalize (GObject * object)
215 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
217 gst_matroska_read_common_finalize (&demux->common);
218 gst_flow_combiner_free (demux->flowcombiner);
219 G_OBJECT_CLASS (parent_class)->finalize (object);
223 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
225 GObjectClass *gobject_class = (GObjectClass *) klass;
226 GstElementClass *gstelement_class = (GstElementClass *) klass;
228 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
231 gobject_class->finalize = gst_matroska_demux_finalize;
233 gobject_class->get_property = gst_matroska_demux_get_property;
234 gobject_class->set_property = gst_matroska_demux_set_property;
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));
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));
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);
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);
264 gst_element_class_add_static_pad_template (gstelement_class,
266 gst_element_class_add_static_pad_template (gstelement_class,
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);
272 gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
274 "Demuxes Matroska/WebM streams into video/audio/subtitles",
275 "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
279 gst_matroska_demux_init (GstMatroskaDemux * demux)
281 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
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);
295 /* init defaults for common read context */
296 gst_matroska_read_common_init (&demux->common);
298 /* property defaults */
299 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
300 demux->max_backtrack_distance = DEFAULT_MAX_BACKTRACK_DISTANCE;
302 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
304 demux->flowcombiner = gst_flow_combiner_new ();
307 gst_matroska_demux_reset (GST_ELEMENT (demux));
311 gst_matroska_demux_reset (GstElement * element)
313 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
315 GST_DEBUG_OBJECT (demux, "Resetting state");
317 gst_matroska_read_common_reset (GST_ELEMENT (demux), &demux->common);
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;
324 demux->have_group_id = FALSE;
325 demux->group_id = G_MAXUINT;
328 demux->tracks_ebml_offset = G_MAXUINT64;
330 if (demux->clusters) {
331 g_array_unref (demux->clusters);
332 demux->clusters = NULL;
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;
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->upstream_format_is_time = FALSE;
355 demux->segment_seqnum = 0;
356 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
357 demux->seek_offset = -1;
358 demux->audio_lead_in_ts = 0;
359 demux->building_index = FALSE;
360 if (demux->seek_event) {
361 gst_event_unref (demux->seek_event);
362 demux->seek_event = NULL;
365 demux->seek_index = NULL;
366 demux->seek_entry = 0;
368 if (demux->new_segment) {
369 gst_event_unref (demux->new_segment);
370 demux->new_segment = NULL;
373 demux->invalid_duration = FALSE;
375 demux->cached_length = G_MAXUINT64;
377 if (demux->deferred_seek_event)
378 gst_event_unref (demux->deferred_seek_event);
379 demux->deferred_seek_event = NULL;
380 demux->deferred_seek_pad = NULL;
382 gst_flow_combiner_clear (demux->flowcombiner);
386 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
391 GstBuffer *out_buf = buf;
393 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
395 GST_DEBUG ("decoding buffer %p", buf);
397 gst_buffer_map (out_buf, &map, GST_MAP_READ);
401 g_return_val_if_fail (size > 0, buf);
403 if (gst_matroska_decode_data (context->encodings, &data, &size,
404 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
405 if (data != map.data) {
406 gst_buffer_unmap (out_buf, &map);
407 gst_buffer_unref (out_buf);
408 out_buf = gst_buffer_new_wrapped (data, size);
410 gst_buffer_unmap (out_buf, &map);
413 GST_DEBUG ("decode data failed");
414 gst_buffer_unmap (out_buf, &map);
415 gst_buffer_unref (out_buf);
418 /* Encrypted stream */
419 if (context->protection_info) {
421 GstStructure *info_protect = gst_structure_copy (context->protection_info);
422 gboolean encrypted = FALSE;
424 gst_buffer_map (out_buf, &map, GST_MAP_READ);
428 if (gst_matroska_parse_protection_meta (&data, &size, info_protect,
430 if (data != map.data) {
433 gst_buffer_unmap (out_buf, &map);
435 out_buf = gst_buffer_copy_region (tmp_buf, GST_BUFFER_COPY_ALL,
436 gst_buffer_get_size (tmp_buf) - size, size);
437 gst_buffer_unref (tmp_buf);
439 gst_buffer_add_protection_meta (out_buf, info_protect);
441 gst_structure_free (info_protect);
443 gst_buffer_unmap (out_buf, &map);
444 gst_structure_free (info_protect);
447 GST_WARNING ("Adding protection metadata failed");
448 gst_buffer_unmap (out_buf, &map);
449 gst_buffer_unref (out_buf);
450 gst_structure_free (info_protect);
459 gst_matroska_demux_add_stream_headers_to_caps (GstMatroskaDemux * demux,
460 GstBufferList * list, GstCaps * caps)
463 GValue arr_val = G_VALUE_INIT;
464 GValue buf_val = G_VALUE_INIT;
467 g_assert (gst_caps_is_writable (caps));
469 g_value_init (&arr_val, GST_TYPE_ARRAY);
470 g_value_init (&buf_val, GST_TYPE_BUFFER);
472 num = gst_buffer_list_length (list);
473 for (i = 0; i < num; ++i) {
474 g_value_set_boxed (&buf_val, gst_buffer_list_get (list, i));
475 gst_value_array_append_value (&arr_val, &buf_val);
478 s = gst_caps_get_structure (caps, 0);
479 gst_structure_take_value (s, "streamheader", &arr_val);
480 g_value_unset (&buf_val);
484 gst_matroska_demux_parse_mastering_metadata (GstMatroskaDemux * demux,
485 GstEbmlRead * ebml, GstMatroskaTrackVideoContext * video_context)
487 GstFlowReturn ret = GST_FLOW_OK;
488 GstVideoMasteringDisplayInfo minfo;
491 /* Precision defined by HEVC specification */
492 const guint chroma_scale = 50000;
493 const guint luma_scale = 10000;
495 gst_video_mastering_display_info_init (&minfo);
497 DEBUG_ELEMENT_START (demux, ebml, "MasteringMetadata");
499 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
502 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
503 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
506 /* all sub elements have float type */
507 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
510 /* chromaticity should be in [0, 1] range */
511 if (id >= GST_MATROSKA_ID_PRIMARYRCHROMATICITYX &&
512 id <= GST_MATROSKA_ID_WHITEPOINTCHROMATICITYY) {
513 if (num < 0 || num > 1.0) {
514 GST_WARNING_OBJECT (demux, "0x%x has invalid value %f", id, num);
517 } else if (id == GST_MATROSKA_ID_LUMINANCEMAX ||
518 id == GST_MATROSKA_ID_LUMINANCEMIN) {
519 /* Note: webM spec said valid range is [0, 999.9999] but
520 * 1000 cd/m^2 is generally used value on HDR. Just check guint range here.
521 * See https://www.webmproject.org/docs/container/#LuminanceMax
523 if (num < 0 || num > (gdouble) (G_MAXUINT32 / luma_scale)) {
524 GST_WARNING_OBJECT (demux, "0x%x has invalid value %f", id, num);
530 case GST_MATROSKA_ID_PRIMARYRCHROMATICITYX:
531 minfo.display_primaries[0].x = (guint16) (num * chroma_scale);
533 case GST_MATROSKA_ID_PRIMARYRCHROMATICITYY:
534 minfo.display_primaries[0].y = (guint16) (num * chroma_scale);
536 case GST_MATROSKA_ID_PRIMARYGCHROMATICITYX:
537 minfo.display_primaries[1].x = (guint16) (num * chroma_scale);
539 case GST_MATROSKA_ID_PRIMARYGCHROMATICITYY:
540 minfo.display_primaries[1].y = (guint16) (num * chroma_scale);
542 case GST_MATROSKA_ID_PRIMARYBCHROMATICITYX:
543 minfo.display_primaries[2].x = (guint16) (num * chroma_scale);
545 case GST_MATROSKA_ID_PRIMARYBCHROMATICITYY:
546 minfo.display_primaries[2].y = (guint16) (num * chroma_scale);
548 case GST_MATROSKA_ID_WHITEPOINTCHROMATICITYX:
549 minfo.white_point.x = (guint16) (num * chroma_scale);
551 case GST_MATROSKA_ID_WHITEPOINTCHROMATICITYY:
552 minfo.white_point.y = (guint16) (num * chroma_scale);
554 case GST_MATROSKA_ID_LUMINANCEMAX:
555 minfo.max_display_mastering_luminance = (guint32) (num * luma_scale);
557 case GST_MATROSKA_ID_LUMINANCEMIN:
558 minfo.min_display_mastering_luminance = (guint32) (num * luma_scale);
561 GST_FIXME_OBJECT (demux,
562 "Unsupported subelement 0x%x in MasteringMetadata", id);
563 ret = gst_ebml_read_skip (ebml);
568 video_context->mastering_display_info = minfo;
569 video_context->mastering_display_info_present = TRUE;
572 DEBUG_ELEMENT_STOP (demux, ebml, "MasteringMetadata", ret);
578 gst_matroska_demux_parse_colour (GstMatroskaDemux * demux, GstEbmlRead * ebml,
579 GstMatroskaTrackVideoContext * video_context)
582 GstVideoColorimetry colorimetry;
586 colorimetry.range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
587 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
588 colorimetry.transfer = GST_VIDEO_TRANSFER_UNKNOWN;
589 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
591 DEBUG_ELEMENT_START (demux, ebml, "TrackVideoColour");
593 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
596 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
597 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
601 case GST_MATROSKA_ID_VIDEOMATRIXCOEFFICIENTS:{
602 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
605 colorimetry.matrix = gst_video_color_matrix_from_iso ((guint) num);
609 case GST_MATROSKA_ID_VIDEORANGE:{
610 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
615 colorimetry.range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
618 colorimetry.range = GST_VIDEO_COLOR_RANGE_16_235;
621 colorimetry.range = GST_VIDEO_COLOR_RANGE_0_255;
624 GST_FIXME_OBJECT (demux, "Unsupported color range %"
625 G_GUINT64_FORMAT, num);
631 case GST_MATROSKA_ID_VIDEOTRANSFERCHARACTERISTICS:{
632 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
635 colorimetry.transfer =
636 gst_video_transfer_function_from_iso ((guint) num);
640 case GST_MATROSKA_ID_VIDEOPRIMARIES:{
641 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
644 colorimetry.primaries =
645 gst_video_color_primaries_from_iso ((guint) num);
649 case GST_MATROSKA_ID_MASTERINGMETADATA:{
651 gst_matroska_demux_parse_mastering_metadata (demux, ebml,
652 video_context)) != GST_FLOW_OK)
657 case GST_MATROSKA_ID_MAXCLL:{
658 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
660 if (num > G_MAXUINT16) {
661 GST_WARNING_OBJECT (demux,
662 "Too large maxCLL value %" G_GUINT64_FORMAT, num);
664 video_context->content_light_level.max_content_light_level = num;
669 case GST_MATROSKA_ID_MAXFALL:{
670 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
672 if (num >= G_MAXUINT16) {
673 GST_WARNING_OBJECT (demux,
674 "Too large maxFALL value %" G_GUINT64_FORMAT, num);
676 video_context->content_light_level.max_frame_average_light_level =
683 GST_FIXME_OBJECT (demux, "Unsupported subelement 0x%x in Colour", id);
684 ret = gst_ebml_read_skip (ebml);
689 memcpy (&video_context->colorimetry, &colorimetry,
690 sizeof (GstVideoColorimetry));
693 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideoColour", ret);
698 gst_matroska_demux_parse_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml,
699 GstMatroskaTrackContext ** dest_context)
701 GstMatroskaTrackContext *context;
702 GstCaps *caps = NULL;
703 GstTagList *cached_taglist;
705 guint32 id, riff_fourcc = 0;
706 guint16 riff_audio_fmt = 0;
709 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
711 *dest_context = NULL;
713 /* start with the master */
714 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
715 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
719 /* allocate generic... if we know the type, we'll g_renew()
720 * with the precise type */
721 context = g_new0 (GstMatroskaTrackContext, 1);
722 context->index_writer_id = -1;
723 context->type = 0; /* no type yet */
724 context->default_duration = 0;
726 context->set_discont = TRUE;
727 context->timecodescale = 1.0;
729 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
730 GST_MATROSKA_TRACK_LACING;
731 context->from_time = GST_CLOCK_TIME_NONE;
732 context->from_offset = -1;
733 context->to_offset = G_MAXINT64;
734 context->alignment = 1;
735 context->dts_only = FALSE;
736 context->intra_only = FALSE;
737 context->tags = gst_tag_list_new_empty ();
738 g_queue_init (&context->protection_event_queue);
739 context->protection_info = NULL;
741 GST_DEBUG_OBJECT (demux, "Parsing a TrackEntry (%d tracks parsed so far)",
742 demux->common.num_streams);
744 /* try reading the trackentry headers */
745 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
746 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
750 /* track number (unique stream ID) */
751 case GST_MATROSKA_ID_TRACKNUMBER:{
754 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
758 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
759 ret = GST_FLOW_ERROR;
763 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
767 /* track UID (unique identifier) */
768 case GST_MATROSKA_ID_TRACKUID:{
771 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
775 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
776 ret = GST_FLOW_ERROR;
780 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
785 /* track type (video, audio, combined, subtitle, etc.) */
786 case GST_MATROSKA_ID_TRACKTYPE:{
789 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
793 if (context->type != 0 && context->type != track_type) {
794 GST_WARNING_OBJECT (demux,
795 "More than one tracktype defined in a TrackEntry - skipping");
797 } else if (track_type < 1 || track_type > 254) {
798 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
803 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
805 /* ok, so we're actually going to reallocate this thing */
806 switch (track_type) {
807 case GST_MATROSKA_TRACK_TYPE_VIDEO:
808 gst_matroska_track_init_video_context (&context);
810 case GST_MATROSKA_TRACK_TYPE_AUDIO:
811 gst_matroska_track_init_audio_context (&context);
813 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
814 gst_matroska_track_init_subtitle_context (&context);
816 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
817 case GST_MATROSKA_TRACK_TYPE_LOGO:
818 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
819 case GST_MATROSKA_TRACK_TYPE_CONTROL:
821 GST_WARNING_OBJECT (demux,
822 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
830 /* tracktype specific stuff for video */
831 case GST_MATROSKA_ID_TRACKVIDEO:{
832 GstMatroskaTrackVideoContext *videocontext;
834 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
836 if (!gst_matroska_track_init_video_context (&context)) {
837 GST_WARNING_OBJECT (demux,
838 "TrackVideo element in non-video track - ignoring track");
839 ret = GST_FLOW_ERROR;
841 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
844 videocontext = (GstMatroskaTrackVideoContext *) context;
846 while (ret == GST_FLOW_OK &&
847 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
848 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
852 /* Should be one level up but some broken muxers write it here. */
853 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
856 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
860 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
864 GST_DEBUG_OBJECT (demux,
865 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
866 context->default_duration = num;
870 /* video framerate */
871 /* NOTE: This one is here only for backward compatibility.
872 * Use _TRACKDEFAULDURATION one level up. */
873 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
876 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
880 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
884 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
885 if (context->default_duration == 0)
886 context->default_duration =
887 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
888 videocontext->default_fps = num;
892 /* width of the size to display the video at */
893 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
896 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
900 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
904 GST_DEBUG_OBJECT (demux,
905 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
906 videocontext->display_width = num;
910 /* height of the size to display the video at */
911 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
914 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
918 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
922 GST_DEBUG_OBJECT (demux,
923 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
924 videocontext->display_height = num;
928 /* width of the video in the file */
929 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
932 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
936 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
940 GST_DEBUG_OBJECT (demux,
941 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
942 videocontext->pixel_width = num;
946 /* height of the video in the file */
947 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
950 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
954 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
958 GST_DEBUG_OBJECT (demux,
959 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
960 videocontext->pixel_height = num;
964 /* whether the video is interlaced */
965 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
968 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
972 videocontext->interlace_mode =
973 GST_MATROSKA_INTERLACE_MODE_INTERLACED;
975 videocontext->interlace_mode =
976 GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
978 videocontext->interlace_mode =
979 GST_MATROSKA_INTERLACE_MODE_UNKNOWN;
981 GST_DEBUG_OBJECT (demux, "video track interlacing mode: %d",
982 videocontext->interlace_mode);
986 /* interlaced field order */
987 case GST_MATROSKA_ID_VIDEOFIELDORDER:{
990 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
993 if (videocontext->interlace_mode !=
994 GST_MATROSKA_INTERLACE_MODE_INTERLACED) {
995 GST_WARNING_OBJECT (demux,
996 "FieldOrder element when not interlaced - ignoring");
1001 /* turns out we're actually progressive */
1002 videocontext->interlace_mode =
1003 GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
1005 videocontext->field_order = GST_VIDEO_FIELD_ORDER_UNKNOWN;
1007 videocontext->field_order =
1008 GST_VIDEO_FIELD_ORDER_TOP_FIELD_FIRST;
1010 videocontext->field_order =
1011 GST_VIDEO_FIELD_ORDER_BOTTOM_FIELD_FIRST;
1013 GST_FIXME_OBJECT (demux,
1014 "Unknown or unsupported FieldOrder %" G_GUINT64_FORMAT,
1016 videocontext->field_order = GST_VIDEO_FIELD_ORDER_UNKNOWN;
1019 GST_DEBUG_OBJECT (demux, "video track field order: %d",
1020 videocontext->field_order);
1024 /* aspect ratio behaviour */
1025 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
1028 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1031 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
1032 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
1033 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
1034 GST_WARNING_OBJECT (demux,
1035 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
1038 GST_DEBUG_OBJECT (demux,
1039 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
1040 videocontext->asr_mode = num;
1044 /* colourspace (only matters for raw video) fourcc */
1045 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
1050 gst_ebml_read_binary (ebml, &id, &data,
1051 &datalen)) != GST_FLOW_OK)
1056 GST_WARNING_OBJECT (demux,
1057 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
1062 memcpy (&videocontext->fourcc, data, 4);
1063 GST_DEBUG_OBJECT (demux,
1064 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
1065 GST_FOURCC_ARGS (videocontext->fourcc));
1071 case GST_MATROSKA_ID_VIDEOCOLOUR:{
1072 ret = gst_matroska_demux_parse_colour (demux, ebml, videocontext);
1076 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
1080 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1083 GST_DEBUG_OBJECT (demux, "StereoMode: %" G_GUINT64_FORMAT, num);
1086 case GST_MATROSKA_STEREO_MODE_SBS_RL:
1087 videocontext->multiview_flags =
1088 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1090 case GST_MATROSKA_STEREO_MODE_SBS_LR:
1091 videocontext->multiview_mode =
1092 GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
1094 case GST_MATROSKA_STEREO_MODE_TB_RL:
1095 videocontext->multiview_flags =
1096 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1098 case GST_MATROSKA_STEREO_MODE_TB_LR:
1099 videocontext->multiview_mode =
1100 GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM;
1102 case GST_MATROSKA_STEREO_MODE_CHECKER_RL:
1103 videocontext->multiview_flags =
1104 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1106 case GST_MATROSKA_STEREO_MODE_CHECKER_LR:
1107 videocontext->multiview_mode =
1108 GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD;
1110 case GST_MATROSKA_STEREO_MODE_FBF_RL:
1111 videocontext->multiview_flags =
1112 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1114 case GST_MATROSKA_STEREO_MODE_FBF_LR:
1115 videocontext->multiview_mode =
1116 GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
1117 /* FIXME: In frame-by-frame mode, left/right frame buffers are
1118 * laced within one block, and we'll need to apply FIRST_IN_BUNDLE
1119 * accordingly. See http://www.matroska.org/technical/specs/index.html#StereoMode */
1120 GST_FIXME_OBJECT (demux,
1121 "Frame-by-frame stereoscopic mode not fully implemented");
1127 case GST_MATROSKA_ID_VIDEOALPHAMODE:
1131 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1134 GST_DEBUG_OBJECT (demux, "AlphaMode: %" G_GUINT64_FORMAT, num);
1137 videocontext->alpha_mode = TRUE;
1139 videocontext->alpha_mode = FALSE;
1144 GST_WARNING_OBJECT (demux,
1145 "Unknown TrackVideo subelement 0x%x - ignoring", id);
1147 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
1148 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
1149 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
1150 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
1151 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
1152 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
1153 ret = gst_ebml_read_skip (ebml);
1158 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
1162 /* tracktype specific stuff for audio */
1163 case GST_MATROSKA_ID_TRACKAUDIO:{
1164 GstMatroskaTrackAudioContext *audiocontext;
1166 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
1168 if (!gst_matroska_track_init_audio_context (&context)) {
1169 GST_WARNING_OBJECT (demux,
1170 "TrackAudio element in non-audio track - ignoring track");
1171 ret = GST_FLOW_ERROR;
1175 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
1178 audiocontext = (GstMatroskaTrackAudioContext *) context;
1180 while (ret == GST_FLOW_OK &&
1181 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1182 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1187 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
1190 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1195 GST_WARNING_OBJECT (demux,
1196 "Invalid TrackAudioSamplingFrequency %lf", num);
1200 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
1201 audiocontext->samplerate = num;
1206 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
1209 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1213 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
1217 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
1219 audiocontext->bitdepth = num;
1224 case GST_MATROSKA_ID_AUDIOCHANNELS:{
1227 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1231 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
1235 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
1237 audiocontext->channels = num;
1242 GST_WARNING_OBJECT (demux,
1243 "Unknown TrackAudio subelement 0x%x - ignoring", id);
1245 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
1246 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
1247 ret = gst_ebml_read_skip (ebml);
1252 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
1257 /* codec identifier */
1258 case GST_MATROSKA_ID_CODECID:{
1261 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
1264 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
1265 context->codec_id = text;
1269 /* codec private data */
1270 case GST_MATROSKA_ID_CODECPRIVATE:{
1275 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
1278 context->codec_priv = data;
1279 context->codec_priv_size = size;
1281 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1286 /* name of the codec */
1287 case GST_MATROSKA_ID_CODECNAME:{
1290 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1293 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1294 context->codec_name = text;
1299 case GST_MATROSKA_ID_CODECDELAY:{
1302 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1305 context->codec_delay = num;
1307 GST_DEBUG_OBJECT (demux, "CodecDelay: %" GST_TIME_FORMAT,
1308 GST_TIME_ARGS (num));
1313 case GST_MATROSKA_ID_SEEKPREROLL:{
1316 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1319 context->seek_preroll = num;
1321 GST_DEBUG_OBJECT (demux, "SeekPreroll: %" GST_TIME_FORMAT,
1322 GST_TIME_ARGS (num));
1326 /* name of this track */
1327 case GST_MATROSKA_ID_TRACKNAME:{
1330 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1333 context->name = text;
1334 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1338 /* language (matters for audio/subtitles, mostly) */
1339 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1342 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1346 context->language = text;
1349 if (strlen (context->language) >= 4 && context->language[3] == '-')
1350 context->language[3] = '\0';
1352 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1353 GST_STR_NULL (context->language));
1357 /* whether this is actually used */
1358 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1361 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1365 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1367 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1369 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1370 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1374 /* whether it's the default for this track type */
1375 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1378 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1382 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1384 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1386 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1387 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
1391 /* whether the track must be used during playback */
1392 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1395 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1399 context->flags |= GST_MATROSKA_TRACK_FORCED;
1401 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1403 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1404 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
1408 /* lacing (like MPEG, where blocks don't end/start on frame
1410 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1413 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1417 context->flags |= GST_MATROSKA_TRACK_LACING;
1419 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1421 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1422 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
1426 /* default length (in time) of one data block in this track */
1427 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1430 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1435 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1439 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1441 context->default_duration = num;
1445 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1446 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1451 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1454 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1458 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1462 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1463 context->timecodescale = num;
1468 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1471 /* we ignore these because they're nothing useful (i.e. crap)
1472 * or simply not implemented yet. */
1473 case GST_MATROSKA_ID_TRACKMINCACHE:
1474 case GST_MATROSKA_ID_TRACKMAXCACHE:
1475 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1476 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1477 case GST_MATROSKA_ID_TRACKOVERLAY:
1478 case GST_MATROSKA_ID_TRACKTRANSLATE:
1479 case GST_MATROSKA_ID_TRACKOFFSET:
1480 case GST_MATROSKA_ID_CODECSETTINGS:
1481 case GST_MATROSKA_ID_CODECINFOURL:
1482 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1483 case GST_MATROSKA_ID_CODECDECODEALL:
1484 ret = gst_ebml_read_skip (ebml);
1489 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1491 /* Decode codec private data if necessary */
1492 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1493 && context->codec_priv_size > 0) {
1494 if (!gst_matroska_decode_data (context->encodings,
1495 &context->codec_priv, &context->codec_priv_size,
1496 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1497 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1498 ret = GST_FLOW_ERROR;
1502 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1503 && ret != GST_FLOW_EOS)) {
1504 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1505 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1507 gst_matroska_track_free (context);
1509 *dest_context = NULL;
1513 /* check for a cached track taglist */
1515 (GstTagList *) g_hash_table_lookup (demux->common.cached_track_taglists,
1516 GUINT_TO_POINTER (context->uid));
1518 gst_tag_list_insert (context->tags, cached_taglist, GST_TAG_MERGE_APPEND);
1521 switch (context->type) {
1522 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1523 GstMatroskaTrackVideoContext *videocontext =
1524 (GstMatroskaTrackVideoContext *) context;
1526 caps = gst_matroska_demux_video_caps (videocontext,
1527 context->codec_id, context->codec_priv,
1528 context->codec_priv_size, &codec, &riff_fourcc);
1531 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1532 GST_TAG_VIDEO_CODEC, codec, NULL);
1533 context->tags_changed = TRUE;
1539 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1540 GstClockTime lead_in_ts = 0;
1541 GstMatroskaTrackAudioContext *audiocontext =
1542 (GstMatroskaTrackAudioContext *) context;
1544 caps = gst_matroska_demux_audio_caps (audiocontext,
1545 context->codec_id, context->codec_priv, context->codec_priv_size,
1546 &codec, &riff_audio_fmt, &lead_in_ts);
1547 if (lead_in_ts > demux->audio_lead_in_ts) {
1548 demux->audio_lead_in_ts = lead_in_ts;
1549 GST_DEBUG_OBJECT (demux, "Increased audio lead-in to %" GST_TIME_FORMAT,
1550 GST_TIME_ARGS (lead_in_ts));
1554 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1555 GST_TAG_AUDIO_CODEC, codec, NULL);
1556 context->tags_changed = TRUE;
1562 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1563 GstMatroskaTrackSubtitleContext *subtitlecontext =
1564 (GstMatroskaTrackSubtitleContext *) context;
1566 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1567 context->codec_id, context->codec_priv, context->codec_priv_size);
1571 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1572 case GST_MATROSKA_TRACK_TYPE_LOGO:
1573 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1574 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1576 /* we should already have quit by now */
1577 g_assert_not_reached ();
1580 if ((context->language == NULL || *context->language == '\0') &&
1581 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1582 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1583 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1584 context->language = g_strdup ("eng");
1587 if (context->language) {
1590 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1591 lang = gst_tag_get_language_code (context->language);
1592 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1593 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1595 if (context->name) {
1596 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1597 GST_TAG_TITLE, context->name, NULL);
1599 context->tags_changed = TRUE;
1603 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1604 "codec_id='%s'", context->codec_id);
1605 switch (context->type) {
1606 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1607 caps = gst_caps_new_empty_simple ("video/x-unknown");
1609 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1610 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1612 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1613 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1615 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1617 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1620 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1623 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1624 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1625 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1626 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1627 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1628 GST_FOURCC_ARGS (riff_fourcc));
1629 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1632 } else if (context->stream_headers != NULL) {
1633 gst_matroska_demux_add_stream_headers_to_caps (demux,
1634 context->stream_headers, caps);
1637 if (context->encodings) {
1638 GstMatroskaTrackEncoding *enc;
1641 for (i = 0; i < context->encodings->len; i++) {
1642 enc = &g_array_index (context->encodings, GstMatroskaTrackEncoding, i);
1643 if (enc->type == GST_MATROSKA_ENCODING_ENCRYPTION /* encryption */ ) {
1644 GstStructure *s = gst_caps_get_structure (caps, 0);
1645 if (!gst_structure_has_name (s, "application/x-webm-enc")) {
1646 gst_structure_set (s, "original-media-type", G_TYPE_STRING,
1647 gst_structure_get_name (s), NULL);
1648 gst_structure_set (s, "encryption-algorithm", G_TYPE_STRING,
1649 gst_matroska_track_encryption_algorithm_name (enc->enc_algo),
1651 gst_structure_set (s, "encoding-scope", G_TYPE_STRING,
1652 gst_matroska_track_encoding_scope_name (enc->scope), NULL);
1653 gst_structure_set (s, "cipher-mode", G_TYPE_STRING,
1654 gst_matroska_track_encryption_cipher_mode_name
1655 (enc->enc_cipher_mode), NULL);
1656 gst_structure_set_name (s, "application/x-webm-enc");
1662 context->caps = caps;
1665 *dest_context = context;
1670 gst_matroska_demux_add_stream (GstMatroskaDemux * demux,
1671 GstMatroskaTrackContext * context)
1673 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
1674 gchar *padname = NULL;
1675 GstPadTemplate *templ = NULL;
1676 GstStreamFlags stream_flags;
1678 GstEvent *stream_start;
1682 g_ptr_array_add (demux->common.src, context);
1683 context->index = demux->common.num_streams++;
1684 g_assert (demux->common.src->len == demux->common.num_streams);
1685 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1) =
1688 /* now create the GStreamer connectivity */
1689 switch (context->type) {
1690 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1691 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1692 templ = gst_element_class_get_pad_template (klass, "video_%u");
1694 if (!context->intra_only)
1695 demux->have_nonintraonly_v_streams = TRUE;
1698 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1699 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1700 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1703 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1704 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1705 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1709 /* we should already have quit by now */
1710 g_assert_not_reached ();
1713 /* the pad in here */
1714 context->pad = gst_pad_new_from_template (templ, padname);
1716 gst_pad_set_event_function (context->pad,
1717 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1718 gst_pad_set_query_function (context->pad,
1719 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1721 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1722 padname, context->caps);
1724 gst_pad_set_element_private (context->pad, context);
1726 gst_pad_use_fixed_caps (context->pad);
1727 gst_pad_set_active (context->pad, TRUE);
1730 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1731 "%03" G_GUINT64_FORMAT ":%03" G_GUINT64_FORMAT,
1732 context->num, context->uid);
1734 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1737 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1738 demux->have_group_id = TRUE;
1740 demux->have_group_id = FALSE;
1741 gst_event_unref (stream_start);
1742 } else if (!demux->have_group_id) {
1743 demux->have_group_id = TRUE;
1744 demux->group_id = gst_util_group_id_next ();
1747 stream_start = gst_event_new_stream_start (stream_id);
1749 if (demux->have_group_id)
1750 gst_event_set_group_id (stream_start, demux->group_id);
1751 stream_flags = GST_STREAM_FLAG_NONE;
1752 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1753 stream_flags |= GST_STREAM_FLAG_SPARSE;
1754 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1755 stream_flags |= GST_STREAM_FLAG_SELECT;
1756 else if (!(context->flags & GST_MATROSKA_TRACK_ENABLED))
1757 stream_flags |= GST_STREAM_FLAG_UNSELECT;
1759 gst_event_set_stream_flags (stream_start, stream_flags);
1760 gst_pad_push_event (context->pad, stream_start);
1761 gst_pad_set_caps (context->pad, context->caps);
1764 if (demux->common.global_tags) {
1765 GstEvent *tag_event;
1767 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1768 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1769 GST_DEBUG_OBJECT (context->pad, "Sending global_tags %p: %" GST_PTR_FORMAT,
1770 demux->common.global_tags, demux->common.global_tags);
1773 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1775 gst_pad_push_event (context->pad, tag_event);
1778 if (G_UNLIKELY (context->tags_changed)) {
1779 GST_DEBUG_OBJECT (context->pad, "Sending tags %p: %"
1780 GST_PTR_FORMAT, context->tags, context->tags);
1781 gst_pad_push_event (context->pad,
1782 gst_event_new_tag (gst_tag_list_copy (context->tags)));
1783 context->tags_changed = FALSE;
1786 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1787 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1793 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1796 gboolean res = FALSE;
1797 GstMatroskaTrackContext *context = NULL;
1800 context = gst_pad_get_element_private (pad);
1803 switch (GST_QUERY_TYPE (query)) {
1804 case GST_QUERY_POSITION:
1808 gst_query_parse_position (query, &format, NULL);
1811 if (format == GST_FORMAT_TIME) {
1812 GST_OBJECT_LOCK (demux);
1814 gst_query_set_position (query, GST_FORMAT_TIME,
1815 MAX (context->pos, demux->stream_start_time) -
1816 demux->stream_start_time);
1818 gst_query_set_position (query, GST_FORMAT_TIME,
1819 MAX (demux->common.segment.position, demux->stream_start_time) -
1820 demux->stream_start_time);
1821 GST_OBJECT_UNLOCK (demux);
1822 } else if (format == GST_FORMAT_DEFAULT && context
1823 && context->default_duration) {
1824 GST_OBJECT_LOCK (demux);
1825 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1826 context->pos / context->default_duration);
1827 GST_OBJECT_UNLOCK (demux);
1829 GST_DEBUG_OBJECT (demux,
1830 "only position query in TIME and DEFAULT format is supported");
1836 case GST_QUERY_DURATION:
1840 gst_query_parse_duration (query, &format, NULL);
1842 if (format == GST_FORMAT_TIME) {
1845 res = gst_pad_query_default (pad, GST_OBJECT_CAST (demux), query);
1847 GST_OBJECT_LOCK (demux);
1848 gst_query_set_duration (query, GST_FORMAT_TIME,
1849 demux->common.segment.duration);
1850 GST_OBJECT_UNLOCK (demux);
1854 } else if (format == GST_FORMAT_DEFAULT && context
1855 && context->default_duration) {
1858 GST_OBJECT_LOCK (demux);
1859 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1860 demux->common.segment.duration / context->default_duration);
1861 GST_OBJECT_UNLOCK (demux);
1863 GST_DEBUG_OBJECT (demux,
1864 "only duration query in TIME and DEFAULT format is supported");
1870 case GST_QUERY_SEEKING:
1874 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1875 if (fmt == GST_FORMAT_TIME) {
1878 res = gst_pad_query_default (pad, GST_OBJECT_CAST (demux), query);
1880 GST_OBJECT_LOCK (demux);
1881 if (demux->streaming) {
1882 /* assuming we'll be able to get an index ... */
1883 seekable = demux->seekable;
1888 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1889 0, demux->common.segment.duration);
1890 GST_OBJECT_UNLOCK (demux);
1897 case GST_QUERY_SEGMENT:
1902 format = demux->common.segment.format;
1905 gst_segment_to_stream_time (&demux->common.segment, format,
1906 demux->common.segment.start);
1907 if ((stop = demux->common.segment.stop) == -1)
1908 stop = demux->common.segment.duration;
1911 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1913 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1920 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1923 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1932 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1934 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1938 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1941 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1943 return gst_matroska_demux_query (demux, pad, query);
1946 /* returns FALSE if there are no pads to deliver event to,
1947 * otherwise TRUE (whatever the outcome of event sending),
1948 * takes ownership of the passed event! */
1950 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1952 gboolean ret = FALSE;
1955 g_return_val_if_fail (event != NULL, FALSE);
1957 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1958 GST_EVENT_TYPE_NAME (event));
1960 g_assert (demux->common.src->len == demux->common.num_streams);
1961 for (i = 0; i < demux->common.src->len; i++) {
1962 GstMatroskaTrackContext *stream;
1964 stream = g_ptr_array_index (demux->common.src, i);
1965 gst_event_ref (event);
1966 gst_pad_push_event (stream->pad, event);
1970 gst_event_unref (event);
1975 gst_matroska_demux_send_tags (GstMatroskaDemux * demux)
1979 if (G_UNLIKELY (demux->common.global_tags_changed)) {
1980 GstEvent *tag_event;
1981 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1982 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1983 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1984 demux->common.global_tags, demux->common.global_tags);
1987 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1989 for (i = 0; i < demux->common.src->len; i++) {
1990 GstMatroskaTrackContext *stream;
1992 stream = g_ptr_array_index (demux->common.src, i);
1993 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1996 gst_event_unref (tag_event);
1997 demux->common.global_tags_changed = FALSE;
2000 g_assert (demux->common.src->len == demux->common.num_streams);
2001 for (i = 0; i < demux->common.src->len; i++) {
2002 GstMatroskaTrackContext *stream;
2004 stream = g_ptr_array_index (demux->common.src, i);
2006 if (G_UNLIKELY (stream->tags_changed)) {
2007 GST_DEBUG_OBJECT (demux, "Sending tags %p for pad %s:%s : %"
2008 GST_PTR_FORMAT, stream->tags,
2009 GST_DEBUG_PAD_NAME (stream->pad), stream->tags);
2010 gst_pad_push_event (stream->pad,
2011 gst_event_new_tag (gst_tag_list_copy (stream->tags)));
2012 stream->tags_changed = FALSE;
2018 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
2020 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
2023 g_return_val_if_fail (event != NULL, FALSE);
2025 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
2026 /* no seeking until we are (safely) ready */
2027 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2028 GST_DEBUG_OBJECT (demux,
2029 "not ready for seeking yet, deferring seek: %" GST_PTR_FORMAT, event);
2030 if (demux->deferred_seek_event)
2031 gst_event_unref (demux->deferred_seek_event);
2032 demux->deferred_seek_event = event;
2033 demux->deferred_seek_pad = NULL;
2036 if (!demux->streaming)
2037 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
2039 res = gst_matroska_demux_handle_seek_push (demux, NULL, event);
2041 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
2042 GST_EVENT_TYPE_NAME (event));
2045 gst_event_unref (event);
2050 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
2051 GstMatroskaIndex * entry, gboolean reset, gboolean update)
2055 GST_OBJECT_LOCK (demux);
2058 /* seek (relative to matroska segment) */
2059 /* position might be invalid; will error when streaming resumes ... */
2060 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
2061 demux->next_cluster_offset = 0;
2063 GST_DEBUG_OBJECT (demux,
2064 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
2065 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
2066 entry->block, GST_TIME_ARGS (entry->time));
2068 /* update the time */
2069 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
2070 gst_flow_combiner_reset (demux->flowcombiner);
2071 demux->common.segment.position = entry->time;
2072 demux->seek_block = entry->block;
2073 demux->seek_first = TRUE;
2074 demux->last_stop_end = GST_CLOCK_TIME_NONE;
2077 for (i = 0; i < demux->common.src->len; i++) {
2078 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2081 stream->to_offset = G_MAXINT64;
2083 if (stream->from_offset != -1)
2084 stream->to_offset = stream->from_offset;
2086 stream->from_offset = -1;
2087 stream->from_time = GST_CLOCK_TIME_NONE;
2090 GST_OBJECT_UNLOCK (demux);
2096 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
2106 /* searches for a cluster start from @pos,
2107 * return GST_FLOW_OK and cluster position in @pos if found */
2108 static GstFlowReturn
2109 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos,
2112 gint64 newpos = *pos;
2114 GstFlowReturn ret = GST_FLOW_OK;
2115 const guint chunk = 128 * 1024;
2116 GstBuffer *buf = NULL;
2118 gpointer data = NULL;
2123 gint64 oldpos, oldlength;
2125 orig_offset = demux->common.offset;
2127 GST_LOG_OBJECT (demux, "searching cluster %s offset %" G_GINT64_FORMAT,
2128 forward ? "following" : "preceding", *pos);
2130 if (demux->clusters) {
2133 cpos = gst_util_array_binary_search (demux->clusters->data,
2134 demux->clusters->len, sizeof (gint64),
2135 (GCompareDataFunc) gst_matroska_cluster_compare,
2136 forward ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE, pos, NULL);
2139 GST_DEBUG_OBJECT (demux,
2140 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
2141 demux->common.offset = *cpos;
2142 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2143 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2144 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
2151 /* read in at newpos and scan for ebml cluster id */
2152 oldpos = oldlength = -1;
2154 GstByteReader reader;
2156 guint toread = chunk;
2159 /* never read beyond the requested target */
2160 if (G_UNLIKELY (newpos < chunk)) {
2168 gst_buffer_unmap (buf, &map);
2169 gst_buffer_unref (buf);
2172 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, toread, &buf);
2173 if (ret != GST_FLOW_OK)
2175 GST_DEBUG_OBJECT (demux,
2176 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
2177 gst_buffer_get_size (buf), newpos);
2178 gst_buffer_map (buf, &map, GST_MAP_READ);
2181 if (oldpos == newpos && oldlength == map.size) {
2182 GST_ERROR_OBJECT (demux, "Stuck at same position");
2183 ret = GST_FLOW_ERROR;
2187 oldlength = map.size;
2190 gst_byte_reader_init (&reader, data, size);
2193 gint found = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
2194 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
2196 cluster_pos = found;
2199 /* need last occurrence when searching backwards */
2201 cluster_pos = gst_byte_reader_get_pos (&reader) + found;
2202 gst_byte_reader_skip (&reader, found + 4);
2208 if (cluster_pos >= 0) {
2209 newpos += cluster_pos;
2210 GST_DEBUG_OBJECT (demux,
2211 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
2212 /* extra checks whether we really sync'ed to a cluster:
2213 * - either it is the first and only cluster
2214 * - either there is a cluster after this one
2215 * - either cluster length is undefined
2217 /* ok if first cluster (there may not a subsequent one) */
2218 if (newpos == demux->first_cluster_offset) {
2219 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
2222 demux->common.offset = newpos;
2223 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2224 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2225 if (ret != GST_FLOW_OK) {
2226 GST_DEBUG_OBJECT (demux, "need more data -> continue");
2229 g_assert (id == GST_MATROSKA_ID_CLUSTER);
2230 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
2232 /* ok if undefined length or first cluster */
2233 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
2234 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
2238 demux->common.offset += length + needed;
2239 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2240 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2241 if (ret != GST_FLOW_OK)
2243 GST_DEBUG_OBJECT (demux, "next element is %scluster",
2244 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
2245 if (id == GST_MATROSKA_ID_CLUSTER)
2251 /* partial cluster id may have been in tail of buffer */
2253 forward ? MAX (gst_byte_reader_get_remaining (&reader), 4) - 3 : 3;
2258 gst_buffer_unmap (buf, &map);
2259 gst_buffer_unref (buf);
2264 demux->common.offset = orig_offset;
2269 /* Three states to express: starts with I-frame, starts with delta, don't know */
2272 CLUSTER_STATUS_NONE = 0,
2273 CLUSTER_STATUS_STARTS_WITH_KEYFRAME,
2274 CLUSTER_STATUS_STARTS_WITH_DELTAUNIT,
2283 ClusterStatus status;
2286 static const gchar *
2287 cluster_status_get_nick (ClusterStatus status)
2290 case CLUSTER_STATUS_NONE:
2292 case CLUSTER_STATUS_STARTS_WITH_KEYFRAME:
2294 case CLUSTER_STATUS_STARTS_WITH_DELTAUNIT:
2300 /* Skip ebml-coded number:
2303 * 001x.. = 3 bytes, etc.
2306 bit_reader_skip_ebml_num (GstBitReader * br)
2310 if (!gst_bit_reader_peek_bits_uint8 (br, &v, 8))
2313 for (i = 0; i < 8; i++) {
2314 if ((v & (0x80 >> i)) != 0)
2317 return gst_bit_reader_skip (br, (i + 1) * 8);
2320 /* Don't probe more than that many bytes into the cluster for keyframe info
2321 * (random value, mostly for sanity checking) */
2322 #define MAX_CLUSTER_INFO_PROBE_LENGTH 256
2325 gst_matroska_demux_peek_cluster_info (GstMatroskaDemux * demux,
2326 ClusterInfo * cluster, guint64 offset)
2328 demux->common.offset = offset;
2329 demux->cluster_time = GST_CLOCK_TIME_NONE;
2331 cluster->offset = offset;
2333 cluster->prev_size = 0;
2334 cluster->time = GST_CLOCK_TIME_NONE;
2335 cluster->status = CLUSTER_STATUS_NONE;
2337 /* parse first few elements in cluster */
2344 flow = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2345 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2347 if (flow != GST_FLOW_OK)
2350 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2351 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
2354 /* Reached start of next cluster without finding data, stop processing */
2355 if (id == GST_MATROSKA_ID_CLUSTER && cluster->offset != offset)
2358 /* Not going to parse into these for now, stop processing */
2359 if (id == GST_MATROSKA_ID_ENCRYPTEDBLOCK
2360 || id == GST_MATROSKA_ID_BLOCKGROUP || id == GST_MATROSKA_ID_BLOCK)
2363 /* SimpleBlock: peek at headers to check if it's a keyframe */
2364 if (id == GST_MATROSKA_ID_SIMPLEBLOCK) {
2366 guint8 *d, hdr_len, v = 0;
2368 GST_DEBUG_OBJECT (demux, "SimpleBlock found");
2370 /* SimpleBlock header is max. 21 bytes */
2371 hdr_len = MIN (21, length);
2373 flow = gst_matroska_read_common_peek_bytes (&demux->common,
2374 demux->common.offset, hdr_len, NULL, &d);
2376 if (flow != GST_FLOW_OK)
2379 gst_bit_reader_init (&br, d, hdr_len);
2381 /* skip prefix: ebml id (SimpleBlock) + element length */
2382 if (!gst_bit_reader_skip (&br, 8 * needed))
2385 /* skip track number (ebml coded) */
2386 if (!bit_reader_skip_ebml_num (&br))
2390 if (!gst_bit_reader_skip (&br, 16))
2394 if (!gst_bit_reader_get_bits_uint8 (&br, &v, 8))
2397 if ((v & 0x80) != 0)
2398 cluster->status = CLUSTER_STATUS_STARTS_WITH_KEYFRAME;
2400 cluster->status = CLUSTER_STATUS_STARTS_WITH_DELTAUNIT;
2405 flow = gst_matroska_demux_parse_id (demux, id, length, needed);
2407 if (flow != GST_FLOW_OK)
2411 case GST_MATROSKA_ID_CLUSTER:
2412 if (length == G_MAXUINT64)
2415 cluster->size = length + needed;
2417 case GST_MATROSKA_ID_PREVSIZE:
2418 cluster->prev_size = demux->cluster_prevsize;
2420 case GST_MATROSKA_ID_CLUSTERTIMECODE:
2421 cluster->time = demux->cluster_time * demux->common.time_scale;
2423 case GST_MATROSKA_ID_SILENTTRACKS:
2424 case GST_EBML_ID_CRC32:
2425 /* ignore and continue */
2428 GST_WARNING_OBJECT (demux, "Unknown ebml id 0x%08x (possibly garbage), "
2432 } while (demux->common.offset - offset < MAX_CLUSTER_INFO_PROBE_LENGTH);
2436 GST_INFO_OBJECT (demux, "Cluster @ %" G_GUINT64_FORMAT ": "
2437 "time %" GST_TIME_FORMAT ", size %" G_GUINT64_FORMAT ", "
2438 "prev_size %" G_GUINT64_FORMAT ", %s", cluster->offset,
2439 GST_TIME_ARGS (cluster->time), cluster->size, cluster->prev_size,
2440 cluster_status_get_nick (cluster->status));
2442 /* return success as long as we could extract the minimum useful information */
2443 return cluster->time != GST_CLOCK_TIME_NONE;
2446 /* returns TRUE if the cluster offset was updated */
2448 gst_matroska_demux_scan_back_for_keyframe_cluster (GstMatroskaDemux * demux,
2449 gint64 * cluster_offset, GstClockTime * cluster_time)
2451 GstClockTime stream_start_time = demux->stream_start_time;
2452 guint64 first_cluster_offset = demux->first_cluster_offset;
2453 gint64 off = *cluster_offset;
2454 ClusterInfo cluster = { 0, };
2456 GST_INFO_OBJECT (demux, "Checking if cluster starts with keyframe");
2457 while (off > first_cluster_offset) {
2458 if (!gst_matroska_demux_peek_cluster_info (demux, &cluster, off)) {
2459 GST_LOG_OBJECT (demux,
2460 "Couldn't get info on cluster @ %" G_GUINT64_FORMAT, off);
2464 /* Keyframe? Then we're done */
2465 if (cluster.status == CLUSTER_STATUS_STARTS_WITH_KEYFRAME) {
2466 GST_LOG_OBJECT (demux,
2467 "Found keyframe at start of cluster @ %" G_GUINT64_FORMAT, off);
2471 /* We only scan back if we *know* we landed on a cluster that
2472 * starts with a delta frame. */
2473 if (cluster.status != CLUSTER_STATUS_STARTS_WITH_DELTAUNIT) {
2474 GST_LOG_OBJECT (demux,
2475 "No delta frame at start of cluster @ %" G_GUINT64_FORMAT, off);
2479 GST_DEBUG_OBJECT (demux, "Cluster starts with delta frame, backtracking");
2481 /* Don't scan back more than this much in time from the cluster we
2482 * originally landed on. This is mostly a sanity check in case a file
2483 * always has keyframes in the middle of clusters and never at the
2484 * beginning. Without this we would always scan back to the beginning
2485 * of the file in that case. */
2486 if (cluster.time != GST_CLOCK_TIME_NONE) {
2487 GstClockTimeDiff distance = GST_CLOCK_DIFF (cluster.time, *cluster_time);
2489 if (distance < 0 || distance > demux->max_backtrack_distance * GST_SECOND) {
2490 GST_DEBUG_OBJECT (demux, "Haven't found cluster with keyframe within "
2491 "%u secs of original seek target cluster, stopping",
2492 demux->max_backtrack_distance);
2497 /* If we have cluster prev_size we can skip back efficiently. If not,
2498 * we'll just do a brute force search for a cluster identifier */
2499 if (cluster.prev_size > 0 && off >= cluster.prev_size) {
2500 off -= cluster.prev_size;
2504 GST_LOG_OBJECT (demux, "Cluster has no or invalid prev size, searching "
2505 "for previous cluster instead then");
2507 flow = gst_matroska_demux_search_cluster (demux, &off, FALSE);
2508 if (flow != GST_FLOW_OK) {
2509 GST_DEBUG_OBJECT (demux, "cluster search yielded flow %s, stopping",
2510 gst_flow_get_name (flow));
2515 if (off <= first_cluster_offset) {
2516 GST_LOG_OBJECT (demux, "Reached first cluster, stopping");
2517 *cluster_offset = first_cluster_offset;
2518 *cluster_time = stream_start_time;
2521 GST_LOG_OBJECT (demux, "Trying prev cluster @ %" G_GUINT64_FORMAT, off);
2524 /* If we found a cluster starting with a keyframe jump to that instead,
2525 * otherwise leave everything as it was before */
2526 if (cluster.time != GST_CLOCK_TIME_NONE
2527 && (cluster.offset == first_cluster_offset
2528 || cluster.status == CLUSTER_STATUS_STARTS_WITH_KEYFRAME)) {
2529 *cluster_offset = cluster.offset;
2530 *cluster_time = cluster.time;
2537 /* bisect and scan through file for cluster starting before @time,
2538 * returns fake index entry with corresponding info on cluster */
2539 static GstMatroskaIndex *
2540 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
2542 GstMatroskaIndex *entry = NULL;
2543 GstMatroskaReadState current_state;
2544 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
2546 gint64 opos, newpos, current_offset;
2547 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
2548 gint64 apos, maxpos;
2549 guint64 cluster_size = 0;
2555 /* estimate new position, resync using cluster ebml id,
2556 * and bisect further or scan forward to appropriate cluster */
2558 /* save some current global state which will be touched by our scanning */
2559 current_state = demux->common.state;
2560 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
2562 current_cluster_offset = demux->cluster_offset;
2563 current_cluster_time = demux->cluster_time;
2564 current_offset = demux->common.offset;
2566 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
2568 /* estimate using start and last known cluster */
2569 GST_OBJECT_LOCK (demux);
2570 apos = demux->first_cluster_offset;
2571 atime = demux->stream_start_time;
2572 opos = demux->last_cluster_offset;
2573 otime = demux->stream_last_time;
2574 GST_OBJECT_UNLOCK (demux);
2577 time = MAX (time, atime);
2578 otime = MAX (otime, atime);
2579 opos = MAX (opos, apos);
2581 maxpos = gst_matroska_read_common_get_length (&demux->common);
2586 * apos always refer to a cluster before target time;
2587 * opos may or may not be after target time, but if it is once so,
2588 * then also in next iteration
2592 GST_LOG_OBJECT (demux,
2593 "apos: %" G_GUINT64_FORMAT ", atime: %" GST_TIME_FORMAT ", %"
2594 GST_TIME_FORMAT " in stream time, "
2595 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
2596 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
2597 GST_TIME_FORMAT, apos, GST_TIME_ARGS (atime),
2598 GST_TIME_ARGS (atime - demux->stream_start_time), opos,
2599 GST_TIME_ARGS (otime), GST_TIME_ARGS (otime - demux->stream_start_time),
2600 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
2602 g_assert (atime <= otime);
2603 g_assert (apos <= opos);
2604 if (time == GST_CLOCK_TIME_NONE) {
2605 GST_DEBUG_OBJECT (demux, "searching last cluster");
2608 GST_DEBUG_OBJECT (demux, "unknown file size; bailing out");
2611 } else if (otime <= atime) {
2615 gst_util_uint64_scale (opos - apos, time - atime, otime - atime);
2616 if (maxpos != -1 && newpos > maxpos)
2620 GST_DEBUG_OBJECT (demux,
2621 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
2622 GST_TIME_ARGS (time), newpos);
2624 /* search backwards */
2625 if (newpos > apos) {
2626 ret = gst_matroska_demux_search_cluster (demux, &newpos, FALSE);
2627 if (ret != GST_FLOW_OK)
2631 /* then start scanning and parsing for cluster time,
2632 * re-estimate if possible, otherwise next cluster and so on */
2633 /* note that each re-estimate is entered with a change in apos or opos,
2634 * avoiding infinite loop */
2635 demux->common.offset = newpos;
2636 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
2638 prev_cluster_time = GST_CLOCK_TIME_NONE;
2640 /* peek and parse some elements */
2641 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2642 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2643 if (ret != GST_FLOW_OK)
2645 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2646 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
2648 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
2649 if (ret != GST_FLOW_OK)
2652 if (id == GST_MATROSKA_ID_CLUSTER) {
2653 cluster_time = GST_CLOCK_TIME_NONE;
2654 if (length == G_MAXUINT64)
2657 cluster_size = length + needed;
2659 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
2660 cluster_time == GST_CLOCK_TIME_NONE) {
2661 cluster_time = demux->cluster_time * demux->common.time_scale;
2662 cluster_offset = demux->cluster_offset;
2663 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
2664 " with time %" GST_TIME_FORMAT, cluster_offset,
2665 GST_TIME_ARGS (cluster_time));
2666 if (time == GST_CLOCK_TIME_NONE) {
2667 GST_DEBUG_OBJECT (demux, "found last cluster");
2668 prev_cluster_time = cluster_time;
2669 prev_cluster_offset = cluster_offset;
2672 if (cluster_time > time) {
2673 GST_DEBUG_OBJECT (demux, "overshot target");
2674 /* cluster overshoots */
2675 if (cluster_offset == demux->first_cluster_offset) {
2676 /* but no prev one */
2677 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
2678 prev_cluster_time = cluster_time;
2679 prev_cluster_offset = cluster_offset;
2682 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
2683 /* prev cluster did not overshoot, so prev cluster is target */
2686 /* re-estimate using this new position info */
2687 opos = cluster_offset;
2688 otime = cluster_time;
2692 /* cluster undershoots */
2693 GST_DEBUG_OBJECT (demux, "undershot target");
2694 /* ok if close enough */
2695 if (GST_CLOCK_DIFF (cluster_time, time) < 5 * GST_SECOND) {
2696 GST_DEBUG_OBJECT (demux, "target close enough");
2697 prev_cluster_time = cluster_time;
2698 prev_cluster_offset = cluster_offset;
2702 /* we are in between atime and otime => can bisect if worthwhile */
2703 if (prev_cluster_time != GST_CLOCK_TIME_NONE &&
2704 cluster_time > prev_cluster_time &&
2705 (GST_CLOCK_DIFF (prev_cluster_time, cluster_time) * 10 <
2706 GST_CLOCK_DIFF (cluster_time, time))) {
2707 /* we moved at least one cluster forward,
2708 * and it looks like target is still far away,
2709 * let's estimate again */
2710 GST_DEBUG_OBJECT (demux, "bisecting with new apos");
2711 apos = cluster_offset;
2712 atime = cluster_time;
2716 /* cluster undershoots, goto next one */
2717 prev_cluster_time = cluster_time;
2718 prev_cluster_offset = cluster_offset;
2719 /* skip cluster if length is defined,
2720 * otherwise will be skippingly parsed into */
2722 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
2723 demux->common.offset = cluster_offset + cluster_size;
2724 demux->cluster_time = GST_CLOCK_TIME_NONE;
2726 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
2733 if (ret == GST_FLOW_EOS) {
2734 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
2740 /* In the bisect loop above we always undershoot and then jump forward
2741 * cluster-by-cluster until we overshoot, so if we get here we've gone
2742 * over and the previous cluster is where we need to go to. */
2743 cluster_offset = prev_cluster_offset;
2744 cluster_time = prev_cluster_time;
2746 /* If we have video and can easily backtrack, check if we landed on a cluster
2747 * that starts with a keyframe - and if not backtrack until we find one that
2749 if (demux->have_nonintraonly_v_streams && demux->max_backtrack_distance > 0) {
2750 if (gst_matroska_demux_scan_back_for_keyframe_cluster (demux,
2751 &cluster_offset, &cluster_time)) {
2752 GST_INFO_OBJECT (demux, "Adjusted cluster to %" GST_TIME_FORMAT " @ "
2753 "%" G_GUINT64_FORMAT, GST_TIME_ARGS (cluster_time), cluster_offset);
2757 entry = g_new0 (GstMatroskaIndex, 1);
2758 entry->time = cluster_time;
2759 entry->pos = cluster_offset - demux->common.ebml_segment_start;
2760 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
2761 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
2765 /* restore some state */
2766 demux->cluster_offset = current_cluster_offset;
2767 demux->cluster_time = current_cluster_time;
2768 demux->common.offset = current_offset;
2769 demux->common.state = current_state;
2775 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
2776 GstPad * pad, GstEvent * event)
2778 GstMatroskaIndex *entry = NULL;
2779 GstMatroskaIndex scan_entry;
2781 GstSeekType cur_type, stop_type;
2783 gboolean flush, keyunit, instant_rate_change, before, after, accurate,
2787 GstMatroskaTrackContext *track = NULL;
2788 GstSegment seeksegment = { 0, };
2790 gboolean update = TRUE;
2791 gboolean pad_locked = FALSE;
2793 GstSearchMode snap_dir;
2795 g_return_val_if_fail (event != NULL, FALSE);
2798 track = gst_pad_get_element_private (pad);
2800 GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
2802 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2804 seqnum = gst_event_get_seqnum (event);
2806 /* we can only seek on time */
2807 if (format != GST_FORMAT_TIME) {
2808 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2812 GST_DEBUG_OBJECT (demux, "configuring seek");
2814 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2815 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2816 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
2817 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
2818 accurate = ! !(flags & GST_SEEK_FLAG_ACCURATE);
2819 instant_rate_change = ! !(flags & GST_SEEK_FLAG_INSTANT_RATE_CHANGE);
2821 /* Directly send the instant-rate-change event here before taking the
2822 * stream-lock so that it can be applied as soon as possible */
2823 if (instant_rate_change) {
2826 /* instant rate change only supported if direction does not change. All
2827 * other requirements are already checked before creating the seek event
2828 * but let's double-check here to be sure */
2829 if ((rate > 0 && demux->common.segment.rate < 0) ||
2830 (rate < 0 && demux->common.segment.rate > 0) ||
2831 cur_type != GST_SEEK_TYPE_NONE ||
2832 stop_type != GST_SEEK_TYPE_NONE || flush) {
2833 GST_ERROR_OBJECT (demux,
2834 "Instant rate change seeks only supported in the "
2835 "same direction, without flushing and position change");
2839 ev = gst_event_new_instant_rate_change (rate /
2840 demux->common.segment.rate, (GstSegmentFlags) flags);
2841 gst_event_set_seqnum (ev, seqnum);
2842 gst_matroska_demux_send_event (demux, ev);
2846 /* copy segment, we need this because we still need the old
2847 * segment when we close the current segment. */
2848 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
2850 /* pull mode without index means that the actual duration is not known,
2851 * we might be playing a file that's still being recorded
2852 * so, invalidate our current duration, which is only a moving target,
2853 * and should not be used to clamp anything */
2854 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
2855 seeksegment.duration = GST_CLOCK_TIME_NONE;
2858 /* Subtract stream_start_time so we always seek on a segment
2860 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2861 seeksegment.start -= demux->stream_start_time;
2862 seeksegment.position -= demux->stream_start_time;
2863 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2864 seeksegment.stop -= demux->stream_start_time;
2866 seeksegment.stop = seeksegment.duration;
2869 if (!gst_segment_do_seek (&seeksegment, rate, format, flags,
2870 cur_type, cur, stop_type, stop, &update)) {
2871 GST_WARNING_OBJECT (demux, "gst_segment_do_seek() failed.");
2875 /* Restore the clip timestamp offset */
2876 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2877 seeksegment.position += demux->stream_start_time;
2878 seeksegment.start += demux->stream_start_time;
2879 if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2880 seeksegment.stop = seeksegment.duration;
2881 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2882 seeksegment.stop += demux->stream_start_time;
2885 /* restore segment duration (if any effect),
2886 * would be determined again when parsing, but anyway ... */
2887 seeksegment.duration = demux->common.segment.duration;
2889 /* always do full update if flushing,
2890 * otherwise problems might arise downstream with missing keyframes etc */
2891 update = update || flush;
2893 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2895 /* check sanity before we start flushing and all that */
2896 snap_next = after && !before;
2897 if (seeksegment.rate < 0)
2898 snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
2900 snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
2902 GST_OBJECT_LOCK (demux);
2904 seekpos = seeksegment.position;
2906 seekpos -= MIN (seeksegment.position, demux->audio_lead_in_ts);
2909 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2910 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2911 seekpos, &demux->seek_index, &demux->seek_entry,
2912 snap_dir)) == NULL) {
2913 /* pull mode without index can scan later on */
2914 if (demux->streaming) {
2915 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2916 GST_OBJECT_UNLOCK (demux);
2918 } else if (rate < 0.0) {
2919 /* FIXME: We should build an index during playback or when scanning
2920 * that can be used here. The reverse playback code requires seek_index
2921 * and seek_entry to be set!
2923 GST_DEBUG_OBJECT (demux,
2924 "No matching seek entry in index, needed for reverse playback");
2925 GST_OBJECT_UNLOCK (demux);
2929 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2930 GST_OBJECT_UNLOCK (demux);
2933 /* only have to update some segment,
2934 * but also still have to honour flush and so on */
2935 GST_DEBUG_OBJECT (demux, "... no update");
2936 /* bad goto, bad ... */
2940 if (demux->streaming)
2945 GstEvent *flush_event = gst_event_new_flush_start ();
2946 gst_event_set_seqnum (flush_event, seqnum);
2947 GST_DEBUG_OBJECT (demux, "Starting flush");
2948 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2949 gst_matroska_demux_send_event (demux, flush_event);
2951 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2952 gst_pad_pause_task (demux->common.sinkpad);
2956 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2961 /* now grab the stream lock so that streaming cannot continue, for
2962 * non flushing seeks when the element is in PAUSED this could block
2964 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2965 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2968 /* pull mode without index can do some scanning */
2969 if (!demux->streaming && !entry) {
2970 GstEvent *flush_event;
2972 /* need to stop flushing upstream as we need it next */
2974 flush_event = gst_event_new_flush_stop (TRUE);
2975 gst_event_set_seqnum (flush_event, seqnum);
2976 gst_pad_push_event (demux->common.sinkpad, flush_event);
2978 entry = gst_matroska_demux_search_pos (demux, seekpos);
2979 /* keep local copy */
2981 scan_entry = *entry;
2983 entry = &scan_entry;
2985 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2987 flush_event = gst_event_new_flush_stop (TRUE);
2988 gst_event_set_seqnum (flush_event, seqnum);
2989 gst_matroska_demux_send_event (demux, flush_event);
2996 if (keyunit && seeksegment.rate > 0) {
2997 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2998 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2999 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
3000 seeksegment.start = MAX (entry->time, demux->stream_start_time);
3001 seeksegment.position = seeksegment.start;
3002 seeksegment.time = seeksegment.start - demux->stream_start_time;
3003 } else if (keyunit) {
3004 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment stop from %"
3005 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
3006 GST_TIME_ARGS (seeksegment.stop), GST_TIME_ARGS (entry->time));
3007 seeksegment.stop = MAX (entry->time, demux->stream_start_time);
3008 seeksegment.position = seeksegment.stop;
3011 if (demux->streaming) {
3012 GST_OBJECT_LOCK (demux);
3013 /* track real position we should start at */
3014 GST_DEBUG_OBJECT (demux, "storing segment start");
3015 demux->requested_seek_time = seeksegment.position;
3016 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
3017 GST_OBJECT_UNLOCK (demux);
3018 /* need to seek to cluster start to pick up cluster time */
3019 /* upstream takes care of flushing and all that
3020 * ... and newsegment event handling takes care of the rest */
3021 return perform_seek_to_offset (demux, rate,
3022 entry->pos + demux->common.ebml_segment_start, seqnum, flags);
3027 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
3028 gst_event_set_seqnum (flush_event, seqnum);
3029 GST_DEBUG_OBJECT (demux, "Stopping flush");
3030 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
3031 gst_matroska_demux_send_event (demux, flush_event);
3034 GST_OBJECT_LOCK (demux);
3035 /* now update the real segment info */
3036 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
3037 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
3038 GST_OBJECT_UNLOCK (demux);
3040 /* update some (segment) state */
3041 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
3044 /* notify start of new segment */
3045 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
3048 msg = gst_message_new_segment_start (GST_OBJECT (demux),
3049 GST_FORMAT_TIME, demux->common.segment.start);
3050 gst_message_set_seqnum (msg, seqnum);
3051 gst_element_post_message (GST_ELEMENT (demux), msg);
3054 GST_OBJECT_LOCK (demux);
3055 if (demux->new_segment)
3056 gst_event_unref (demux->new_segment);
3058 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
3059 demux->new_segment = gst_event_new_segment (&demux->common.segment);
3060 gst_event_set_seqnum (demux->new_segment, seqnum);
3061 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
3062 demux->to_time = demux->common.segment.position;
3064 demux->to_time = GST_CLOCK_TIME_NONE;
3065 demux->segment_seqnum = seqnum;
3066 GST_OBJECT_UNLOCK (demux);
3068 /* restart our task since it might have been stopped when we did the
3070 gst_pad_start_task (demux->common.sinkpad,
3071 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
3073 /* streaming can continue now */
3075 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
3083 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
3085 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
3091 * Handle whether we can perform the seek event or if we have to let the chain
3092 * function handle seeks to build the seek indexes first.
3095 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
3099 GstSeekType cur_type, stop_type;
3104 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
3107 /* Directly send the instant-rate-change event here before taking the
3108 * stream-lock so that it can be applied as soon as possible */
3109 if (flags & GST_SEEK_FLAG_INSTANT_RATE_CHANGE) {
3113 /* instant rate change only supported if direction does not change. All
3114 * other requirements are already checked before creating the seek event
3115 * but let's double-check here to be sure */
3116 if ((rate > 0 && demux->common.segment.rate < 0) ||
3117 (rate < 0 && demux->common.segment.rate > 0) ||
3118 cur_type != GST_SEEK_TYPE_NONE ||
3119 stop_type != GST_SEEK_TYPE_NONE || (flags & GST_SEEK_FLAG_FLUSH)) {
3120 GST_ERROR_OBJECT (demux,
3121 "Instant rate change seeks only supported in the "
3122 "same direction, without flushing and position change");
3126 seqnum = gst_event_get_seqnum (event);
3127 ev = gst_event_new_instant_rate_change (rate / demux->common.segment.rate,
3128 (GstSegmentFlags) flags);
3129 gst_event_set_seqnum (ev, seqnum);
3130 gst_matroska_demux_send_event (demux, ev);
3138 /* we can only seek on time */
3139 if (format != GST_FORMAT_TIME) {
3140 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
3144 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
3145 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
3149 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
3150 GST_DEBUG_OBJECT (demux,
3151 "Non-flushing seek not supported in streaming mode");
3155 if (flags & GST_SEEK_FLAG_SEGMENT) {
3156 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
3160 /* check for having parsed index already */
3161 if (!demux->common.index_parsed) {
3162 gboolean building_index;
3165 if (!demux->index_offset) {
3166 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
3170 GST_OBJECT_LOCK (demux);
3171 /* handle the seek event in the chain function */
3172 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
3173 /* no more seek can be issued until state reset to _DATA */
3175 /* copy the event */
3176 if (demux->seek_event)
3177 gst_event_unref (demux->seek_event);
3178 demux->seek_event = gst_event_ref (event);
3180 /* set the building_index flag so that only one thread can setup the
3181 * structures for index seeking. */
3182 building_index = demux->building_index;
3183 if (!building_index) {
3184 demux->building_index = TRUE;
3185 offset = demux->index_offset;
3187 GST_OBJECT_UNLOCK (demux);
3189 if (!building_index) {
3190 /* seek to the first subindex or legacy index */
3191 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
3192 return perform_seek_to_offset (demux, rate, offset,
3193 gst_event_get_seqnum (event), GST_SEEK_FLAG_NONE);
3196 /* well, we are handling it already */
3200 /* delegate to tweaked regular seek */
3201 return gst_matroska_demux_handle_seek_event (demux, pad, event);
3205 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
3208 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
3209 gboolean res = TRUE;
3211 switch (GST_EVENT_TYPE (event)) {
3212 case GST_EVENT_SEEK:
3213 /* no seeking until we are (safely) ready */
3214 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
3215 GST_DEBUG_OBJECT (demux,
3216 "not ready for seeking yet, deferring seek event: %" GST_PTR_FORMAT,
3218 if (demux->deferred_seek_event)
3219 gst_event_unref (demux->deferred_seek_event);
3220 demux->deferred_seek_event = event;
3221 demux->deferred_seek_pad = pad;
3226 guint32 seqnum = gst_event_get_seqnum (event);
3227 if (seqnum == demux->segment_seqnum) {
3228 GST_LOG_OBJECT (pad,
3229 "Drop duplicated SEEK event seqnum %" G_GUINT32_FORMAT, seqnum);
3230 gst_event_unref (event);
3235 if (!demux->streaming)
3236 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
3238 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
3239 gst_event_unref (event);
3244 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
3245 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3246 GstMatroskaTrackVideoContext *videocontext =
3247 (GstMatroskaTrackVideoContext *) context;
3249 GstClockTimeDiff diff;
3250 GstClockTime timestamp;
3252 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
3254 GST_OBJECT_LOCK (demux);
3255 videocontext->earliest_time = timestamp + diff;
3256 GST_OBJECT_UNLOCK (demux);
3259 gst_event_unref (event);
3263 case GST_EVENT_TOC_SELECT:
3266 GstTocEntry *entry = NULL;
3267 GstEvent *seek_event;
3270 if (!demux->common.toc) {
3271 GST_DEBUG_OBJECT (demux, "no TOC to select");
3274 gst_event_parse_toc_select (event, &uid);
3276 GST_OBJECT_LOCK (demux);
3277 entry = gst_toc_find_entry (demux->common.toc, uid);
3278 if (entry == NULL) {
3279 GST_OBJECT_UNLOCK (demux);
3280 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
3283 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
3284 GST_OBJECT_UNLOCK (demux);
3285 seek_event = gst_event_new_seek (1.0,
3287 GST_SEEK_FLAG_FLUSH,
3288 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
3289 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
3290 gst_event_unref (seek_event);
3294 GST_WARNING_OBJECT (demux, "received empty TOC select event");
3298 gst_event_unref (event);
3302 /* events we don't need to handle */
3303 case GST_EVENT_NAVIGATION:
3304 gst_event_unref (event);
3308 case GST_EVENT_LATENCY:
3310 res = gst_pad_push_event (demux->common.sinkpad, event);
3318 gst_matroska_demux_handle_sink_query (GstPad * pad, GstObject * parent,
3321 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
3322 gboolean res = FALSE;
3324 switch (GST_QUERY_TYPE (query)) {
3325 case GST_QUERY_BITRATE:
3327 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
3328 demux->common.offset >= demux->cached_length)) {
3329 demux->cached_length =
3330 gst_matroska_read_common_get_length (&demux->common);
3333 if (demux->cached_length < G_MAXUINT64
3334 && demux->common.segment.duration > 0) {
3335 /* TODO: better results based on ranges/index tables */
3337 gst_util_uint64_scale (8 * demux->cached_length, GST_SECOND,
3338 demux->common.segment.duration);
3340 GST_LOG_OBJECT (demux, "bitrate query byte length: %" G_GUINT64_FORMAT
3341 " duration %" GST_TIME_FORMAT " resulting in a bitrate of %u",
3342 demux->cached_length,
3343 GST_TIME_ARGS (demux->common.segment.duration), bitrate);
3345 gst_query_set_bitrate (query, bitrate);
3351 res = gst_pad_query_default (pad, (GstObject *) demux, query);
3358 static GstFlowReturn
3359 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
3361 GstFlowReturn ret = GST_FLOW_EOS;
3362 gboolean done = TRUE;
3365 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
3366 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
3369 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
3371 if (!demux->seek_entry) {
3372 GST_DEBUG_OBJECT (demux, "no earlier index entry");
3376 for (i = 0; i < demux->common.src->len; i++) {
3377 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
3379 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
3380 ", stream %d at %" GST_TIME_FORMAT,
3381 GST_TIME_ARGS (demux->common.segment.start), stream->index,
3382 GST_TIME_ARGS (stream->from_time));
3383 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
3384 if (stream->from_time > demux->common.segment.start) {
3385 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
3389 /* nothing pushed for this stream;
3390 * likely seek entry did not start at keyframe, so all was skipped.
3391 * So we need an earlier entry */
3397 GstMatroskaIndex *entry;
3399 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
3400 --demux->seek_entry);
3401 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
3411 static GstFlowReturn
3412 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3414 GstFlowReturn ret = GST_FLOW_OK;
3416 guint64 ebml_offset = ebml->offset;
3418 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
3420 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3421 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3425 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3426 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3430 /* one track within the "all-tracks" header */
3431 case GST_MATROSKA_ID_TRACKENTRY:{
3432 GstMatroskaTrackContext *track;
3433 ret = gst_matroska_demux_parse_stream (demux, ebml, &track);
3434 if (track != NULL) {
3435 if (gst_matroska_read_common_tracknumber_unique (&demux->common,
3437 gst_matroska_demux_add_stream (demux, track);
3439 GST_ERROR_OBJECT (demux,
3440 "TrackNumber %" G_GUINT64_FORMAT " is not unique", track->num);
3441 ret = GST_FLOW_ERROR;
3442 gst_matroska_track_free (track);
3450 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3455 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3457 demux->tracks_ebml_offset = ebml_offset;
3458 GST_DEBUG_OBJECT (demux, "signaling no more pads");
3459 gst_element_no_more_pads (GST_ELEMENT (demux));
3464 static GstFlowReturn
3465 gst_matroska_demux_update_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3467 GstFlowReturn ret = GST_FLOW_OK;
3468 guint num_tracks_found = 0;
3471 GST_INFO_OBJECT (demux, "Reparsing Tracks element");
3473 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
3475 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3476 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3480 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3481 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3485 /* one track within the "all-tracks" header */
3486 case GST_MATROSKA_ID_TRACKENTRY:{
3487 GstMatroskaTrackContext *new_track;
3488 gint old_track_index;
3489 GstMatroskaTrackContext *old_track;
3490 ret = gst_matroska_demux_parse_stream (demux, ebml, &new_track);
3491 if (new_track == NULL)
3495 if (gst_matroska_read_common_tracknumber_unique (&demux->common,
3497 GST_ERROR_OBJECT (demux,
3498 "Unexpected new TrackNumber: %" G_GUINT64_FORMAT, new_track->num);
3499 goto track_mismatch_error;
3503 gst_matroska_read_common_stream_from_num (&demux->common,
3505 g_assert (old_track_index != -1);
3506 old_track = g_ptr_array_index (demux->common.src, old_track_index);
3508 if (old_track->type != new_track->type) {
3509 GST_ERROR_OBJECT (demux,
3510 "Mismatch reparsing track %" G_GUINT64_FORMAT
3511 " on track type. Expected %d, found %d", new_track->num,
3512 old_track->type, new_track->type);
3513 goto track_mismatch_error;
3516 if (g_strcmp0 (old_track->codec_id, new_track->codec_id) != 0) {
3517 GST_ERROR_OBJECT (demux,
3518 "Mismatch reparsing track %" G_GUINT64_FORMAT
3519 " on codec id. Expected '%s', found '%s'", new_track->num,
3520 old_track->codec_id, new_track->codec_id);
3521 goto track_mismatch_error;
3524 /* The new track matches the old track. No problems on our side.
3525 * Let's make it replace the old track. */
3526 new_track->pad = old_track->pad;
3527 new_track->index = old_track->index;
3528 new_track->pos = old_track->pos;
3530 /* If index table is empty, do not ref it, we will try to fallback
3531 * to the generic one from read-common in such case */
3532 if (old_track->index_table && old_track->index_table->len > 0)
3533 new_track->index_table = g_array_ref (old_track->index_table);
3535 g_ptr_array_index (demux->common.src, old_track_index) = new_track;
3536 gst_pad_set_element_private (new_track->pad, new_track);
3538 if (!gst_caps_is_equal (old_track->caps, new_track->caps)) {
3539 gst_pad_set_caps (new_track->pad, new_track->caps);
3541 gst_caps_replace (&old_track->caps, NULL);
3543 if (!gst_tag_list_is_equal (old_track->tags, new_track->tags)) {
3544 GST_DEBUG_OBJECT (old_track->pad, "Sending tags %p: %"
3545 GST_PTR_FORMAT, new_track->tags, new_track->tags);
3546 gst_pad_push_event (new_track->pad,
3547 gst_event_new_tag (gst_tag_list_copy (new_track->tags)));
3550 gst_matroska_track_free (old_track);
3553 track_mismatch_error:
3554 gst_matroska_track_free (new_track);
3556 ret = GST_FLOW_ERROR;
3561 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3566 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3568 if (ret != GST_FLOW_ERROR && demux->common.num_streams != num_tracks_found) {
3569 GST_ERROR_OBJECT (demux,
3570 "Mismatch on the number of tracks. Expected %du tracks, found %du",
3571 demux->common.num_streams, num_tracks_found);
3572 ret = GST_FLOW_ERROR;
3579 * Read signed/unsigned "EBML" numbers.
3580 * Return: number of bytes processed.
3584 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
3586 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
3594 while (read <= 8 && !(total & len_mask)) {
3601 if ((total &= (len_mask - 1)) == len_mask - 1)
3606 if (data[n] == 0xff)
3608 total = (total << 8) | data[n];
3612 if (read == num_ffs && total != 0)
3621 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
3626 /* read as unsigned number first */
3627 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
3631 if (unum == G_MAXUINT64)
3634 *num = unum - ((1 << ((7 * res) - 1)) - 1);
3640 * Mostly used for subtitles. We add void filler data for each
3641 * lagging stream to make sure we don't deadlock.
3645 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
3647 GstClockTime gap_threshold;
3650 GST_OBJECT_LOCK (demux);
3652 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
3653 GST_TIME_ARGS (demux->common.segment.position));
3655 g_assert (demux->common.num_streams == demux->common.src->len);
3656 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
3657 GstMatroskaTrackContext *context;
3659 context = g_ptr_array_index (demux->common.src, stream_nr);
3661 GST_LOG_OBJECT (demux,
3662 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
3663 GST_TIME_ARGS (context->pos));
3665 /* Only send gap events on non-subtitle streams if lagging way behind.
3666 * The 0.5 second threshold for subtitle streams is also quite random. */
3667 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
3668 gap_threshold = GST_SECOND / 2;
3670 gap_threshold = 3 * GST_SECOND;
3672 /* Lag need only be considered if we have advanced into requested segment */
3673 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
3674 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3675 demux->common.segment.position > demux->common.segment.start &&
3676 context->pos + gap_threshold < demux->common.segment.position) {
3679 guint64 start = context->pos;
3680 guint64 stop = demux->common.segment.position - gap_threshold;
3682 GST_DEBUG_OBJECT (demux,
3683 "Synchronizing stream %d with other by advancing time from %"
3684 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
3685 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
3687 context->pos = stop;
3689 event = gst_event_new_gap (start, stop - start);
3690 GST_OBJECT_UNLOCK (demux);
3691 gst_pad_push_event (context->pad, event);
3692 GST_OBJECT_LOCK (demux);
3696 GST_OBJECT_UNLOCK (demux);
3699 static GstFlowReturn
3700 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
3701 GstMatroskaTrackContext * stream)
3703 GstFlowReturn ret = GST_FLOW_OK;
3706 num = gst_buffer_list_length (stream->stream_headers);
3707 for (i = 0; i < num; ++i) {
3710 buf = gst_buffer_list_get (stream->stream_headers, i);
3711 buf = gst_buffer_copy (buf);
3713 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
3715 if (stream->set_discont) {
3716 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
3717 stream->set_discont = FALSE;
3719 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
3722 /* push out all headers in one go and use last flow return */
3723 ret = gst_pad_push (stream->pad, buf);
3726 /* don't need these any longer */
3727 gst_buffer_list_unref (stream->stream_headers);
3728 stream->stream_headers = NULL;
3731 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3737 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
3738 GstMatroskaTrackContext * stream)
3742 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
3744 if (!stream->codec_priv)
3747 /* ideally, VobSub private data should be parsed and stored more convenient
3748 * elsewhere, but for now, only interested in a small part */
3750 /* make sure we have terminating 0 */
3751 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
3753 /* just locate and parse palette part */
3754 start = strstr (buf, "palette:");
3759 guint8 r, g, b, y, u, v;
3762 while (g_ascii_isspace (*start))
3764 for (i = 0; i < 16; i++) {
3765 if (sscanf (start, "%06x", &col) != 1)
3768 while ((*start == ',') || g_ascii_isspace (*start))
3770 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
3771 r = (col >> 16) & 0xff;
3772 g = (col >> 8) & 0xff;
3774 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
3776 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
3777 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
3778 clut[i] = (y << 16) | (u << 8) | v;
3781 /* got them all without problems; build and send event */
3785 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
3786 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
3787 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
3788 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
3789 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
3790 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
3791 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
3792 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
3793 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
3794 G_TYPE_INT, clut[15], NULL);
3796 gst_pad_push_event (stream->pad,
3797 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
3804 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
3808 g_assert (demux->common.num_streams == demux->common.src->len);
3809 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
3810 GstMatroskaTrackContext *stream;
3812 stream = g_ptr_array_index (demux->common.src, stream_nr);
3814 if (stream->send_stream_headers) {
3815 if (stream->stream_headers != NULL) {
3816 gst_matroska_demux_push_stream_headers (demux, stream);
3818 /* FIXME: perhaps we can just disable and skip this stream then */
3819 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
3820 ("Failed to extract stream headers from codec private data"));
3822 stream->send_stream_headers = FALSE;
3825 if (stream->send_dvd_event) {
3826 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
3827 /* FIXME: should we send this event again after (flushing) seek ? */
3828 stream->send_dvd_event = FALSE;
3834 static GstFlowReturn
3835 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
3836 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3839 guint seq_header_len;
3840 guint32 header, tmp;
3842 if (stream->codec_state) {
3843 seq_header = stream->codec_state;
3844 seq_header_len = stream->codec_state_size;
3845 } else if (stream->codec_priv) {
3846 seq_header = stream->codec_priv;
3847 seq_header_len = stream->codec_priv_size;
3852 /* Sequence header only needed for keyframes */
3853 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
3856 if (gst_buffer_get_size (*buf) < 4)
3859 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
3860 header = GUINT32_FROM_BE (tmp);
3862 /* Sequence start code, if not found prepend */
3863 if (header != 0x000001b3) {
3866 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
3868 newbuf = gst_buffer_new_memdup (seq_header, seq_header_len);
3870 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
3871 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
3872 gst_buffer_get_size (*buf));
3874 gst_buffer_unref (*buf);
3881 static GstFlowReturn
3882 gst_matroska_demux_add_wvpk_header (GstElement * element,
3883 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3885 GstMatroskaTrackAudioContext *audiocontext =
3886 (GstMatroskaTrackAudioContext *) stream;
3887 GstBuffer *newbuf = NULL;
3888 GstMapInfo map, outmap;
3889 guint8 *buf_data, *data;
3897 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
3900 wvh.total_samples = -1;
3901 wvh.block_index = audiocontext->wvpk_block_index;
3903 if (audiocontext->channels <= 2) {
3904 guint32 block_samples, tmp;
3905 gsize size = gst_buffer_get_size (*buf);
3908 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
3909 gst_buffer_unmap (*buf, &map);
3910 return GST_FLOW_ERROR;
3913 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
3914 block_samples = GUINT32_FROM_LE (tmp);
3915 /* we need to reconstruct the header of the wavpack block */
3917 /* -20 because ck_size is the size of the wavpack block -8
3918 * and lace_size is the size of the wavpack block + 12
3919 * (the three guint32 of the header that already are in the buffer) */
3920 wvh.ck_size = size + WAVPACK4_HEADER_SIZE - 20;
3922 /* block_samples, flags and crc are already in the buffer */
3923 newbuf = gst_buffer_new_allocate (NULL, WAVPACK4_HEADER_SIZE - 12, NULL);
3925 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3931 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
3932 GST_WRITE_UINT16_LE (data + 8, wvh.version);
3933 GST_WRITE_UINT8 (data + 10, wvh.track_no);
3934 GST_WRITE_UINT8 (data + 11, wvh.index_no);
3935 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
3936 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
3937 gst_buffer_unmap (newbuf, &outmap);
3939 /* Append data from buf: */
3940 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
3941 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
3943 gst_buffer_unref (*buf);
3945 audiocontext->wvpk_block_index += block_samples;
3947 guint8 *outdata = NULL;
3948 gsize buf_size, size;
3949 guint32 block_samples, flags, crc;
3951 GstAdapter *adapter;
3953 adapter = gst_adapter_new ();
3955 gst_buffer_map (*buf, &map, GST_MAP_READ);
3956 buf_data = map.data;
3957 buf_size = map.size;
3960 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
3961 gst_buffer_unmap (*buf, &map);
3962 g_object_unref (adapter);
3963 return GST_FLOW_ERROR;
3969 block_samples = GST_READ_UINT32_LE (data);
3974 flags = GST_READ_UINT32_LE (data);
3977 crc = GST_READ_UINT32_LE (data);
3980 blocksize = GST_READ_UINT32_LE (data);
3984 if (blocksize == 0 || size < blocksize) {
3985 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
3986 gst_buffer_unmap (*buf, &map);
3987 g_object_unref (adapter);
3988 return GST_FLOW_ERROR;
3991 if (blocksize > G_MAXSIZE - WAVPACK4_HEADER_SIZE) {
3992 GST_ERROR_OBJECT (element, "Too big wavpack buffer");
3993 gst_buffer_unmap (*buf, &map);
3994 g_object_unref (adapter);
3995 return GST_FLOW_ERROR;
3998 g_assert (newbuf == NULL);
4001 gst_buffer_new_allocate (NULL, WAVPACK4_HEADER_SIZE + blocksize,
4003 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
4004 outdata = outmap.data;
4012 GST_WRITE_UINT32_LE (outdata, blocksize + WAVPACK4_HEADER_SIZE - 8);
4013 GST_WRITE_UINT16_LE (outdata + 4, wvh.version);
4014 GST_WRITE_UINT8 (outdata + 6, wvh.track_no);
4015 GST_WRITE_UINT8 (outdata + 7, wvh.index_no);
4016 GST_WRITE_UINT32_LE (outdata + 8, wvh.total_samples);
4017 GST_WRITE_UINT32_LE (outdata + 12, wvh.block_index);
4018 GST_WRITE_UINT32_LE (outdata + 16, block_samples);
4019 GST_WRITE_UINT32_LE (outdata + 20, flags);
4020 GST_WRITE_UINT32_LE (outdata + 24, crc);
4023 memcpy (outdata, data, blocksize);
4025 gst_buffer_unmap (newbuf, &outmap);
4026 gst_adapter_push (adapter, newbuf);
4032 gst_buffer_unmap (*buf, &map);
4034 newbuf = gst_adapter_take_buffer (adapter, gst_adapter_available (adapter));
4035 g_object_unref (adapter);
4037 gst_buffer_copy_into (newbuf, *buf,
4038 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
4039 gst_buffer_unref (*buf);
4042 audiocontext->wvpk_block_index += block_samples;
4048 static GstFlowReturn
4049 gst_matroska_demux_add_prores_header (GstElement * element,
4050 GstMatroskaTrackContext * stream, GstBuffer ** buf)
4052 GstBuffer *newbuf = gst_buffer_new_allocate (NULL, 8, NULL);
4056 if (!gst_buffer_map (newbuf, &map, GST_MAP_WRITE)) {
4057 GST_ERROR ("Failed to map newly allocated buffer");
4058 return GST_FLOW_ERROR;
4061 frame_size = gst_buffer_get_size (*buf);
4063 GST_WRITE_UINT32_BE (map.data, frame_size);
4069 gst_buffer_unmap (newbuf, &map);
4070 *buf = gst_buffer_append (newbuf, *buf);
4075 /* @text must be null-terminated */
4077 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
4082 g_return_val_if_fail (text != NULL, FALSE);
4084 /* yes, this might all lead to false positives ... */
4085 tag = (gchar *) text;
4086 while ((tag = strchr (tag, '<'))) {
4088 if (*tag != '\0' && *(tag + 1) == '>') {
4089 /* some common convenience ones */
4090 /* maybe any character will do here ? */
4103 if (strstr (text, "<span"))
4109 static GstFlowReturn
4110 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
4111 GstMatroskaTrackContext * stream, GstBuffer ** buf)
4113 GstMatroskaTrackSubtitleContext *sub_stream;
4114 const gchar *encoding;
4119 gboolean needs_unmap = TRUE;
4121 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
4123 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
4126 /* The subtitle buffer we push out should not include a NUL terminator as
4127 * part of the data. */
4128 if (map.data[map.size - 1] == '\0') {
4129 gst_buffer_set_size (*buf, map.size - 1);
4130 gst_buffer_unmap (*buf, &map);
4131 gst_buffer_map (*buf, &map, GST_MAP_READ);
4134 if (!sub_stream->invalid_utf8) {
4135 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
4138 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
4139 " is not valid UTF-8, this is broken according to the matroska"
4140 " specification", stream->num);
4141 sub_stream->invalid_utf8 = TRUE;
4144 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
4145 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
4146 if (encoding == NULL || *encoding == '\0') {
4147 /* if local encoding is UTF-8 and no encoding specified
4148 * via the environment variable, assume ISO-8859-15 */
4149 if (g_get_charset (&encoding)) {
4150 encoding = "ISO-8859-15";
4155 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
4156 (char *) "*", NULL, NULL, &err);
4159 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
4160 encoding, err->message);
4164 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
4165 encoding = "ISO-8859-15";
4167 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
4168 encoding, (char *) "*", NULL, NULL, NULL);
4171 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
4172 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
4175 utf8 = g_strdup ("invalid subtitle");
4177 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
4178 gst_buffer_unmap (*buf, &map);
4179 gst_buffer_copy_into (newbuf, *buf,
4180 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
4182 gst_buffer_unref (*buf);
4185 gst_buffer_map (*buf, &map, GST_MAP_READ);
4189 if (sub_stream->check_markup) {
4190 /* caps claim markup text, so we need to escape text,
4191 * except if text is already markup and then needs no further escaping */
4192 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
4193 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
4195 if (!sub_stream->seen_markup_tag) {
4196 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
4198 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
4199 gst_buffer_unmap (*buf, &map);
4200 gst_buffer_copy_into (newbuf, *buf,
4201 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
4202 GST_BUFFER_COPY_META, 0, -1);
4203 gst_buffer_unref (*buf);
4206 needs_unmap = FALSE;
4211 gst_buffer_unmap (*buf, &map);
4216 static GstFlowReturn
4217 gst_matroska_demux_check_aac (GstElement * element,
4218 GstMatroskaTrackContext * stream, GstBuffer ** buf)
4223 gst_buffer_extract (*buf, 0, data, 2);
4224 size = gst_buffer_get_size (*buf);
4226 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
4229 /* tss, ADTS data, remove codec_data
4230 * still assume it is at least parsed */
4231 stream->caps = gst_caps_make_writable (stream->caps);
4232 s = gst_caps_get_structure (stream->caps, 0);
4234 gst_structure_remove_field (s, "codec_data");
4235 gst_pad_set_caps (stream->pad, stream->caps);
4236 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
4237 "new caps: %" GST_PTR_FORMAT, stream->caps);
4240 /* disable subsequent checking */
4241 stream->postprocess_frame = NULL;
4247 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
4248 GstBuffer * buffer, gsize alignment)
4252 gst_buffer_map (buffer, &map, GST_MAP_READ);
4254 if (map.size < sizeof (guintptr)) {
4255 gst_buffer_unmap (buffer, &map);
4259 if (((guintptr) map.data) & (alignment - 1)) {
4260 GstBuffer *new_buffer;
4261 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
4263 new_buffer = gst_buffer_new_allocate (NULL,
4264 gst_buffer_get_size (buffer), ¶ms);
4266 /* Copy data "by hand", so ensure alignment is kept: */
4267 gst_buffer_fill (new_buffer, 0, map.data, map.size);
4269 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
4270 GST_DEBUG_OBJECT (demux,
4271 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
4274 gst_buffer_unmap (buffer, &map);
4275 gst_buffer_unref (buffer);
4280 gst_buffer_unmap (buffer, &map);
4291 static GstFlowReturn
4292 gst_matroska_demux_parse_blockmore (GstMatroskaDemux * demux,
4293 GstEbmlRead * ebml, GQueue * additions)
4297 guint64 block_id = 1;
4298 guint64 datalen = 0;
4299 guint8 *data = NULL;
4301 ret = gst_ebml_read_master (ebml, &id); /* GST_MATROSKA_ID_BLOCKMORE */
4302 if (ret != GST_FLOW_OK)
4305 /* read all BlockMore sub-entries */
4306 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4308 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4312 case GST_MATROSKA_ID_BLOCKADDID:
4313 ret = gst_ebml_read_uint (ebml, &id, &block_id);
4317 case GST_MATROSKA_ID_BLOCKADDITIONAL:
4321 ret = gst_ebml_read_binary (ebml, &id, &data, &datalen);
4324 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
4330 if (data != NULL && datalen > 0) {
4331 BlockAddition *blockadd = g_new (BlockAddition, 1);
4333 GST_LOG_OBJECT (demux, "BlockAddition %" G_GUINT64_FORMAT ": "
4334 "%" G_GUINT64_FORMAT " bytes", block_id, datalen);
4335 GST_MEMDUMP_OBJECT (demux, "BlockAdditional", data, datalen);
4336 blockadd->data = data;
4337 blockadd->size = datalen;
4338 blockadd->id = block_id;
4339 g_queue_push_tail (additions, blockadd);
4340 GST_LOG_OBJECT (demux, "now %d pending block additions", additions->length);
4351 static GstFlowReturn
4352 gst_matroska_demux_parse_blockadditions (GstMatroskaDemux * demux,
4353 GstEbmlRead * ebml, GQueue * additions)
4358 ret = gst_ebml_read_master (ebml, &id); /* GST_MATROSKA_ID_BLOCKADDITIONS */
4359 if (ret != GST_FLOW_OK)
4362 /* read all BlockMore sub-entries */
4363 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4365 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4368 if (id == GST_MATROSKA_ID_BLOCKMORE) {
4369 DEBUG_ELEMENT_START (demux, ebml, "BlockMore");
4370 ret = gst_matroska_demux_parse_blockmore (demux, ebml, additions);
4371 DEBUG_ELEMENT_STOP (demux, ebml, "BlockMore", ret);
4372 if (ret != GST_FLOW_OK)
4375 GST_WARNING_OBJECT (demux, "Expected BlockMore, got %x", id);
4382 static GstFlowReturn
4383 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
4384 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
4385 gboolean is_simpleblock)
4387 GstMatroskaTrackContext *stream = NULL;
4388 GstFlowReturn ret = GST_FLOW_OK;
4389 gboolean readblock = FALSE;
4391 guint64 block_duration = -1;
4392 gint64 block_discardpadding = 0;
4393 GstBuffer *buf = NULL;
4395 gint stream_num = -1, n, laces = 0;
4397 gint *lace_size = NULL;
4400 gint64 referenceblock = 0;
4402 GstClockTime buffer_timestamp;
4403 GQueue additions = G_QUEUE_INIT;
4405 offset = gst_ebml_read_get_offset (ebml);
4407 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4408 if (!is_simpleblock) {
4409 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
4413 id = GST_MATROSKA_ID_SIMPLEBLOCK;
4417 /* one block inside the group. Note, block parsing is one
4418 * of the harder things, so this code is a bit complicated.
4419 * See http://www.matroska.org/ for documentation. */
4420 case GST_MATROSKA_ID_SIMPLEBLOCK:
4421 case GST_MATROSKA_ID_BLOCK:
4427 gst_buffer_unmap (buf, &map);
4428 gst_buffer_unref (buf);
4431 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
4434 gst_buffer_map (buf, &map, GST_MAP_READ);
4438 /* first byte(s): blocknum */
4439 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
4444 /* fetch stream from num */
4445 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
4447 if (G_UNLIKELY (size < 3)) {
4448 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
4449 /* non-fatal, try next block(group) */
4452 } else if (G_UNLIKELY (stream_num < 0 ||
4453 stream_num >= demux->common.num_streams)) {
4454 /* let's not give up on a stray invalid track number */
4455 GST_WARNING_OBJECT (demux,
4456 "Invalid stream %d for track number %" G_GUINT64_FORMAT
4457 "; ignoring block", stream_num, num);
4461 stream = g_ptr_array_index (demux->common.src, stream_num);
4463 /* time (relative to cluster time) */
4464 time = ((gint16) GST_READ_UINT16_BE (data));
4467 flags = GST_READ_UINT8 (data);
4471 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
4474 switch ((flags & 0x06) >> 1) {
4475 case 0x0: /* no lacing */
4477 lace_size = g_new (gint, 1);
4478 lace_size[0] = size;
4481 case 0x1: /* xiph lacing */
4482 case 0x2: /* fixed-size lacing */
4483 case 0x3: /* EBML lacing */
4485 goto invalid_lacing;
4486 laces = GST_READ_UINT8 (data) + 1;
4489 lace_size = g_new0 (gint, laces);
4491 switch ((flags & 0x06) >> 1) {
4492 case 0x1: /* xiph lacing */ {
4493 guint temp, total = 0;
4495 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
4498 goto invalid_lacing;
4499 temp = GST_READ_UINT8 (data);
4500 lace_size[n] += temp;
4506 total += lace_size[n];
4508 lace_size[n] = size - total;
4512 case 0x2: /* fixed-size lacing */
4513 for (n = 0; n < laces; n++)
4514 lace_size[n] = size / laces;
4517 case 0x3: /* EBML lacing */ {
4520 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
4524 total = lace_size[0] = num;
4525 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
4529 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
4533 lace_size[n] = lace_size[n - 1] + snum;
4534 total += lace_size[n];
4537 lace_size[n] = size - total;
4544 if (ret != GST_FLOW_OK)
4551 case GST_MATROSKA_ID_BLOCKADDITIONS:
4553 DEBUG_ELEMENT_START (demux, ebml, "BlockAdditions");
4554 ret = gst_matroska_demux_parse_blockadditions (demux, ebml, &additions);
4555 DEBUG_ELEMENT_STOP (demux, ebml, "BlockAdditions", ret);
4559 case GST_MATROSKA_ID_BLOCKDURATION:{
4560 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
4561 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
4566 case GST_MATROSKA_ID_DISCARDPADDING:{
4567 ret = gst_ebml_read_sint (ebml, &id, &block_discardpadding);
4568 GST_DEBUG_OBJECT (demux, "DiscardPadding: %" GST_STIME_FORMAT,
4569 GST_STIME_ARGS (block_discardpadding));
4573 case GST_MATROSKA_ID_REFERENCEBLOCK:{
4574 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
4575 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
4580 case GST_MATROSKA_ID_CODECSTATE:{
4582 guint64 data_len = 0;
4585 gst_ebml_read_binary (ebml, &id, &data,
4586 &data_len)) != GST_FLOW_OK)
4589 if (G_UNLIKELY (stream == NULL)) {
4590 GST_WARNING_OBJECT (demux,
4591 "Unexpected CodecState subelement - ignoring");
4595 g_free (stream->codec_state);
4596 stream->codec_state = data;
4597 stream->codec_state_size = data_len;
4599 /* Decode if necessary */
4600 if (stream->encodings && stream->encodings->len > 0
4601 && stream->codec_state && stream->codec_state_size > 0) {
4602 if (!gst_matroska_decode_data (stream->encodings,
4603 &stream->codec_state, &stream->codec_state_size,
4604 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
4605 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
4609 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
4610 stream->codec_state_size);
4615 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
4619 case GST_MATROSKA_ID_BLOCKVIRTUAL:
4620 case GST_MATROSKA_ID_REFERENCEPRIORITY:
4621 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
4622 case GST_MATROSKA_ID_SLICES:
4623 GST_DEBUG_OBJECT (demux,
4624 "Skipping BlockGroup subelement 0x%x - ignoring", id);
4625 ret = gst_ebml_read_skip (ebml);
4633 /* reading a number or so could have failed */
4634 if (ret != GST_FLOW_OK)
4637 if (ret == GST_FLOW_OK && readblock) {
4638 gboolean invisible_frame = FALSE;
4639 gboolean delta_unit = FALSE;
4640 guint64 duration = 0;
4641 gint64 lace_time = 0;
4642 gboolean keep_seek_start = TRUE;
4643 GstEvent *protect_event;
4645 stream = g_ptr_array_index (demux->common.src, stream_num);
4647 if (cluster_time != GST_CLOCK_TIME_NONE) {
4648 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
4649 * Drop unless the lace contains timestamp 0? */
4650 if (time < 0 && (-time) > cluster_time) {
4653 if (stream->timecodescale == 1.0)
4654 lace_time = (cluster_time + time) * demux->common.time_scale;
4657 gst_util_guint64_to_gdouble ((cluster_time + time) *
4658 demux->common.time_scale) * stream->timecodescale;
4661 lace_time = GST_CLOCK_TIME_NONE;
4663 /* Send the GST_PROTECTION event */
4664 while ((protect_event = g_queue_pop_head (&stream->protection_event_queue))) {
4665 GST_TRACE_OBJECT (demux, "pushing protection event for stream %d:%s",
4666 stream->index, GST_STR_NULL (stream->name));
4667 gst_pad_push_event (stream->pad, protect_event);
4670 /* need to refresh segment info ASAP */
4671 if (GST_CLOCK_TIME_IS_VALID (lace_time)
4672 && GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)
4673 && lace_time < demux->stream_start_time) {
4675 (demux->common.segment.start > demux->stream_start_time);
4676 demux->stream_start_time = lace_time;
4677 demux->need_segment = TRUE;
4680 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
4681 GstSegment *segment = &demux->common.segment;
4683 GstEvent *segment_event;
4685 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
4686 demux->stream_start_time = lace_time;
4687 GST_DEBUG_OBJECT (demux,
4688 "Setting stream start time to %" GST_TIME_FORMAT,
4689 GST_TIME_ARGS (lace_time));
4691 clace_time = MAX (lace_time, demux->stream_start_time);
4693 && GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
4694 && demux->common.segment.position != 0) {
4695 GST_DEBUG_OBJECT (demux, "using stored seek position %" GST_TIME_FORMAT,
4696 GST_TIME_ARGS (demux->common.segment.position));
4697 clace_time = demux->common.segment.position;
4700 /* We shouldn't modify upstream driven TIME FORMAT segment */
4701 if (!demux->upstream_format_is_time) {
4702 segment->start = clace_time;
4703 segment->stop = demux->common.segment.stop;
4704 segment->time = segment->start - demux->stream_start_time;
4705 segment->position = segment->start - demux->stream_start_time;
4707 GST_DEBUG_OBJECT (demux,
4708 "generated segment starting at %" GST_TIME_FORMAT ": %"
4709 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
4710 /* now convey our segment notion downstream */
4711 segment_event = gst_event_new_segment (segment);
4712 if (demux->segment_seqnum)
4713 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
4714 gst_matroska_demux_send_event (demux, segment_event);
4715 demux->need_segment = FALSE;
4716 demux->segment_seqnum = 0;
4719 /* send pending codec data headers for all streams,
4720 * before we perform sync across all streams */
4721 gst_matroska_demux_push_codec_data_all (demux);
4723 if (block_duration != -1) {
4724 if (stream->timecodescale == 1.0)
4725 duration = gst_util_uint64_scale (block_duration,
4726 demux->common.time_scale, 1);
4729 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
4730 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
4731 1)) * stream->timecodescale);
4732 } else if (stream->default_duration) {
4733 duration = stream->default_duration * laces;
4735 /* else duration is diff between timecode of this and next block */
4737 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
4738 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
4739 a ReferenceBlock implies that this is not a keyframe. In either
4740 case, it only makes sense for video streams. */
4741 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
4743 invisible_frame = ((flags & 0x08)) &&
4744 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
4745 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9) ||
4746 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_AV1));
4749 /* If we're doing a keyframe-only trickmode, only push keyframes on video
4752 && demux->common.segment.
4753 flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) {
4754 GST_LOG_OBJECT (demux, "Skipping non-keyframe on stream %d",
4761 for (n = 0; n < laces; n++) {
4764 if (G_UNLIKELY (lace_size[n] > size)) {
4765 GST_WARNING_OBJECT (demux, "Invalid lace size");
4769 /* QoS for video track with an index. the assumption is that
4770 index entries point to keyframes, but if that is not true we
4771 will instead skip until the next keyframe. */
4772 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
4773 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
4774 stream->index_table && demux->common.segment.rate > 0.0) {
4775 GstMatroskaTrackVideoContext *videocontext =
4776 (GstMatroskaTrackVideoContext *) stream;
4777 GstClockTime earliest_time;
4778 GstClockTime earliest_stream_time;
4780 GST_OBJECT_LOCK (demux);
4781 earliest_time = videocontext->earliest_time;
4782 GST_OBJECT_UNLOCK (demux);
4783 earliest_stream_time =
4784 gst_segment_position_from_running_time (&demux->common.segment,
4785 GST_FORMAT_TIME, earliest_time);
4787 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
4788 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
4789 lace_time <= earliest_stream_time) {
4790 /* find index entry (keyframe) <= earliest_stream_time */
4791 GstMatroskaIndex *entry =
4792 gst_util_array_binary_search (stream->index_table->data,
4793 stream->index_table->len, sizeof (GstMatroskaIndex),
4794 (GCompareDataFunc) gst_matroska_index_seek_find,
4795 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
4797 /* if that entry (keyframe) is after the current the current
4798 buffer, we can skip pushing (and thus decoding) all
4799 buffers until that keyframe. */
4800 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
4801 entry->time > lace_time) {
4802 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
4803 stream->set_discont = TRUE;
4809 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
4810 gst_buffer_get_size (buf) - size, lace_size[n]);
4811 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
4814 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4816 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4818 if (invisible_frame)
4819 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
4821 if (stream->encodings != NULL && stream->encodings->len > 0)
4822 sub = gst_matroska_decode_buffer (stream, sub);
4825 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
4829 if (!stream->dts_only) {
4830 GST_BUFFER_PTS (sub) = lace_time;
4832 GST_BUFFER_DTS (sub) = lace_time;
4833 if (stream->intra_only)
4834 GST_BUFFER_PTS (sub) = lace_time;
4837 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
4839 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
4840 GstClockTime last_stop_end;
4842 /* Check if this stream is after segment stop,
4843 * but only terminate if we hit the next keyframe,
4844 * to make sure that all frames potentially inside the segment
4845 * are available to the decoder for decoding / reordering.*/
4846 if (!delta_unit && GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
4847 && lace_time >= demux->common.segment.stop) {
4848 GST_DEBUG_OBJECT (demux,
4849 "Stream %d lace time: %" GST_TIME_FORMAT " after segment stop: %"
4850 GST_TIME_FORMAT, stream->index, GST_TIME_ARGS (lace_time),
4851 GST_TIME_ARGS (demux->common.segment.stop));
4852 gst_buffer_unref (sub);
4855 if (offset >= stream->to_offset
4856 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
4857 && lace_time > demux->to_time)) {
4858 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
4860 gst_buffer_unref (sub);
4864 /* handle gaps, e.g. non-zero start-time, or an cue index entry
4865 * that landed us with timestamps not quite intended */
4866 GST_OBJECT_LOCK (demux);
4867 if (demux->max_gap_time &&
4868 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
4869 demux->common.segment.rate > 0.0) {
4870 GstClockTimeDiff diff;
4872 /* only send segments with increasing start times,
4873 * otherwise if these go back and forth downstream (sinks) increase
4874 * accumulated time and running_time */
4875 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
4876 if (diff > 0 && diff > demux->max_gap_time
4877 && lace_time > demux->common.segment.start
4878 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
4879 || lace_time < demux->common.segment.stop)) {
4881 GST_DEBUG_OBJECT (demux,
4882 "Gap of %" G_GINT64_FORMAT " ns detected in"
4883 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
4884 "Sending updated SEGMENT events", diff,
4885 stream->index, GST_TIME_ARGS (stream->pos),
4886 GST_TIME_ARGS (lace_time));
4888 event = gst_event_new_gap (demux->last_stop_end, diff);
4889 GST_OBJECT_UNLOCK (demux);
4890 gst_pad_push_event (stream->pad, event);
4891 GST_OBJECT_LOCK (demux);
4895 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
4896 || demux->common.segment.position < lace_time) {
4897 demux->common.segment.position = lace_time;
4899 GST_OBJECT_UNLOCK (demux);
4901 last_stop_end = lace_time;
4903 GST_BUFFER_DURATION (sub) = duration / laces;
4904 last_stop_end += GST_BUFFER_DURATION (sub);
4907 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
4908 demux->last_stop_end < last_stop_end)
4909 demux->last_stop_end = last_stop_end;
4911 GST_OBJECT_LOCK (demux);
4912 if (demux->common.segment.duration == -1 ||
4913 demux->stream_start_time + demux->common.segment.duration <
4915 demux->common.segment.duration =
4916 last_stop_end - demux->stream_start_time;
4917 GST_OBJECT_UNLOCK (demux);
4918 if (!demux->invalid_duration) {
4919 gst_element_post_message (GST_ELEMENT_CAST (demux),
4920 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
4921 demux->invalid_duration = TRUE;
4924 GST_OBJECT_UNLOCK (demux);
4928 stream->pos = lace_time;
4930 gst_matroska_demux_sync_streams (demux);
4932 if (stream->set_discont) {
4933 GST_DEBUG_OBJECT (demux, "marking DISCONT");
4934 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
4935 stream->set_discont = FALSE;
4937 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
4940 /* reverse playback book-keeping */
4941 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
4942 stream->from_time = lace_time;
4943 if (stream->from_offset == -1)
4944 stream->from_offset = offset;
4946 GST_DEBUG_OBJECT (demux,
4947 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
4948 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
4949 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
4950 GST_TIME_ARGS (buffer_timestamp),
4951 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
4954 if (demux->common.element_index) {
4955 if (stream->index_writer_id == -1)
4956 gst_index_get_writer_id (demux->common.element_index,
4957 GST_OBJECT (stream->pad), &stream->index_writer_id);
4959 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4960 G_GUINT64_FORMAT " for writer id %d",
4961 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
4962 stream->index_writer_id);
4963 gst_index_add_association (demux->common.element_index,
4964 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
4965 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
4966 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
4971 /* Postprocess the buffers depending on the codec used */
4972 if (stream->postprocess_frame) {
4973 GST_LOG_OBJECT (demux, "running post process");
4974 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
4977 /* At this point, we have a sub-buffer pointing at data within a larger
4978 buffer. This data might not be aligned with anything. If the data is
4979 raw samples though, we want it aligned to the raw type (eg, 4 bytes
4980 for 32 bit samples, etc), or bad things will happen downstream as
4981 elements typically assume minimal alignment.
4982 Therefore, create an aligned copy if necessary. */
4983 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
4985 if (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
4986 guint64 start_clip = 0, end_clip = 0;
4988 /* Codec delay is part of the timestamps */
4989 if (GST_BUFFER_PTS_IS_VALID (sub) && stream->codec_delay) {
4990 if (GST_BUFFER_PTS (sub) > stream->codec_delay) {
4991 GST_BUFFER_PTS (sub) -= stream->codec_delay;
4993 GST_BUFFER_PTS (sub) = 0;
4995 /* Opus GstAudioClippingMeta units are scaled by 48000/sample_rate.
4996 That is, if a Opus track has audio encoded at 24000 Hz and 132
4997 samples need to be clipped, GstAudioClippingMeta.start will be
4998 set to 264. (This is also the case for buffer offsets.)
4999 Opus sample rates are always divisors of 48000 Hz, which is the
5000 maximum allowed sample rate. */
5002 gst_util_uint64_scale_round (stream->codec_delay, 48000,
5005 if (GST_BUFFER_DURATION_IS_VALID (sub)) {
5006 if (GST_BUFFER_DURATION (sub) > stream->codec_delay)
5007 GST_BUFFER_DURATION (sub) -= stream->codec_delay;
5009 GST_BUFFER_DURATION (sub) = 0;
5014 if (block_discardpadding) {
5016 gst_util_uint64_scale_round (block_discardpadding, 48000,
5020 if (start_clip || end_clip) {
5021 gst_buffer_add_audio_clipping_meta (sub, GST_FORMAT_DEFAULT,
5022 start_clip, end_clip);
5026 if (GST_BUFFER_PTS_IS_VALID (sub)) {
5027 stream->pos = GST_BUFFER_PTS (sub);
5028 if (GST_BUFFER_DURATION_IS_VALID (sub))
5029 stream->pos += GST_BUFFER_DURATION (sub);
5030 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
5031 stream->pos = GST_BUFFER_DTS (sub);
5032 if (GST_BUFFER_DURATION_IS_VALID (sub))
5033 stream->pos += GST_BUFFER_DURATION (sub);
5036 /* Attach BlockAdditions to buffer; we assume a single buffer per group
5038 if (additions.length > 0) {
5039 BlockAddition *blockadd;
5042 GST_FIXME_OBJECT (demux, "Fix block additions with laced buffers");
5044 while ((blockadd = g_queue_pop_head (&additions))) {
5045 GstMatroskaTrackVideoContext *videocontext =
5046 (GstMatroskaTrackVideoContext *) stream;
5047 if (blockadd->id == 1 && videocontext->alpha_mode
5048 && (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)
5049 || !strcmp (stream->codec_id,
5050 GST_MATROSKA_CODEC_ID_VIDEO_VP9))) {
5051 GstBuffer *alpha_buffer;
5053 GST_TRACE_OBJECT (demux, "adding block addition %u as VP8/VP9 "
5054 "alpha meta to buffer %p, %u bytes", (guint) blockadd->id, buf,
5055 (guint) blockadd->size);
5057 alpha_buffer = gst_buffer_new_wrapped (blockadd->data,
5059 gst_buffer_copy_into (alpha_buffer, sub,
5060 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
5061 gst_buffer_add_video_codec_alpha_meta (sub, alpha_buffer);
5063 g_free (blockadd->data);
5069 ret = gst_pad_push (stream->pad, sub);
5071 if (demux->common.segment.rate < 0) {
5072 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
5073 /* In reverse playback we can get a GST_FLOW_EOS when
5074 * we are at the end of the segment, so we just need to jump
5075 * back to the previous section. */
5076 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
5081 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
5085 size -= lace_size[n];
5086 if (lace_time != GST_CLOCK_TIME_NONE && duration)
5087 lace_time += duration / laces;
5089 lace_time = GST_CLOCK_TIME_NONE;
5095 gst_buffer_unmap (buf, &map);
5096 gst_buffer_unref (buf);
5100 BlockAddition *blockadd;
5102 while ((blockadd = g_queue_pop_head (&additions))) {
5103 g_free (blockadd->data);
5115 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
5121 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
5122 /* non-fatal, try next block(group) */
5128 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
5129 /* non-fatal, try next block(group) */
5135 /* return FALSE if block(group) should be skipped (due to a seek) */
5136 static inline gboolean
5137 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
5139 if (G_UNLIKELY (demux->seek_block)) {
5140 if (!(--demux->seek_block)) {
5143 GST_LOG_OBJECT (demux, "should skip block due to seek");
5151 static GstFlowReturn
5152 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
5156 guint64 seek_pos = (guint64) - 1;
5157 guint32 seek_id = 0;
5160 DEBUG_ELEMENT_START (demux, ebml, "Seek");
5162 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
5163 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
5167 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
5168 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
5172 case GST_MATROSKA_ID_SEEKID:
5176 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
5179 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
5184 case GST_MATROSKA_ID_SEEKPOSITION:
5188 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
5191 if (t > G_MAXINT64) {
5192 GST_WARNING_OBJECT (demux,
5193 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
5197 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
5203 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
5209 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
5212 if (!seek_id || seek_pos == (guint64) - 1) {
5213 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
5214 G_GUINT64_FORMAT ")", seek_id, seek_pos);
5219 case GST_MATROSKA_ID_SEEKHEAD:
5222 case GST_MATROSKA_ID_CUES:
5223 case GST_MATROSKA_ID_TAGS:
5224 case GST_MATROSKA_ID_TRACKS:
5225 case GST_MATROSKA_ID_SEGMENTINFO:
5226 case GST_MATROSKA_ID_ATTACHMENTS:
5227 case GST_MATROSKA_ID_CHAPTERS:
5229 guint64 before_pos, length;
5233 length = gst_matroska_read_common_get_length (&demux->common);
5234 before_pos = demux->common.offset;
5236 if (length == (guint64) - 1) {
5237 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
5241 /* check for validity */
5242 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
5243 GST_WARNING_OBJECT (demux,
5244 "SeekHead reference lies outside file!" " (%"
5245 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
5246 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
5251 /* only pick up index location when streaming */
5252 if (demux->streaming) {
5253 if (seek_id == GST_MATROSKA_ID_CUES) {
5254 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
5255 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
5256 demux->index_offset);
5262 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
5265 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
5266 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
5270 if (id != seek_id) {
5271 GST_WARNING_OBJECT (demux,
5272 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
5273 seek_id, id, seek_pos + demux->common.ebml_segment_start);
5276 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5281 demux->common.offset = before_pos;
5285 case GST_MATROSKA_ID_CLUSTER:
5287 guint64 pos = seek_pos + demux->common.ebml_segment_start;
5289 GST_LOG_OBJECT (demux, "Cluster position");
5290 if (G_UNLIKELY (!demux->clusters))
5291 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
5292 g_array_append_val (demux->clusters, pos);
5297 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
5300 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
5305 static GstFlowReturn
5306 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
5308 GstFlowReturn ret = GST_FLOW_OK;
5311 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
5313 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
5314 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
5318 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
5319 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
5323 case GST_MATROSKA_ID_SEEKENTRY:
5325 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
5326 /* Ignore EOS and errors here */
5327 if (ret != GST_FLOW_OK) {
5328 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
5335 ret = gst_matroska_read_common_parse_skip (&demux->common,
5336 ebml, "SeekHead", id);
5341 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
5343 /* Sort clusters by position for easier searching */
5344 if (demux->clusters)
5345 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
5350 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
5352 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
5354 static inline GstFlowReturn
5355 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
5357 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
5358 /* only a few blocks are expected/allowed to be large,
5359 * and will be recursed into, whereas others will be read and must fit */
5360 if (demux->streaming) {
5361 /* fatal in streaming case, as we can't step over easily */
5362 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5363 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
5364 "file might be corrupt.", bytes));
5365 return GST_FLOW_ERROR;
5367 /* indicate higher level to quietly give up */
5368 GST_DEBUG_OBJECT (demux,
5369 "too large block of size %" G_GUINT64_FORMAT, bytes);
5370 return GST_FLOW_ERROR;
5377 /* returns TRUE if we truly are in error state, and should give up */
5378 static inline GstFlowReturn
5379 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
5381 if (!demux->streaming && demux->next_cluster_offset > 0) {
5382 /* just repositioning to where next cluster should be and try from there */
5383 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
5384 G_GUINT64_FORMAT, demux->next_cluster_offset);
5385 demux->common.offset = demux->next_cluster_offset;
5386 demux->next_cluster_offset = 0;
5392 /* sigh, one last attempt above and beyond call of duty ...;
5393 * search for cluster mark following current pos */
5394 pos = demux->common.offset;
5395 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
5396 if ((ret = gst_matroska_demux_search_cluster (demux, &pos, TRUE)) !=
5398 /* did not work, give up */
5401 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
5402 /* try that position */
5403 demux->common.offset = pos;
5409 static inline GstFlowReturn
5410 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
5412 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
5413 demux->common.offset += flush;
5414 if (demux->streaming) {
5417 /* hard to skip large blocks when streaming */
5418 ret = gst_matroska_demux_check_read_size (demux, flush);
5419 if (ret != GST_FLOW_OK)
5421 if (flush <= gst_adapter_available (demux->common.adapter))
5422 gst_adapter_flush (demux->common.adapter, flush);
5424 return GST_FLOW_EOS;
5429 /* initializes @ebml with @bytes from input stream at current offset.
5430 * Returns EOS if insufficient available,
5431 * ERROR if too much was attempted to read. */
5432 static inline GstFlowReturn
5433 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
5436 GstBuffer *buffer = NULL;
5437 GstFlowReturn ret = GST_FLOW_OK;
5439 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
5441 ret = gst_matroska_demux_check_read_size (demux, bytes);
5442 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
5443 if (!demux->streaming) {
5444 /* in pull mode, we can skip */
5445 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
5446 ret = GST_FLOW_OVERFLOW;
5448 /* otherwise fatal */
5449 ret = GST_FLOW_ERROR;
5453 if (demux->streaming) {
5454 if (gst_adapter_available (demux->common.adapter) >= bytes)
5455 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
5459 ret = gst_matroska_read_common_peek_bytes (&demux->common,
5460 demux->common.offset, bytes, &buffer, NULL);
5461 if (G_LIKELY (buffer)) {
5462 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
5463 demux->common.offset);
5464 demux->common.offset += bytes;
5471 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
5474 gboolean seekable = FALSE;
5475 gint64 start = -1, stop = -1;
5477 query = gst_query_new_seeking (GST_FORMAT_BYTES);
5478 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
5479 GST_DEBUG_OBJECT (demux, "seeking query failed");
5483 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
5485 /* try harder to query upstream size if we didn't get it the first time */
5486 if (seekable && stop == -1) {
5487 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
5488 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
5492 /* if upstream doesn't know the size, it's likely that it's not seekable in
5493 * practice even if it technically may be seekable */
5494 if (seekable && (start != 0 || stop <= start)) {
5495 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
5500 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
5501 G_GUINT64_FORMAT ")", seekable, start, stop);
5502 demux->seekable = seekable;
5504 gst_query_unref (query);
5507 static GstFlowReturn
5508 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
5514 GstFlowReturn ret = GST_FLOW_OK;
5516 GST_WARNING_OBJECT (demux,
5517 "Found Cluster element before Tracks, searching Tracks");
5520 before_pos = demux->common.offset;
5522 /* Search Tracks element */
5524 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
5525 GST_ELEMENT_CAST (demux), &id, &length, &needed);
5526 if (ret != GST_FLOW_OK)
5529 if (id != GST_MATROSKA_ID_TRACKS) {
5530 /* we may be skipping large cluster here, so forego size check etc */
5531 /* ... but we can't skip undefined size; force error */
5532 if (length == G_MAXUINT64) {
5533 ret = gst_matroska_demux_check_read_size (demux, length);
5536 demux->common.offset += needed;
5537 demux->common.offset += length;
5542 /* will lead to track parsing ... */
5543 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5548 demux->common.offset = before_pos;
5553 #define GST_READ_CHECK(stmt) \
5555 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
5556 if (ret == GST_FLOW_OVERFLOW) { \
5557 ret = GST_FLOW_OK; \
5563 static GstFlowReturn
5564 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
5565 guint64 length, guint needed)
5567 GstEbmlRead ebml = { 0, };
5568 GstFlowReturn ret = GST_FLOW_OK;
5571 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
5572 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
5574 /* if we plan to read and parse this element, we need prefix (id + length)
5575 * and the contents */
5576 /* mind about overflow wrap-around when dealing with undefined size */
5578 if (G_LIKELY (length != G_MAXUINT64))
5581 switch (demux->common.state) {
5582 case GST_MATROSKA_READ_STATE_START:
5584 case GST_EBML_ID_HEADER:
5585 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5586 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
5587 if (ret != GST_FLOW_OK)
5589 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
5590 gst_matroska_demux_check_seekability (demux);
5593 goto invalid_header;
5597 case GST_MATROSKA_READ_STATE_SEGMENT:
5599 case GST_MATROSKA_ID_SEGMENT:
5600 /* eat segment prefix */
5601 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
5602 GST_DEBUG_OBJECT (demux,
5603 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
5604 G_GUINT64_FORMAT, demux->common.offset, length);
5605 /* seeks are from the beginning of the segment,
5606 * after the segment ID/length */
5607 demux->common.ebml_segment_start = demux->common.offset;
5609 length = G_MAXUINT64;
5610 demux->common.ebml_segment_length = length;
5611 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
5614 GST_WARNING_OBJECT (demux,
5615 "Expected a Segment ID (0x%x), but received 0x%x!",
5616 GST_MATROSKA_ID_SEGMENT, id);
5617 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5621 case GST_MATROSKA_READ_STATE_SCANNING:
5622 if (id != GST_MATROSKA_ID_CLUSTER &&
5623 id != GST_MATROSKA_ID_PREVSIZE &&
5624 id != GST_MATROSKA_ID_CLUSTERTIMECODE) {
5625 if (demux->common.start_resync_offset != -1) {
5626 /* we need to skip byte per byte if we are scanning for a new cluster
5627 * after invalid data is found
5633 if (demux->common.start_resync_offset != -1) {
5634 GST_LOG_OBJECT (demux, "Resync done, new cluster found!");
5635 demux->common.start_resync_offset = -1;
5636 demux->common.state = demux->common.state_to_restore;
5640 case GST_MATROSKA_READ_STATE_HEADER:
5641 case GST_MATROSKA_READ_STATE_DATA:
5642 case GST_MATROSKA_READ_STATE_SEEK:
5644 case GST_EBML_ID_HEADER:
5645 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5646 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
5647 gst_matroska_demux_check_seekability (demux);
5649 case GST_MATROSKA_ID_SEGMENTINFO:
5650 if (!demux->common.segmentinfo_parsed) {
5651 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5652 ret = gst_matroska_read_common_parse_info (&demux->common,
5653 GST_ELEMENT_CAST (demux), &ebml);
5654 if (ret == GST_FLOW_OK)
5655 gst_matroska_demux_send_tags (demux);
5657 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5660 case GST_MATROSKA_ID_TRACKS:
5661 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5662 if (demux->tracks_ebml_offset == G_MAXUINT64) {
5663 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
5664 } else if (demux->tracks_ebml_offset != ebml.offset) {
5665 /* This is a new Tracks entry, as can happen in MSE
5667 ret = gst_matroska_demux_update_tracks (demux, &ebml);
5670 case GST_MATROSKA_ID_CLUSTER:
5671 if (G_UNLIKELY (demux->tracks_ebml_offset == G_MAXUINT64)) {
5672 if (demux->streaming) {
5673 GST_DEBUG_OBJECT (demux, "Cluster before Track");
5674 goto not_streamable;
5676 ret = gst_matroska_demux_find_tracks (demux);
5677 if (demux->tracks_ebml_offset == G_MAXUINT64)
5681 if (demux->common.state == GST_MATROSKA_READ_STATE_HEADER) {
5682 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
5683 demux->first_cluster_offset = demux->common.offset;
5685 if (!demux->streaming &&
5686 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.duration)) {
5687 GstMatroskaIndex *last = NULL;
5689 GST_DEBUG_OBJECT (demux,
5690 "estimating duration using last cluster");
5691 if ((last = gst_matroska_demux_search_pos (demux,
5692 GST_CLOCK_TIME_NONE)) != NULL) {
5693 demux->last_cluster_offset =
5694 last->pos + demux->common.ebml_segment_start;
5695 demux->stream_last_time = last->time;
5696 demux->common.segment.duration =
5697 demux->stream_last_time - demux->stream_start_time;
5698 /* above estimate should not be taken all too strongly */
5699 demux->invalid_duration = TRUE;
5700 GST_DEBUG_OBJECT (demux,
5701 "estimated duration as %" GST_TIME_FORMAT,
5702 GST_TIME_ARGS (demux->common.segment.duration));
5708 /* Peek at second cluster in order to figure out if we have cluster
5709 * prev_size or not (which is never set on the first cluster for
5710 * obvious reasons). This is useful in case someone initiates a
5711 * seek or direction change before we reach the second cluster. */
5712 if (!demux->streaming) {
5713 ClusterInfo cluster = { 0, };
5715 if (gst_matroska_demux_peek_cluster_info (demux, &cluster,
5716 demux->first_cluster_offset) && cluster.size > 0) {
5717 gst_matroska_demux_peek_cluster_info (demux, &cluster,
5718 demux->first_cluster_offset + cluster.size);
5720 demux->common.offset = demux->first_cluster_offset;
5723 if (demux->deferred_seek_event) {
5724 GstEvent *seek_event;
5726 seek_event = demux->deferred_seek_event;
5727 seek_pad = demux->deferred_seek_pad;
5728 demux->deferred_seek_event = NULL;
5729 demux->deferred_seek_pad = NULL;
5730 GST_DEBUG_OBJECT (demux,
5731 "Handling deferred seek event: %" GST_PTR_FORMAT, seek_event);
5732 gst_matroska_demux_handle_seek_event (demux, seek_pad,
5734 gst_event_unref (seek_event);
5737 /* send initial segment - we wait till we know the first
5738 incoming timestamp, so we can properly set the start of
5740 demux->need_segment = TRUE;
5742 demux->cluster_time = GST_CLOCK_TIME_NONE;
5743 demux->cluster_offset = demux->common.offset;
5744 demux->cluster_prevsize = 0;
5745 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
5746 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
5747 " not found in Cluster, trying next Cluster's first block instead",
5749 demux->seek_block = 0;
5751 demux->seek_first = FALSE;
5752 /* record next cluster for recovery */
5753 if (read != G_MAXUINT64)
5754 demux->next_cluster_offset = demux->cluster_offset + read;
5755 /* eat cluster prefix */
5756 gst_matroska_demux_flush (demux, needed);
5758 case GST_MATROSKA_ID_CLUSTERTIMECODE:
5762 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5763 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
5765 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
5766 demux->cluster_time = num;
5767 /* track last cluster */
5768 if (demux->cluster_offset > demux->last_cluster_offset) {
5769 demux->last_cluster_offset = demux->cluster_offset;
5770 demux->stream_last_time =
5771 demux->cluster_time * demux->common.time_scale;
5774 if (demux->common.element_index) {
5775 if (demux->common.element_index_writer_id == -1)
5776 gst_index_get_writer_id (demux->common.element_index,
5777 GST_OBJECT (demux), &demux->common.element_index_writer_id);
5778 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
5779 G_GUINT64_FORMAT " for writer id %d",
5780 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
5781 demux->common.element_index_writer_id);
5782 gst_index_add_association (demux->common.element_index,
5783 demux->common.element_index_writer_id,
5784 GST_ASSOCIATION_FLAG_KEY_UNIT,
5785 GST_FORMAT_TIME, demux->cluster_time,
5786 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
5791 case GST_MATROSKA_ID_BLOCKGROUP:
5792 if (!gst_matroska_demux_seek_block (demux))
5794 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5795 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
5796 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
5797 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
5798 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
5800 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
5802 case GST_MATROSKA_ID_SIMPLEBLOCK:
5803 if (!gst_matroska_demux_seek_block (demux))
5805 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5806 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
5807 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
5808 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
5809 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
5811 case GST_MATROSKA_ID_ATTACHMENTS:
5812 if (!demux->common.attachments_parsed) {
5813 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5814 ret = gst_matroska_read_common_parse_attachments (&demux->common,
5815 GST_ELEMENT_CAST (demux), &ebml);
5816 if (ret == GST_FLOW_OK)
5817 gst_matroska_demux_send_tags (demux);
5819 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5822 case GST_MATROSKA_ID_TAGS:
5823 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5824 ret = gst_matroska_read_common_parse_metadata (&demux->common,
5825 GST_ELEMENT_CAST (demux), &ebml);
5826 if (ret == GST_FLOW_OK)
5827 gst_matroska_demux_send_tags (demux);
5829 case GST_MATROSKA_ID_CHAPTERS:
5830 if (!demux->common.chapters_parsed) {
5831 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5833 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
5835 if (demux->common.toc) {
5836 gst_matroska_demux_send_event (demux,
5837 gst_event_new_toc (demux->common.toc, FALSE));
5840 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5842 case GST_MATROSKA_ID_SEEKHEAD:
5843 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5844 ret = gst_matroska_demux_parse_contents (demux, &ebml);
5846 case GST_MATROSKA_ID_CUES:
5847 if (demux->common.index_parsed) {
5848 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5851 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5852 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
5853 /* only push based; delayed index building */
5854 if (ret == GST_FLOW_OK
5855 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
5858 GST_OBJECT_LOCK (demux);
5859 event = demux->seek_event;
5860 demux->seek_event = NULL;
5861 GST_OBJECT_UNLOCK (demux);
5864 /* unlikely to fail, since we managed to seek to this point */
5865 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
5866 gst_event_unref (event);
5869 gst_event_unref (event);
5870 /* resume data handling, main thread clear to seek again */
5871 GST_OBJECT_LOCK (demux);
5872 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
5873 GST_OBJECT_UNLOCK (demux);
5876 case GST_MATROSKA_ID_PREVSIZE:{
5879 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5880 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
5882 GST_LOG_OBJECT (demux, "ClusterPrevSize: %" G_GUINT64_FORMAT, num);
5883 demux->cluster_prevsize = num;
5884 demux->seen_cluster_prevsize = TRUE;
5887 case GST_MATROSKA_ID_POSITION:
5888 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
5889 /* The WebM doesn't support the EncryptedBlock element.
5890 * The Matroska spec doesn't give us more detail, how to parse this element,
5891 * for example the field TransformID isn't specified yet.*/
5892 case GST_MATROSKA_ID_SILENTTRACKS:
5893 GST_DEBUG_OBJECT (demux,
5894 "Skipping Cluster subelement 0x%x - ignoring", id);
5898 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
5899 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5905 if (ret == GST_FLOW_PARSE)
5909 gst_ebml_read_clear (&ebml);
5915 /* simply exit, maybe not enough data yet */
5916 /* no ebml to clear if read error */
5921 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5922 ("Failed to parse Element 0x%x", id));
5923 ret = GST_FLOW_ERROR;
5928 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5929 ("File layout does not permit streaming"));
5930 ret = GST_FLOW_ERROR;
5935 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5936 ("No Tracks element found"));
5937 ret = GST_FLOW_ERROR;
5942 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
5943 ret = GST_FLOW_ERROR;
5948 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
5949 ret = GST_FLOW_ERROR;
5955 gst_matroska_demux_loop (GstPad * pad)
5957 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
5963 /* If we have to close a segment, send a new segment to do this now */
5964 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
5965 if (G_UNLIKELY (demux->new_segment)) {
5966 gst_matroska_demux_send_event (demux, demux->new_segment);
5967 demux->new_segment = NULL;
5971 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
5972 GST_ELEMENT_CAST (demux), &id, &length, &needed);
5973 if (ret == GST_FLOW_EOS) {
5975 } else if (ret == GST_FLOW_FLUSHING) {
5977 } else if (ret != GST_FLOW_OK) {
5978 ret = gst_matroska_demux_check_parse_error (demux);
5980 /* Only handle EOS as no error if we're outside the segment already */
5981 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
5982 && demux->common.offset >=
5983 demux->common.ebml_segment_start +
5984 demux->common.ebml_segment_length))
5986 else if (ret != GST_FLOW_OK)
5992 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
5993 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
5996 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5997 if (ret == GST_FLOW_EOS)
5999 if (ret != GST_FLOW_OK)
6002 /* check if we're at the end of a configured segment */
6003 if (G_LIKELY (demux->common.src->len)) {
6006 g_assert (demux->common.num_streams == demux->common.src->len);
6007 for (i = 0; i < demux->common.src->len; i++) {
6008 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
6010 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
6011 GST_TIME_ARGS (context->pos));
6012 if (context->eos == FALSE)
6016 GST_INFO_OBJECT (demux, "All streams are EOS");
6022 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
6023 demux->common.offset >= demux->cached_length)) {
6024 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
6025 if (demux->common.offset == demux->cached_length) {
6026 GST_LOG_OBJECT (demux, "Reached end of stream");
6037 if (demux->common.segment.rate < 0.0) {
6038 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
6039 if (ret == GST_FLOW_OK)
6046 const gchar *reason = gst_flow_get_name (ret);
6047 gboolean push_eos = FALSE;
6049 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
6050 gst_pad_pause_task (demux->common.sinkpad);
6052 if (ret == GST_FLOW_EOS) {
6053 /* perform EOS logic */
6055 /* If we were in the headers, make sure we send no-more-pads.
6056 This will ensure decodebin does not get stuck thinking
6057 the chain is not complete yet, and waiting indefinitely. */
6058 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
6059 if (demux->common.src->len == 0) {
6060 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
6061 ("No pads created"));
6063 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
6064 ("Failed to finish reading headers"));
6066 gst_element_no_more_pads (GST_ELEMENT (demux));
6069 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
6074 /* for segment playback we need to post when (in stream time)
6075 * we stopped, this is either stop (when set) or the duration. */
6076 if ((stop = demux->common.segment.stop) == -1)
6077 stop = demux->last_stop_end;
6079 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
6080 msg = gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
6082 if (demux->segment_seqnum)
6083 gst_message_set_seqnum (msg, demux->segment_seqnum);
6084 gst_element_post_message (GST_ELEMENT (demux), msg);
6086 event = gst_event_new_segment_done (GST_FORMAT_TIME, stop);
6087 if (demux->segment_seqnum)
6088 gst_event_set_seqnum (event, demux->segment_seqnum);
6089 gst_matroska_demux_send_event (demux, event);
6093 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
6094 /* for fatal errors we post an error message */
6095 GST_ELEMENT_FLOW_ERROR (demux, ret);
6101 /* send EOS, and prevent hanging if no streams yet */
6102 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
6103 event = gst_event_new_eos ();
6104 if (demux->segment_seqnum)
6105 gst_event_set_seqnum (event, demux->segment_seqnum);
6106 if (!gst_matroska_demux_send_event (demux, event) &&
6107 (ret == GST_FLOW_EOS)) {
6108 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
6109 (NULL), ("got eos but no streams (yet)"));
6117 * Create and push a flushing seek event upstream
6120 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
6121 guint32 seqnum, GstSeekFlags flags)
6126 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
6129 gst_event_new_seek (rate, GST_FORMAT_BYTES,
6130 flags | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
6131 GST_SEEK_TYPE_SET, offset, GST_SEEK_TYPE_NONE, -1);
6132 gst_event_set_seqnum (event, seqnum);
6134 res = gst_pad_push_event (demux->common.sinkpad, event);
6136 /* segment event will update offset */
6140 static GstFlowReturn
6141 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
6143 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
6145 GstFlowReturn ret = GST_FLOW_OK;
6150 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
6151 GST_DEBUG_OBJECT (demux, "got DISCONT");
6152 gst_adapter_clear (demux->common.adapter);
6153 GST_OBJECT_LOCK (demux);
6154 gst_matroska_read_common_reset_streams (&demux->common,
6155 GST_CLOCK_TIME_NONE, FALSE);
6156 GST_OBJECT_UNLOCK (demux);
6159 gst_adapter_push (demux->common.adapter, buffer);
6163 available = gst_adapter_available (demux->common.adapter);
6165 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
6166 GST_ELEMENT_CAST (demux), &id, &length, &needed);
6167 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
6168 if (demux->common.ebml_segment_length != G_MAXUINT64
6169 && demux->common.offset >=
6170 demux->common.ebml_segment_start + demux->common.ebml_segment_length) {
6173 gint64 bytes_scanned;
6174 if (demux->common.start_resync_offset == -1) {
6175 demux->common.start_resync_offset = demux->common.offset;
6176 demux->common.state_to_restore = demux->common.state;
6178 bytes_scanned = demux->common.offset - demux->common.start_resync_offset;
6179 if (bytes_scanned <= INVALID_DATA_THRESHOLD) {
6180 GST_WARNING_OBJECT (demux,
6181 "parse error, looking for next cluster, actual offset %"
6182 G_GUINT64_FORMAT ", start resync offset %" G_GUINT64_FORMAT,
6183 demux->common.offset, demux->common.start_resync_offset);
6184 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
6187 GST_WARNING_OBJECT (demux,
6188 "unrecoverable parse error, next cluster not found and threshold "
6189 "exceeded, bytes scanned %" G_GINT64_FORMAT, bytes_scanned);
6195 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
6196 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
6197 demux->common.offset, id, length, needed, available);
6199 if (needed > available)
6202 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
6203 if (ret == GST_FLOW_EOS) {
6204 /* need more data */
6206 } else if (ret != GST_FLOW_OK) {
6213 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
6216 gboolean res = TRUE;
6217 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
6219 GST_DEBUG_OBJECT (demux,
6220 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
6222 switch (GST_EVENT_TYPE (event)) {
6223 case GST_EVENT_SEGMENT:
6225 const GstSegment *segment;
6227 /* some debug output */
6228 gst_event_parse_segment (event, &segment);
6229 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
6230 GST_DEBUG_OBJECT (demux,
6231 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
6234 if (segment->format == GST_FORMAT_TIME) {
6235 demux->upstream_format_is_time = TRUE;
6236 demux->segment_seqnum = gst_event_get_seqnum (event);
6237 gst_segment_copy_into (segment, &demux->common.segment);
6238 GST_DEBUG_OBJECT (demux, "Got segment in TIME format: %" GST_PTR_FORMAT,
6243 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
6244 GST_DEBUG_OBJECT (demux, "still starting");
6248 demux->upstream_format_is_time = FALSE;
6250 /* we only expect a BYTE segment, e.g. following a seek */
6251 if (segment->format != GST_FORMAT_BYTES) {
6252 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
6256 GST_DEBUG_OBJECT (demux, "clearing segment state");
6257 GST_OBJECT_LOCK (demux);
6258 /* clear current segment leftover */
6259 gst_adapter_clear (demux->common.adapter);
6260 /* and some streaming setup */
6261 demux->common.offset = segment->start;
6262 /* accumulate base based on current position */
6263 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
6264 demux->common.segment.base +=
6265 (MAX (demux->common.segment.position, demux->stream_start_time)
6266 - demux->stream_start_time) / fabs (demux->common.segment.rate);
6267 /* do not know where we are;
6268 * need to come across a cluster and generate segment */
6269 demux->common.segment.position = GST_CLOCK_TIME_NONE;
6270 demux->cluster_time = GST_CLOCK_TIME_NONE;
6271 demux->cluster_offset = 0;
6272 demux->cluster_prevsize = 0;
6273 demux->need_segment = TRUE;
6274 demux->segment_seqnum = gst_event_get_seqnum (event);
6275 /* but keep some of the upstream segment */
6276 demux->common.segment.rate = segment->rate;
6277 demux->common.segment.flags = segment->flags;
6278 /* also check if need to keep some of the requested seek position */
6279 if (demux->seek_offset == segment->start) {
6280 GST_DEBUG_OBJECT (demux, "position matches requested seek");
6281 demux->common.segment.position = demux->requested_seek_time;
6283 GST_DEBUG_OBJECT (demux, "unexpected segment position");
6285 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
6286 demux->seek_offset = -1;
6287 GST_OBJECT_UNLOCK (demux);
6289 /* chain will send initial segment after pads have been added,
6290 * or otherwise come up with one */
6291 GST_DEBUG_OBJECT (demux, "eating event");
6292 gst_event_unref (event);
6298 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA
6299 && demux->common.state != GST_MATROSKA_READ_STATE_SCANNING) {
6300 gst_event_unref (event);
6301 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
6302 (NULL), ("got eos and didn't receive a complete header object"));
6303 } else if (demux->common.num_streams == 0) {
6304 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
6305 (NULL), ("got eos but no streams (yet)"));
6307 gst_matroska_demux_send_event (demux, event);
6311 case GST_EVENT_FLUSH_STOP:
6315 gst_adapter_clear (demux->common.adapter);
6316 GST_OBJECT_LOCK (demux);
6317 gst_matroska_read_common_reset_streams (&demux->common,
6318 GST_CLOCK_TIME_NONE, TRUE);
6319 gst_flow_combiner_reset (demux->flowcombiner);
6320 dur = demux->common.segment.duration;
6321 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
6322 demux->common.segment.duration = dur;
6323 demux->cluster_time = GST_CLOCK_TIME_NONE;
6324 demux->cluster_offset = 0;
6325 demux->cluster_prevsize = 0;
6326 GST_OBJECT_UNLOCK (demux);
6330 res = gst_pad_event_default (pad, parent, event);
6338 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
6340 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
6342 gboolean pull_mode = FALSE;
6344 query = gst_query_new_scheduling ();
6346 if (gst_pad_peer_query (sinkpad, query))
6347 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
6348 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
6350 gst_query_unref (query);
6353 GST_DEBUG ("going to pull mode");
6354 demux->streaming = FALSE;
6355 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
6357 GST_DEBUG ("going to push (streaming) mode");
6358 demux->streaming = TRUE;
6359 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
6364 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
6365 GstPadMode mode, gboolean active)
6368 case GST_PAD_MODE_PULL:
6370 /* if we have a scheduler we can start the task */
6371 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
6374 gst_pad_stop_task (sinkpad);
6377 case GST_PAD_MODE_PUSH:
6385 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
6386 videocontext, const gchar * codec_id, guint8 * data, guint size,
6387 gchar ** codec_name, guint32 * riff_fourcc)
6389 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
6390 GstCaps *caps = NULL;
6392 g_assert (videocontext != NULL);
6393 g_assert (codec_name != NULL);
6398 /* TODO: check if we have all codec types from matroska-ids.h
6399 * check if we have to do more special things with codec_private
6402 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
6403 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
6406 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
6407 gst_riff_strf_vids *vids = NULL;
6410 GstBuffer *buf = NULL;
6412 vids = (gst_riff_strf_vids *) data;
6414 /* assure size is big enough */
6416 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
6419 if (size < sizeof (gst_riff_strf_vids)) {
6420 vids = g_new (gst_riff_strf_vids, 1);
6421 memcpy (vids, data, size);
6424 context->dts_only = TRUE; /* VFW files only store DTS */
6426 /* little-endian -> byte-order */
6427 vids->size = GUINT32_FROM_LE (vids->size);
6428 vids->width = GUINT32_FROM_LE (vids->width);
6429 vids->height = GUINT32_FROM_LE (vids->height);
6430 vids->planes = GUINT16_FROM_LE (vids->planes);
6431 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
6432 vids->compression = GUINT32_FROM_LE (vids->compression);
6433 vids->image_size = GUINT32_FROM_LE (vids->image_size);
6434 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
6435 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
6436 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
6437 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
6439 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
6440 gsize offset = sizeof (gst_riff_strf_vids);
6442 buf = gst_buffer_new_memdup ((guint8 *) vids + offset, size - offset);
6446 *riff_fourcc = vids->compression;
6448 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
6449 buf, NULL, codec_name);
6452 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
6453 GST_FOURCC_ARGS (vids->compression));
6455 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
6456 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
6457 "video/x-compressed-yuv");
6458 context->intra_only =
6459 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
6463 gst_buffer_unref (buf);
6465 if (vids != (gst_riff_strf_vids *) data)
6468 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
6470 GstVideoFormat format;
6472 gst_video_info_init (&info);
6473 switch (videocontext->fourcc) {
6474 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
6475 format = GST_VIDEO_FORMAT_I420;
6477 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
6478 format = GST_VIDEO_FORMAT_YUY2;
6480 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
6481 format = GST_VIDEO_FORMAT_YV12;
6483 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
6484 format = GST_VIDEO_FORMAT_UYVY;
6486 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
6487 format = GST_VIDEO_FORMAT_AYUV;
6489 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
6490 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
6491 format = GST_VIDEO_FORMAT_GRAY8;
6493 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
6494 format = GST_VIDEO_FORMAT_RGB;
6496 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
6497 format = GST_VIDEO_FORMAT_BGR;
6500 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
6501 GST_FOURCC_ARGS (videocontext->fourcc));
6505 context->intra_only = TRUE;
6507 gst_video_info_set_format (&info, format, videocontext->pixel_width,
6508 videocontext->pixel_height);
6509 caps = gst_video_info_to_caps (&info);
6510 *codec_name = gst_pb_utils_get_codec_description (caps);
6511 context->alignment = 32;
6512 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
6513 caps = gst_caps_new_simple ("video/x-divx",
6514 "divxversion", G_TYPE_INT, 4, NULL);
6515 *codec_name = g_strdup ("MPEG-4 simple profile");
6516 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
6517 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
6518 caps = gst_caps_new_simple ("video/mpeg",
6519 "mpegversion", G_TYPE_INT, 4,
6520 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
6524 priv = gst_buffer_new_memdup (data, size);
6525 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6526 gst_buffer_unref (priv);
6528 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
6530 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
6531 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
6533 *codec_name = g_strdup ("MPEG-4 advanced profile");
6534 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
6536 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
6537 "divxversion", G_TYPE_INT, 3, NULL),
6538 gst_structure_new ("video/x-msmpeg",
6539 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
6541 caps = gst_caps_new_simple ("video/x-msmpeg",
6542 "msmpegversion", G_TYPE_INT, 43, NULL);
6543 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
6544 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
6545 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
6548 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
6553 caps = gst_caps_new_simple ("video/mpeg",
6554 "systemstream", G_TYPE_BOOLEAN, FALSE,
6555 "mpegversion", G_TYPE_INT, mpegversion, NULL);
6556 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
6557 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
6558 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
6559 caps = gst_caps_new_empty_simple ("image/jpeg");
6560 *codec_name = g_strdup ("Motion-JPEG");
6561 context->intra_only = TRUE;
6562 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
6563 caps = gst_caps_new_empty_simple ("video/x-h264");
6567 /* First byte is the version, second is the profile indication, and third
6568 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
6569 * level indication. */
6570 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
6573 priv = gst_buffer_new_memdup (data, size);
6574 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6575 gst_buffer_unref (priv);
6577 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
6578 "alignment", G_TYPE_STRING, "au", NULL);
6580 GST_WARNING ("No codec data found, assuming output is byte-stream");
6581 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
6584 *codec_name = g_strdup ("H264");
6585 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
6586 caps = gst_caps_new_empty_simple ("video/x-h265");
6590 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
6593 priv = gst_buffer_new_memdup (data, size);
6594 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6595 gst_buffer_unref (priv);
6597 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
6598 "alignment", G_TYPE_STRING, "au", NULL);
6600 GST_WARNING ("No codec data found, assuming output is byte-stream");
6601 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
6604 *codec_name = g_strdup ("HEVC");
6605 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
6606 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
6607 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
6608 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
6609 gint rmversion = -1;
6611 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
6613 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
6615 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
6617 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
6620 caps = gst_caps_new_simple ("video/x-pn-realvideo",
6621 "rmversion", G_TYPE_INT, rmversion, NULL);
6622 GST_DEBUG ("data:%p, size:0x%x", data, size);
6623 /* We need to extract the extradata ! */
6624 if (data && (size >= 0x22)) {
6629 subformat = GST_READ_UINT32_BE (data + 0x1a);
6630 rformat = GST_READ_UINT32_BE (data + 0x1e);
6632 priv = gst_buffer_new_memdup (data + 0x1a, size - 0x1a);
6633 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
6634 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
6635 gst_buffer_unref (priv);
6638 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
6639 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
6640 caps = gst_caps_new_empty_simple ("video/x-theora");
6641 context->stream_headers =
6642 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6643 context->codec_priv_size);
6644 /* FIXME: mark stream as broken and skip if there are no stream headers */
6645 context->send_stream_headers = TRUE;
6646 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
6647 caps = gst_caps_new_empty_simple ("video/x-dirac");
6648 *codec_name = g_strdup_printf ("Dirac");
6649 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
6650 caps = gst_caps_new_empty_simple ("video/x-vp8");
6651 if (videocontext->alpha_mode)
6652 gst_caps_set_simple (caps, "codec-alpha", G_TYPE_BOOLEAN, TRUE, NULL);
6653 *codec_name = g_strdup_printf ("On2 VP8");
6654 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
6655 caps = gst_caps_new_empty_simple ("video/x-vp9");
6656 if (videocontext->alpha_mode)
6657 gst_caps_set_simple (caps, "codec-alpha", G_TYPE_BOOLEAN, TRUE, NULL);
6658 *codec_name = g_strdup_printf ("On2 VP9");
6659 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_AV1)) {
6660 caps = gst_caps_new_simple ("video/x-av1",
6661 "stream-format", G_TYPE_STRING, "obu-stream",
6662 "alignment", G_TYPE_STRING, "tu", NULL);
6666 priv = gst_buffer_new_memdup (data, size);
6667 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6668 gst_buffer_unref (priv);
6670 GST_WARNING ("No AV1 codec data found!");
6672 *codec_name = g_strdup_printf ("AOM AV1");
6673 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_FFV1)) {
6675 gst_caps_new_simple ("video/x-ffv", "ffvversion", G_TYPE_INT, 1, NULL);
6679 priv = gst_buffer_new_memdup (data, size);
6680 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6681 gst_buffer_unref (priv);
6683 GST_WARNING ("No FFV1 codec data found!");
6685 *codec_name = g_strdup_printf ("FFMpeg v1");
6686 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
6688 const gchar *variant, *variant_descr = "";
6690 /* Expect a fourcc in the codec private data */
6691 if (data && size >= 4) {
6692 fourcc = GST_STR_FOURCC (data);
6694 GST_WARNING ("No ProRes codec data found, picking 'standard 422 SD'");
6698 case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
6699 variant_descr = " 4:2:2 LT";
6702 case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
6704 variant_descr = " 4:2:2 HQ";
6706 case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
6708 variant_descr = " 4:4:4:4";
6710 case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
6712 variant_descr = " 4:2:2 Proxy";
6714 case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
6716 variant = "standard";
6717 variant_descr = " 4:2:2 SD";
6721 GST_LOG ("Prores video, codec fourcc %" GST_FOURCC_FORMAT,
6722 GST_FOURCC_ARGS (fourcc));
6724 caps = gst_caps_new_simple ("video/x-prores",
6725 "format", G_TYPE_STRING, variant, NULL);
6726 *codec_name = g_strdup_printf ("Apple ProRes%s", variant_descr);
6727 context->postprocess_frame = gst_matroska_demux_add_prores_header;
6729 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6735 GstStructure *structure;
6737 for (i = 0; i < gst_caps_get_size (caps); i++) {
6738 structure = gst_caps_get_structure (caps, i);
6740 /* FIXME: use the real unit here! */
6741 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
6742 videocontext->pixel_width,
6743 videocontext->pixel_height,
6744 videocontext->display_width, videocontext->display_height);
6746 /* pixel width and height are the w and h of the video in pixels */
6747 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
6748 gint w = videocontext->pixel_width;
6749 gint h = videocontext->pixel_height;
6751 gst_structure_set (structure,
6752 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
6755 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
6758 if (videocontext->display_width <= 0)
6759 videocontext->display_width = videocontext->pixel_width;
6760 if (videocontext->display_height <= 0)
6761 videocontext->display_height = videocontext->pixel_height;
6763 /* calculate the pixel aspect ratio using the display and pixel w/h */
6764 n = videocontext->display_width * videocontext->pixel_height;
6765 d = videocontext->display_height * videocontext->pixel_width;
6766 GST_DEBUG ("setting PAR to %d/%d", n, d);
6767 gst_structure_set (structure, "pixel-aspect-ratio",
6769 videocontext->display_width * videocontext->pixel_height,
6770 videocontext->display_height * videocontext->pixel_width, NULL);
6773 if (videocontext->default_fps > 0.0) {
6776 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
6778 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
6780 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
6782 } else if (context->default_duration > 0) {
6785 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
6787 GST_INFO ("using default duration %" G_GUINT64_FORMAT
6788 " framerate %d/%d", context->default_duration, fps_n, fps_d);
6790 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
6791 fps_n, fps_d, NULL);
6793 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
6797 switch (videocontext->interlace_mode) {
6798 case GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE:
6799 gst_structure_set (structure,
6800 "interlace-mode", G_TYPE_STRING, "progressive", NULL);
6802 case GST_MATROSKA_INTERLACE_MODE_INTERLACED:
6803 gst_structure_set (structure,
6804 "interlace-mode", G_TYPE_STRING, "interleaved", NULL);
6806 if (videocontext->field_order != GST_VIDEO_FIELD_ORDER_UNKNOWN)
6807 gst_structure_set (structure, "field-order", G_TYPE_STRING,
6808 gst_video_field_order_to_string (videocontext->field_order),
6815 if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
6816 if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
6817 videocontext->pixel_width, videocontext->pixel_height,
6818 videocontext->display_width * videocontext->pixel_height,
6819 videocontext->display_height * videocontext->pixel_width)) {
6820 videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
6822 gst_caps_set_simple (caps,
6823 "multiview-mode", G_TYPE_STRING,
6824 gst_video_multiview_mode_to_caps_string
6825 (videocontext->multiview_mode), "multiview-flags",
6826 GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
6827 GST_FLAG_SET_MASK_EXACT, NULL);
6830 if (videocontext->colorimetry.range != GST_VIDEO_COLOR_RANGE_UNKNOWN ||
6831 videocontext->colorimetry.matrix != GST_VIDEO_COLOR_MATRIX_UNKNOWN ||
6832 videocontext->colorimetry.transfer != GST_VIDEO_TRANSFER_UNKNOWN ||
6833 videocontext->colorimetry.primaries !=
6834 GST_VIDEO_COLOR_PRIMARIES_UNKNOWN) {
6835 gchar *colorimetry =
6836 gst_video_colorimetry_to_string (&videocontext->colorimetry);
6837 gst_caps_set_simple (caps, "colorimetry", G_TYPE_STRING, colorimetry,
6839 GST_DEBUG ("setting colorimetry to %s", colorimetry);
6840 g_free (colorimetry);
6843 if (videocontext->mastering_display_info_present) {
6844 if (!gst_video_mastering_display_info_add_to_caps
6845 (&videocontext->mastering_display_info, caps)) {
6846 GST_WARNING ("couldn't set mastering display info to caps");
6850 if (videocontext->content_light_level.max_content_light_level &&
6851 videocontext->content_light_level.max_frame_average_light_level) {
6852 if (!gst_video_content_light_level_add_to_caps
6853 (&videocontext->content_light_level, caps)) {
6854 GST_WARNING ("couldn't set content light level to caps");
6858 caps = gst_caps_simplify (caps);
6865 * Some AAC specific code... *sigh*
6866 * FIXME: maybe we should use '15' and code the sample rate explicitly
6867 * if the sample rate doesn't match the predefined rates exactly? (tpm)
6871 aac_rate_idx (gint rate)
6875 else if (75132 <= rate)
6877 else if (55426 <= rate)
6879 else if (46009 <= rate)
6881 else if (37566 <= rate)
6883 else if (27713 <= rate)
6885 else if (23004 <= rate)
6887 else if (18783 <= rate)
6889 else if (13856 <= rate)
6891 else if (11502 <= rate)
6893 else if (9391 <= rate)
6900 aac_profile_idx (const gchar * codec_id)
6904 if (strlen (codec_id) <= 12)
6906 else if (!strncmp (&codec_id[12], "MAIN", 4))
6908 else if (!strncmp (&codec_id[12], "LC", 2))
6910 else if (!strncmp (&codec_id[12], "SSR", 3))
6919 round_up_pow2 (guint n)
6930 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
6933 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
6934 audiocontext, const gchar * codec_id, guint8 * data, guint size,
6935 gchar ** codec_name, guint16 * riff_audio_fmt, GstClockTime * lead_in_ts)
6937 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
6938 GstCaps *caps = NULL;
6940 /* Max potential blocksize causing the longest possible lead_in_ts need, as
6941 * we don't have the exact number parsed out here */
6942 guint max_blocksize = 0;
6943 /* Original samplerate before SBR multiplications, as parsers would use */
6944 guint rate = audiocontext->samplerate;
6946 g_assert (audiocontext != NULL);
6947 g_assert (codec_name != NULL);
6950 *riff_audio_fmt = 0;
6952 /* TODO: check if we have all codec types from matroska-ids.h
6953 * check if we have to do more special things with codec_private
6954 * check if we need bitdepth in different places too
6955 * implement channel position magic
6957 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
6958 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
6959 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
6960 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
6963 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
6964 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
6965 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
6968 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
6970 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
6975 lead_in = 30; /* Could mp2 need as much too? */
6976 max_blocksize = 1152;
6977 caps = gst_caps_new_simple ("audio/mpeg",
6978 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
6979 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
6980 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
6981 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
6984 GstAudioFormat format;
6986 sign = (audiocontext->bitdepth != 8);
6987 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
6988 endianness = G_BIG_ENDIAN;
6990 endianness = G_LITTLE_ENDIAN;
6992 format = gst_audio_format_build_integer (sign, endianness,
6993 audiocontext->bitdepth, audiocontext->bitdepth);
6995 /* FIXME: Channel mask and reordering */
6996 caps = gst_caps_new_simple ("audio/x-raw",
6997 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
6998 "layout", G_TYPE_STRING, "interleaved",
6999 "channel-mask", GST_TYPE_BITMASK,
7000 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
7002 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
7003 audiocontext->bitdepth);
7004 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
7005 context->alignment = round_up_pow2 (context->alignment);
7006 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
7007 const gchar *format;
7008 if (audiocontext->bitdepth == 32)
7012 /* FIXME: Channel mask and reordering */
7013 caps = gst_caps_new_simple ("audio/x-raw",
7014 "format", G_TYPE_STRING, format,
7015 "layout", G_TYPE_STRING, "interleaved",
7016 "channel-mask", GST_TYPE_BITMASK,
7017 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
7018 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
7019 audiocontext->bitdepth);
7020 context->alignment = audiocontext->bitdepth / 8;
7021 context->alignment = round_up_pow2 (context->alignment);
7022 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
7023 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
7025 max_blocksize = 1536;
7026 caps = gst_caps_new_simple ("audio/x-ac3",
7027 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
7028 *codec_name = g_strdup ("AC-3 audio");
7029 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
7030 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
7032 max_blocksize = 1536;
7033 caps = gst_caps_new_simple ("audio/x-eac3",
7034 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
7035 *codec_name = g_strdup ("E-AC-3 audio");
7036 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
7037 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
7038 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
7039 *codec_name = g_strdup ("Dolby TrueHD");
7040 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
7041 caps = gst_caps_new_empty_simple ("audio/x-dts");
7042 *codec_name = g_strdup ("DTS audio");
7043 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
7044 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
7045 context->stream_headers =
7046 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
7047 context->codec_priv_size);
7048 /* FIXME: mark stream as broken and skip if there are no stream headers */
7049 context->send_stream_headers = TRUE;
7050 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
7051 caps = gst_caps_new_empty_simple ("audio/x-flac");
7052 context->stream_headers =
7053 gst_matroska_parse_flac_stream_headers (context->codec_priv,
7054 context->codec_priv_size);
7055 /* FIXME: mark stream as broken and skip if there are no stream headers */
7056 context->send_stream_headers = TRUE;
7057 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
7058 caps = gst_caps_new_empty_simple ("audio/x-speex");
7059 context->stream_headers =
7060 gst_matroska_parse_speex_stream_headers (context->codec_priv,
7061 context->codec_priv_size);
7062 /* FIXME: mark stream as broken and skip if there are no stream headers */
7063 context->send_stream_headers = TRUE;
7064 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
7067 if (context->codec_priv_size >= 19) {
7068 if (audiocontext->samplerate)
7069 GST_WRITE_UINT32_LE ((guint8 *) context->codec_priv + 12,
7070 audiocontext->samplerate);
7071 if (context->codec_delay) {
7073 gst_util_uint64_scale_round (context->codec_delay, 48000,
7075 GST_WRITE_UINT16_LE ((guint8 *) context->codec_priv + 10, delay);
7079 gst_buffer_new_memdup (context->codec_priv, context->codec_priv_size);
7080 caps = gst_codec_utils_opus_create_caps_from_header (tmp, NULL);
7081 gst_buffer_unref (tmp);
7082 *codec_name = g_strdup ("Opus");
7083 } else if (context->codec_priv_size == 0) {
7084 GST_WARNING ("No Opus codec data found, trying to create one");
7085 if (audiocontext->channels <= 2) {
7086 guint8 streams, coupled, channels;
7090 audiocontext->samplerate == 0 ? 48000 : audiocontext->samplerate;
7092 channels = audiocontext->channels == 0 ? 2 : audiocontext->channels;
7093 if (channels == 1) {
7102 gst_codec_utils_opus_create_caps (samplerate, channels, 0, streams,
7105 *codec_name = g_strdup ("Opus");
7107 GST_WARNING ("Failed to create Opus caps from audio context");
7110 GST_WARNING ("No Opus codec data, and not enough info to create one");
7113 GST_WARNING ("Invalid Opus codec data size (got %" G_GSIZE_FORMAT
7114 ", expected 19)", context->codec_priv_size);
7116 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
7117 gst_riff_strf_auds auds;
7119 if (data && size >= 18) {
7120 GstBuffer *codec_data = NULL;
7122 /* little-endian -> byte-order */
7123 auds.format = GST_READ_UINT16_LE (data);
7124 auds.channels = GST_READ_UINT16_LE (data + 2);
7125 auds.rate = GST_READ_UINT32_LE (data + 4);
7126 auds.av_bps = GST_READ_UINT32_LE (data + 8);
7127 auds.blockalign = GST_READ_UINT16_LE (data + 12);
7128 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
7130 /* 18 is the waveformatex size */
7132 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
7133 data + 18, size - 18, 0, size - 18, NULL, NULL);
7137 *riff_audio_fmt = auds.format;
7139 /* FIXME: Handle reorder map */
7140 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, codec_data,
7141 NULL, codec_name, NULL);
7143 gst_buffer_unref (codec_data);
7146 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
7149 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
7151 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
7152 GstBuffer *priv = NULL;
7154 gint rate_idx, profile;
7155 guint8 *data = NULL;
7157 /* unspecified AAC profile with opaque private codec data */
7158 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
7159 if (context->codec_priv_size >= 2) {
7160 guint obj_type, freq_index, explicit_freq_bytes = 0;
7162 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
7164 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
7165 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
7166 if (freq_index == 15)
7167 explicit_freq_bytes = 3;
7168 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
7169 priv = gst_buffer_new_memdup (context->codec_priv,
7170 context->codec_priv_size);
7171 /* assume SBR if samplerate <= 24kHz */
7172 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
7173 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
7174 /* TODO: Commonly aacparse will reset the rate in caps to
7175 * non-multiplied - which one is correct? */
7176 audiocontext->samplerate *= 2;
7179 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
7180 /* this is pretty broken;
7181 * maybe we need to make up some default private,
7182 * or maybe ADTS data got dumped in.
7183 * Let's set up some private data now, and check actual data later */
7184 /* just try this and see what happens ... */
7185 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
7186 context->postprocess_frame = gst_matroska_demux_check_aac;
7190 /* make up decoder-specific data if it is not supplied */
7194 priv = gst_buffer_new_allocate (NULL, 5, NULL);
7195 gst_buffer_map (priv, &map, GST_MAP_WRITE);
7197 rate_idx = aac_rate_idx (audiocontext->samplerate);
7198 profile = aac_profile_idx (codec_id);
7200 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
7201 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
7203 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
7204 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
7206 gst_buffer_unmap (priv, &map);
7207 gst_buffer_set_size (priv, 2);
7208 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
7209 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
7212 if (g_strrstr (codec_id, "SBR")) {
7213 /* HE-AAC (aka SBR AAC) */
7214 audiocontext->samplerate *= 2;
7215 rate_idx = aac_rate_idx (audiocontext->samplerate);
7216 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
7217 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
7218 data[4] = (1 << 7) | (rate_idx << 3);
7219 gst_buffer_unmap (priv, &map);
7221 gst_buffer_unmap (priv, &map);
7222 gst_buffer_set_size (priv, 2);
7225 gst_buffer_unmap (priv, &map);
7226 gst_buffer_unref (priv);
7228 GST_ERROR ("Unknown AAC profile and no codec private data");
7234 max_blocksize = 1024;
7235 caps = gst_caps_new_simple ("audio/mpeg",
7236 "mpegversion", G_TYPE_INT, mpegversion,
7237 "framed", G_TYPE_BOOLEAN, TRUE,
7238 "stream-format", G_TYPE_STRING, "raw", NULL);
7239 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
7240 if (context->codec_priv && context->codec_priv_size > 0)
7241 gst_codec_utils_aac_caps_set_level_and_profile (caps,
7242 context->codec_priv, context->codec_priv_size);
7243 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
7244 gst_buffer_unref (priv);
7246 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
7247 caps = gst_caps_new_simple ("audio/x-tta",
7248 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
7249 *codec_name = g_strdup ("TTA audio");
7250 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
7251 caps = gst_caps_new_simple ("audio/x-wavpack",
7252 "width", G_TYPE_INT, audiocontext->bitdepth,
7253 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
7254 *codec_name = g_strdup ("Wavpack audio");
7255 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
7256 audiocontext->wvpk_block_index = 0;
7257 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
7258 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
7259 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
7260 gint raversion = -1;
7262 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
7264 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
7269 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
7270 "raversion", G_TYPE_INT, raversion, NULL);
7271 /* Extract extra information from caps, mapping varies based on codec */
7272 if (data && (size >= 0x50)) {
7279 guint extra_data_size;
7281 GST_DEBUG ("real audio raversion:%d", raversion);
7282 if (raversion == 8) {
7284 flavor = GST_READ_UINT16_BE (data + 22);
7285 packet_size = GST_READ_UINT32_BE (data + 24);
7286 height = GST_READ_UINT16_BE (data + 40);
7287 leaf_size = GST_READ_UINT16_BE (data + 44);
7288 sample_width = GST_READ_UINT16_BE (data + 58);
7289 extra_data_size = GST_READ_UINT32_BE (data + 74);
7292 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
7293 flavor, packet_size, height, leaf_size, sample_width,
7295 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
7296 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
7297 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
7299 if ((size - 78) >= extra_data_size) {
7300 priv = gst_buffer_new_memdup (data + 78, extra_data_size);
7301 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
7302 gst_buffer_unref (priv);
7307 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
7308 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
7309 caps = gst_caps_new_empty_simple ("audio/x-sipro");
7310 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
7311 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
7312 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
7313 *codec_name = g_strdup ("Real Audio Lossless");
7314 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
7315 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
7316 *codec_name = g_strdup ("Sony ATRAC3");
7318 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
7323 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
7326 for (i = 0; i < gst_caps_get_size (caps); i++) {
7327 gst_structure_set (gst_caps_get_structure (caps, i),
7328 "channels", G_TYPE_INT, audiocontext->channels,
7329 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
7333 caps = gst_caps_simplify (caps);
7336 if (lead_in_ts && lead_in && max_blocksize && rate) {
7338 gst_util_uint64_scale (GST_SECOND, max_blocksize * lead_in, rate);
7345 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
7346 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
7348 GstCaps *caps = NULL;
7349 GstMatroskaTrackContext *context =
7350 (GstMatroskaTrackContext *) subtitlecontext;
7352 /* for backwards compatibility */
7353 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
7354 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
7355 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
7356 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
7357 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
7358 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
7359 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
7360 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
7362 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
7363 * Check if we have to do something with codec_private */
7364 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
7365 /* well, plain text simply does not have a lot of markup ... */
7366 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
7367 "pango-markup", NULL);
7368 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
7369 subtitlecontext->check_markup = TRUE;
7370 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
7371 caps = gst_caps_new_empty_simple ("application/x-ssa");
7372 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
7373 subtitlecontext->check_markup = FALSE;
7374 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
7375 caps = gst_caps_new_empty_simple ("application/x-ass");
7376 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
7377 subtitlecontext->check_markup = FALSE;
7378 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
7379 caps = gst_caps_new_empty_simple ("application/x-usf");
7380 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
7381 subtitlecontext->check_markup = FALSE;
7382 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
7383 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
7384 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
7385 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
7386 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
7387 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
7388 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
7389 context->stream_headers =
7390 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
7391 context->codec_priv_size);
7392 /* FIXME: mark stream as broken and skip if there are no stream headers */
7393 context->send_stream_headers = TRUE;
7395 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
7396 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
7399 if (data != NULL && size > 0) {
7402 buf = gst_buffer_new_memdup (data, size);
7403 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
7404 gst_buffer_unref (buf);
7412 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
7414 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
7416 GST_OBJECT_LOCK (demux);
7417 if (demux->common.element_index)
7418 gst_object_unref (demux->common.element_index);
7419 demux->common.element_index = index ? gst_object_ref (index) : NULL;
7420 GST_OBJECT_UNLOCK (demux);
7421 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
7422 demux->common.element_index);
7426 gst_matroska_demux_get_index (GstElement * element)
7428 GstIndex *result = NULL;
7429 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
7431 GST_OBJECT_LOCK (demux);
7432 if (demux->common.element_index)
7433 result = gst_object_ref (demux->common.element_index);
7434 GST_OBJECT_UNLOCK (demux);
7436 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
7442 static GstStateChangeReturn
7443 gst_matroska_demux_change_state (GstElement * element,
7444 GstStateChange transition)
7446 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
7447 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
7449 /* handle upwards state changes here */
7450 switch (transition) {
7455 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
7457 /* handle downwards state changes */
7458 switch (transition) {
7459 case GST_STATE_CHANGE_PAUSED_TO_READY:
7460 gst_matroska_demux_reset (GST_ELEMENT (demux));
7470 gst_matroska_demux_set_property (GObject * object,
7471 guint prop_id, const GValue * value, GParamSpec * pspec)
7473 GstMatroskaDemux *demux;
7475 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
7476 demux = GST_MATROSKA_DEMUX (object);
7479 case PROP_MAX_GAP_TIME:
7480 GST_OBJECT_LOCK (demux);
7481 demux->max_gap_time = g_value_get_uint64 (value);
7482 GST_OBJECT_UNLOCK (demux);
7484 case PROP_MAX_BACKTRACK_DISTANCE:
7485 GST_OBJECT_LOCK (demux);
7486 demux->max_backtrack_distance = g_value_get_uint (value);
7487 GST_OBJECT_UNLOCK (demux);
7490 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
7496 gst_matroska_demux_get_property (GObject * object,
7497 guint prop_id, GValue * value, GParamSpec * pspec)
7499 GstMatroskaDemux *demux;
7501 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
7502 demux = GST_MATROSKA_DEMUX (object);
7505 case PROP_MAX_GAP_TIME:
7506 GST_OBJECT_LOCK (demux);
7507 g_value_set_uint64 (value, demux->max_gap_time);
7508 GST_OBJECT_UNLOCK (demux);
7510 case PROP_MAX_BACKTRACK_DISTANCE:
7511 GST_OBJECT_LOCK (demux);
7512 g_value_set_uint (value, demux->max_backtrack_distance);
7513 GST_OBJECT_UNLOCK (demux);
7516 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
7521 static const gchar *
7522 gst_matroska_track_encryption_algorithm_name (gint val)
7525 GEnumClass *enum_class =
7526 g_type_class_ref (MATROSKA_TRACK_ENCRYPTION_ALGORITHM_TYPE);
7527 en = g_enum_get_value (G_ENUM_CLASS (enum_class), val);
7528 return en ? en->value_nick : NULL;
7531 static const gchar *
7532 gst_matroska_track_encryption_cipher_mode_name (gint val)
7535 GEnumClass *enum_class =
7536 g_type_class_ref (MATROSKA_TRACK_ENCRYPTION_CIPHER_MODE_TYPE);
7537 en = g_enum_get_value (G_ENUM_CLASS (enum_class), val);
7538 return en ? en->value_nick : NULL;
7541 static const gchar *
7542 gst_matroska_track_encoding_scope_name (gint val)
7545 GEnumClass *enum_class =
7546 g_type_class_ref (MATROSKA_TRACK_ENCODING_SCOPE_TYPE);
7548 en = g_enum_get_value (G_ENUM_CLASS (enum_class), val);
7549 return en ? en->value_nick : NULL;