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/video.h>
69 #include "matroska-demux.h"
70 #include "matroska-ids.h"
72 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
73 #define GST_CAT_DEFAULT matroskademux_debug
75 #define DEBUG_ELEMENT_START(demux, ebml, element) \
76 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
77 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
79 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
80 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
81 " finished with '%s'", gst_flow_get_name (ret))
89 PROP_MAX_BACKTRACK_DISTANCE
92 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
93 #define DEFAULT_MAX_BACKTRACK_DISTANCE 30
94 #define INVALID_DATA_THRESHOLD (2 * 1024 * 1024)
96 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
99 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
100 "video/x-matroska-3d; audio/webm; video/webm")
103 /* TODO: fill in caps! */
105 static GstStaticPadTemplate audio_src_templ =
106 GST_STATIC_PAD_TEMPLATE ("audio_%u",
109 GST_STATIC_CAPS ("ANY")
112 static GstStaticPadTemplate video_src_templ =
113 GST_STATIC_PAD_TEMPLATE ("video_%u",
116 GST_STATIC_CAPS ("ANY")
119 static GstStaticPadTemplate subtitle_src_templ =
120 GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
123 GST_STATIC_CAPS ("text/x-raw, format=pango-markup; application/x-ssa; "
124 "application/x-ass;application/x-usf; subpicture/x-dvd; "
125 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
128 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
129 guint32 id, guint64 length, guint needed);
131 /* element functions */
132 static void gst_matroska_demux_loop (GstPad * pad);
134 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
136 static gboolean gst_matroska_demux_element_query (GstElement * element,
140 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad,
142 static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
143 GstObject * parent, GstPadMode mode, gboolean active);
145 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
146 GstPad * pad, GstEvent * event);
147 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
148 GstObject * parent, GstEvent * event);
149 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
150 GstObject * parent, GstQuery * query);
152 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
153 GstObject * parent, GstEvent * event);
154 static gboolean gst_matroska_demux_handle_sink_query (GstPad * pad,
155 GstObject * parent, GstQuery * query);
156 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
157 GstObject * object, GstBuffer * buffer);
159 static GstStateChangeReturn
160 gst_matroska_demux_change_state (GstElement * element,
161 GstStateChange transition);
164 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
165 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
169 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
170 * videocontext, const gchar * codec_id, guint8 * data, guint size,
171 gchar ** codec_name, guint32 * riff_fourcc);
172 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
173 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
174 gchar ** codec_name, guint16 * riff_audio_fmt);
176 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
177 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
178 static const gchar *gst_matroska_track_encryption_algorithm_name (gint val);
179 static const gchar *gst_matroska_track_encryption_cipher_mode_name (gint val);
180 static const gchar *gst_matroska_track_encoding_scope_name (gint val);
183 static void gst_matroska_demux_reset (GstElement * element);
184 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
185 gdouble rate, guint64 offset, guint32 seqnum, GstSeekFlags flags);
187 /* gobject functions */
188 static void gst_matroska_demux_set_property (GObject * object,
189 guint prop_id, const GValue * value, GParamSpec * pspec);
190 static void gst_matroska_demux_get_property (GObject * object,
191 guint prop_id, GValue * value, GParamSpec * pspec);
193 GType gst_matroska_demux_get_type (void);
194 #define parent_class gst_matroska_demux_parent_class
195 G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
198 gst_matroska_demux_finalize (GObject * object)
200 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
202 gst_matroska_read_common_finalize (&demux->common);
203 gst_flow_combiner_free (demux->flowcombiner);
204 G_OBJECT_CLASS (parent_class)->finalize (object);
208 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
210 GObjectClass *gobject_class = (GObjectClass *) klass;
211 GstElementClass *gstelement_class = (GstElementClass *) klass;
213 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
216 gobject_class->finalize = gst_matroska_demux_finalize;
218 gobject_class->get_property = gst_matroska_demux_get_property;
219 gobject_class->set_property = gst_matroska_demux_set_property;
221 g_object_class_install_property (gobject_class, PROP_MAX_GAP_TIME,
222 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
223 "The demuxer sends out segment events for skipping "
224 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
225 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
227 g_object_class_install_property (gobject_class, PROP_MAX_BACKTRACK_DISTANCE,
228 g_param_spec_uint ("max-backtrack-distance",
229 "Maximum backtrack distance",
230 "Maximum backtrack distance in seconds when seeking without "
231 "and index in pull mode and search for a keyframe "
232 "(0 = disable backtracking).",
233 0, G_MAXUINT, DEFAULT_MAX_BACKTRACK_DISTANCE,
234 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
236 gstelement_class->change_state =
237 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
238 gstelement_class->send_event =
239 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
240 gstelement_class->query =
241 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
243 gstelement_class->set_index =
244 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
245 gstelement_class->get_index =
246 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
249 gst_element_class_add_static_pad_template (gstelement_class,
251 gst_element_class_add_static_pad_template (gstelement_class,
253 gst_element_class_add_static_pad_template (gstelement_class,
254 &subtitle_src_templ);
255 gst_element_class_add_static_pad_template (gstelement_class, &sink_templ);
257 gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
259 "Demuxes Matroska/WebM streams into video/audio/subtitles",
260 "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
264 gst_matroska_demux_init (GstMatroskaDemux * demux)
266 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
268 gst_pad_set_activate_function (demux->common.sinkpad,
269 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
270 gst_pad_set_activatemode_function (demux->common.sinkpad,
271 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
272 gst_pad_set_chain_function (demux->common.sinkpad,
273 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
274 gst_pad_set_event_function (demux->common.sinkpad,
275 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
276 gst_pad_set_query_function (demux->common.sinkpad,
277 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_query));
278 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
280 /* init defaults for common read context */
281 gst_matroska_read_common_init (&demux->common);
283 /* property defaults */
284 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
285 demux->max_backtrack_distance = DEFAULT_MAX_BACKTRACK_DISTANCE;
287 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
289 demux->flowcombiner = gst_flow_combiner_new ();
292 gst_matroska_demux_reset (GST_ELEMENT (demux));
296 gst_matroska_demux_reset (GstElement * element)
298 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
300 GST_DEBUG_OBJECT (demux, "Resetting state");
302 gst_matroska_read_common_reset (GST_ELEMENT (demux), &demux->common);
304 demux->num_a_streams = 0;
305 demux->num_t_streams = 0;
306 demux->num_v_streams = 0;
307 demux->have_nonintraonly_v_streams = FALSE;
309 demux->have_group_id = FALSE;
310 demux->group_id = G_MAXUINT;
313 demux->tracks_parsed = FALSE;
315 if (demux->clusters) {
316 g_array_free (demux->clusters, TRUE);
317 demux->clusters = NULL;
320 g_list_foreach (demux->seek_parsed,
321 (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
322 g_list_free (demux->seek_parsed);
323 demux->seek_parsed = NULL;
325 demux->last_stop_end = GST_CLOCK_TIME_NONE;
326 demux->seek_block = 0;
327 demux->stream_start_time = GST_CLOCK_TIME_NONE;
328 demux->to_time = GST_CLOCK_TIME_NONE;
329 demux->cluster_time = GST_CLOCK_TIME_NONE;
330 demux->cluster_offset = 0;
331 demux->cluster_prevsize = 0;
332 demux->seen_cluster_prevsize = FALSE;
333 demux->next_cluster_offset = 0;
334 demux->stream_last_time = GST_CLOCK_TIME_NONE;
335 demux->last_cluster_offset = 0;
336 demux->index_offset = 0;
337 demux->seekable = FALSE;
338 demux->need_segment = FALSE;
339 demux->segment_seqnum = 0;
340 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
341 demux->seek_offset = -1;
342 demux->building_index = FALSE;
343 if (demux->seek_event) {
344 gst_event_unref (demux->seek_event);
345 demux->seek_event = NULL;
348 demux->seek_index = NULL;
349 demux->seek_entry = 0;
351 if (demux->new_segment) {
352 gst_event_unref (demux->new_segment);
353 demux->new_segment = NULL;
356 demux->invalid_duration = FALSE;
358 demux->cached_length = G_MAXUINT64;
360 if (demux->deferred_seek_event)
361 gst_event_unref (demux->deferred_seek_event);
362 demux->deferred_seek_event = NULL;
363 demux->deferred_seek_pad = NULL;
365 gst_flow_combiner_clear (demux->flowcombiner);
369 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
374 GstBuffer *out_buf = buf;
376 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
378 GST_DEBUG ("decoding buffer %p", buf);
380 gst_buffer_map (out_buf, &map, GST_MAP_READ);
384 g_return_val_if_fail (size > 0, buf);
386 if (gst_matroska_decode_data (context->encodings, &data, &size,
387 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
388 if (data != map.data) {
389 gst_buffer_unmap (out_buf, &map);
390 gst_buffer_unref (out_buf);
391 out_buf = gst_buffer_new_wrapped (data, size);
393 gst_buffer_unmap (out_buf, &map);
396 GST_DEBUG ("decode data failed");
397 gst_buffer_unmap (out_buf, &map);
398 gst_buffer_unref (out_buf);
401 /* Encrypted stream */
402 if (context->protection_info) {
404 GstStructure *info_protect = gst_structure_copy (context->protection_info);
405 gboolean encrypted = FALSE;
407 gst_buffer_map (out_buf, &map, GST_MAP_READ);
411 if (gst_matroska_parse_protection_meta (&data, &size, info_protect,
413 if (data != map.data) {
416 gst_buffer_unmap (out_buf, &map);
418 out_buf = gst_buffer_copy_region (tmp_buf, GST_BUFFER_COPY_ALL,
419 gst_buffer_get_size (tmp_buf) - size, size);
420 gst_buffer_unref (tmp_buf);
422 gst_buffer_add_protection_meta (out_buf, info_protect);
424 gst_structure_free (info_protect);
426 gst_buffer_unmap (out_buf, &map);
427 gst_structure_free (info_protect);
430 GST_WARNING ("Adding protection metadata failed");
431 gst_buffer_unmap (out_buf, &map);
432 gst_buffer_unref (out_buf);
433 gst_structure_free (info_protect);
442 gst_matroska_demux_add_stream_headers_to_caps (GstMatroskaDemux * demux,
443 GstBufferList * list, GstCaps * caps)
446 GValue arr_val = G_VALUE_INIT;
447 GValue buf_val = G_VALUE_INIT;
450 g_assert (gst_caps_is_writable (caps));
452 g_value_init (&arr_val, GST_TYPE_ARRAY);
453 g_value_init (&buf_val, GST_TYPE_BUFFER);
455 num = gst_buffer_list_length (list);
456 for (i = 0; i < num; ++i) {
457 g_value_set_boxed (&buf_val, gst_buffer_list_get (list, i));
458 gst_value_array_append_value (&arr_val, &buf_val);
461 s = gst_caps_get_structure (caps, 0);
462 gst_structure_take_value (s, "streamheader", &arr_val);
463 g_value_unset (&buf_val);
467 gst_matroska_demux_parse_mastering_metadata (GstMatroskaDemux * demux,
468 GstEbmlRead * ebml, GstMatroskaTrackVideoContext * video_context)
470 GstFlowReturn ret = GST_FLOW_OK;
471 GstVideoMasteringDisplayInfo minfo;
474 /* Precision defined by HEVC specification */
475 const guint chroma_den = 50000;
476 const guint luma_den = 10000;
478 gst_video_mastering_display_info_init (&minfo);
480 DEBUG_ELEMENT_START (demux, ebml, "MasteringMetadata");
482 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
485 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
486 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
489 /* all sub elements have float type */
490 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
493 /* chromaticity should be in [0, 1] range */
494 if (id >= GST_MATROSKA_ID_PRIMARYRCHROMATICITYX &&
495 id <= GST_MATROSKA_ID_WHITEPOINTCHROMATICITYY) {
496 if (num < 0 || num > 1.0) {
497 GST_WARNING_OBJECT (demux, "0x%x has invalid value %f", id, num);
500 } else if (id == GST_MATROSKA_ID_LUMINANCEMAX ||
501 id == GST_MATROSKA_ID_LUMINANCEMIN) {
502 /* Note: webM spec said valid range is [0, 999.9999] but
503 * 1000 cd/m^2 is generally used value on HDR. Just check guint range here.
504 * See https://www.webmproject.org/docs/container/#LuminanceMax
506 if (num < 0 || num > (gdouble) (G_MAXUINT32 / luma_den)) {
507 GST_WARNING_OBJECT (demux, "0x%x has invalid value %f", id, num);
513 case GST_MATROSKA_ID_PRIMARYRCHROMATICITYX:
514 minfo.Rx_n = (guint) round (num * chroma_den);
515 minfo.Rx_d = chroma_den;
517 case GST_MATROSKA_ID_PRIMARYRCHROMATICITYY:
518 minfo.Ry_n = (guint) round (num * chroma_den);
519 minfo.Ry_d = chroma_den;
521 case GST_MATROSKA_ID_PRIMARYGCHROMATICITYX:
522 minfo.Gx_n = (guint) round (num * chroma_den);
523 minfo.Gx_d = chroma_den;
525 case GST_MATROSKA_ID_PRIMARYGCHROMATICITYY:
526 minfo.Gy_n = (guint) round (num * chroma_den);
527 minfo.Gy_d = chroma_den;
529 case GST_MATROSKA_ID_PRIMARYBCHROMATICITYX:
530 minfo.Bx_n = (guint) round (num * chroma_den);
531 minfo.Bx_d = chroma_den;
533 case GST_MATROSKA_ID_PRIMARYBCHROMATICITYY:
534 minfo.By_n = (guint) round (num * chroma_den);
535 minfo.By_d = chroma_den;
537 case GST_MATROSKA_ID_WHITEPOINTCHROMATICITYX:
538 minfo.Wx_n = (guint) round (num * chroma_den);
539 minfo.Wx_d = chroma_den;
541 case GST_MATROSKA_ID_WHITEPOINTCHROMATICITYY:
542 minfo.Wy_n = (guint) round (num * chroma_den);
543 minfo.Wy_d = chroma_den;
545 case GST_MATROSKA_ID_LUMINANCEMAX:
546 minfo.max_luma_n = (guint) round (num * luma_den);
547 minfo.max_luma_d = luma_den;
549 case GST_MATROSKA_ID_LUMINANCEMIN:
550 minfo.min_luma_n = (guint) round (num * luma_den);
551 minfo.min_luma_d = luma_den;
554 GST_FIXME_OBJECT (demux,
555 "Unsupported subelement 0x%x in MasteringMetadata", id);
556 ret = gst_ebml_read_skip (ebml);
561 video_context->mastering_display_info = minfo;
562 video_context->mastering_display_info_present = TRUE;
565 DEBUG_ELEMENT_STOP (demux, ebml, "MasteringMetadata", ret);
571 gst_matroska_demux_parse_colour (GstMatroskaDemux * demux, GstEbmlRead * ebml,
572 GstMatroskaTrackVideoContext * video_context)
575 GstVideoColorimetry colorimetry;
579 colorimetry.range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
580 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
581 colorimetry.transfer = GST_VIDEO_TRANSFER_UNKNOWN;
582 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
584 DEBUG_ELEMENT_START (demux, ebml, "TrackVideoColour");
586 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
589 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
590 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
594 case GST_MATROSKA_ID_VIDEOMATRIXCOEFFICIENTS:{
595 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
598 colorimetry.matrix = gst_video_color_matrix_from_iso ((guint) num);
602 case GST_MATROSKA_ID_VIDEORANGE:{
603 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
608 colorimetry.range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
611 colorimetry.range = GST_VIDEO_COLOR_RANGE_16_235;
614 colorimetry.range = GST_VIDEO_COLOR_RANGE_0_255;
617 GST_FIXME_OBJECT (demux, "Unsupported color range %"
618 G_GUINT64_FORMAT, num);
624 case GST_MATROSKA_ID_VIDEOTRANSFERCHARACTERISTICS:{
625 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
628 colorimetry.transfer = gst_video_color_transfer_from_iso ((guint) num);
632 case GST_MATROSKA_ID_VIDEOPRIMARIES:{
633 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
636 colorimetry.primaries =
637 gst_video_color_primaries_from_iso ((guint) num);
641 case GST_MATROSKA_ID_MASTERINGMETADATA:{
643 gst_matroska_demux_parse_mastering_metadata (demux, ebml,
644 video_context)) != GST_FLOW_OK)
649 case GST_MATROSKA_ID_MAXCLL:{
650 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
652 if (num >= G_MAXUINT32) {
653 GST_WARNING_OBJECT (demux,
654 "Too large maxCLL value %" G_GUINT64_FORMAT, num);
656 video_context->content_light_level.maxCLL_n = num;
657 video_context->content_light_level.maxCLL_d = 1;
662 case GST_MATROSKA_ID_MAXFALL:{
663 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
665 if (num >= G_MAXUINT32) {
666 GST_WARNING_OBJECT (demux,
667 "Too large maxFALL value %" G_GUINT64_FORMAT, num);
669 video_context->content_light_level.maxFALL_n = num;
670 video_context->content_light_level.maxFALL_d = 1;
676 GST_FIXME_OBJECT (demux, "Unsupported subelement 0x%x in Colour", id);
677 ret = gst_ebml_read_skip (ebml);
682 memcpy (&video_context->colorimetry, &colorimetry,
683 sizeof (GstVideoColorimetry));
686 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideoColour", ret);
691 gst_matroska_demux_parse_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml,
692 GstMatroskaTrackContext ** dest_context)
694 GstMatroskaTrackContext *context;
695 GstCaps *caps = NULL;
696 GstTagList *cached_taglist;
698 guint32 id, riff_fourcc = 0;
699 guint16 riff_audio_fmt = 0;
702 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
704 /* start with the master */
705 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
706 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
710 /* allocate generic... if we know the type, we'll g_renew()
711 * with the precise type */
712 context = g_new0 (GstMatroskaTrackContext, 1);
713 context->index_writer_id = -1;
714 context->type = 0; /* no type yet */
715 context->default_duration = 0;
717 context->set_discont = TRUE;
718 context->timecodescale = 1.0;
720 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
721 GST_MATROSKA_TRACK_LACING;
722 context->from_time = GST_CLOCK_TIME_NONE;
723 context->from_offset = -1;
724 context->to_offset = G_MAXINT64;
725 context->alignment = 1;
726 context->dts_only = FALSE;
727 context->intra_only = FALSE;
728 context->tags = gst_tag_list_new_empty ();
729 g_queue_init (&context->protection_event_queue);
730 context->protection_info = NULL;
732 GST_DEBUG_OBJECT (demux, "Parsing a TrackEntry (%d tracks parsed so far)",
733 demux->common.num_streams);
735 /* try reading the trackentry headers */
736 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
737 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
741 /* track number (unique stream ID) */
742 case GST_MATROSKA_ID_TRACKNUMBER:{
745 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
749 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
750 ret = GST_FLOW_ERROR;
754 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
758 /* track UID (unique identifier) */
759 case GST_MATROSKA_ID_TRACKUID:{
762 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
766 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
767 ret = GST_FLOW_ERROR;
771 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
776 /* track type (video, audio, combined, subtitle, etc.) */
777 case GST_MATROSKA_ID_TRACKTYPE:{
780 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
784 if (context->type != 0 && context->type != track_type) {
785 GST_WARNING_OBJECT (demux,
786 "More than one tracktype defined in a TrackEntry - skipping");
788 } else if (track_type < 1 || track_type > 254) {
789 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
794 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
796 /* ok, so we're actually going to reallocate this thing */
797 switch (track_type) {
798 case GST_MATROSKA_TRACK_TYPE_VIDEO:
799 gst_matroska_track_init_video_context (&context);
801 case GST_MATROSKA_TRACK_TYPE_AUDIO:
802 gst_matroska_track_init_audio_context (&context);
804 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
805 gst_matroska_track_init_subtitle_context (&context);
807 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
808 case GST_MATROSKA_TRACK_TYPE_LOGO:
809 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
810 case GST_MATROSKA_TRACK_TYPE_CONTROL:
812 GST_WARNING_OBJECT (demux,
813 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
821 /* tracktype specific stuff for video */
822 case GST_MATROSKA_ID_TRACKVIDEO:{
823 GstMatroskaTrackVideoContext *videocontext;
825 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
827 if (!gst_matroska_track_init_video_context (&context)) {
828 GST_WARNING_OBJECT (demux,
829 "TrackVideo element in non-video track - ignoring track");
830 ret = GST_FLOW_ERROR;
832 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
835 videocontext = (GstMatroskaTrackVideoContext *) context;
837 while (ret == GST_FLOW_OK &&
838 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
839 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
843 /* Should be one level up but some broken muxers write it here. */
844 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
847 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
851 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
855 GST_DEBUG_OBJECT (demux,
856 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
857 context->default_duration = num;
861 /* video framerate */
862 /* NOTE: This one is here only for backward compatibility.
863 * Use _TRACKDEFAULDURATION one level up. */
864 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
867 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
871 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
875 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
876 if (context->default_duration == 0)
877 context->default_duration =
878 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
879 videocontext->default_fps = num;
883 /* width of the size to display the video at */
884 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
887 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
891 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
895 GST_DEBUG_OBJECT (demux,
896 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
897 videocontext->display_width = num;
901 /* height of the size to display the video at */
902 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
905 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
909 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
913 GST_DEBUG_OBJECT (demux,
914 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
915 videocontext->display_height = num;
919 /* width of the video in the file */
920 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
923 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
927 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
931 GST_DEBUG_OBJECT (demux,
932 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
933 videocontext->pixel_width = num;
937 /* height of the video in the file */
938 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
941 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
945 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
949 GST_DEBUG_OBJECT (demux,
950 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
951 videocontext->pixel_height = num;
955 /* whether the video is interlaced */
956 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
959 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
963 videocontext->interlace_mode =
964 GST_MATROSKA_INTERLACE_MODE_INTERLACED;
966 videocontext->interlace_mode =
967 GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
969 videocontext->interlace_mode =
970 GST_MATROSKA_INTERLACE_MODE_UNKNOWN;
972 GST_DEBUG_OBJECT (demux, "video track interlacing mode: %d",
973 videocontext->interlace_mode);
977 /* interlaced field order */
978 case GST_MATROSKA_ID_VIDEOFIELDORDER:{
981 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
984 if (videocontext->interlace_mode !=
985 GST_MATROSKA_INTERLACE_MODE_INTERLACED) {
986 GST_WARNING_OBJECT (demux,
987 "FieldOrder element when not interlaced - ignoring");
992 /* turns out we're actually progressive */
993 videocontext->interlace_mode =
994 GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
996 videocontext->field_order = GST_VIDEO_FIELD_ORDER_UNKNOWN;
998 videocontext->field_order =
999 GST_VIDEO_FIELD_ORDER_TOP_FIELD_FIRST;
1001 videocontext->field_order =
1002 GST_VIDEO_FIELD_ORDER_BOTTOM_FIELD_FIRST;
1004 GST_FIXME_OBJECT (demux,
1005 "Unknown or unsupported FieldOrder %" G_GUINT64_FORMAT,
1007 videocontext->field_order = GST_VIDEO_FIELD_ORDER_UNKNOWN;
1010 GST_DEBUG_OBJECT (demux, "video track field order: %d",
1011 videocontext->field_order);
1015 /* aspect ratio behaviour */
1016 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
1019 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1022 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
1023 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
1024 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
1025 GST_WARNING_OBJECT (demux,
1026 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
1029 GST_DEBUG_OBJECT (demux,
1030 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
1031 videocontext->asr_mode = num;
1035 /* colourspace (only matters for raw video) fourcc */
1036 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
1041 gst_ebml_read_binary (ebml, &id, &data,
1042 &datalen)) != GST_FLOW_OK)
1047 GST_WARNING_OBJECT (demux,
1048 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
1053 memcpy (&videocontext->fourcc, data, 4);
1054 GST_DEBUG_OBJECT (demux,
1055 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
1056 GST_FOURCC_ARGS (videocontext->fourcc));
1062 case GST_MATROSKA_ID_VIDEOCOLOUR:{
1063 ret = gst_matroska_demux_parse_colour (demux, ebml, videocontext);
1067 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
1071 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1074 GST_DEBUG_OBJECT (demux, "StereoMode: %" G_GUINT64_FORMAT, num);
1077 case GST_MATROSKA_STEREO_MODE_SBS_RL:
1078 videocontext->multiview_flags =
1079 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1081 case GST_MATROSKA_STEREO_MODE_SBS_LR:
1082 videocontext->multiview_mode =
1083 GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
1085 case GST_MATROSKA_STEREO_MODE_TB_RL:
1086 videocontext->multiview_flags =
1087 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1089 case GST_MATROSKA_STEREO_MODE_TB_LR:
1090 videocontext->multiview_mode =
1091 GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM;
1093 case GST_MATROSKA_STEREO_MODE_CHECKER_RL:
1094 videocontext->multiview_flags =
1095 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1097 case GST_MATROSKA_STEREO_MODE_CHECKER_LR:
1098 videocontext->multiview_mode =
1099 GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD;
1101 case GST_MATROSKA_STEREO_MODE_FBF_RL:
1102 videocontext->multiview_flags =
1103 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1105 case GST_MATROSKA_STEREO_MODE_FBF_LR:
1106 videocontext->multiview_mode =
1107 GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
1108 /* FIXME: In frame-by-frame mode, left/right frame buffers are
1109 * laced within one block, and we'll need to apply FIRST_IN_BUNDLE
1110 * accordingly. See http://www.matroska.org/technical/specs/index.html#StereoMode */
1111 GST_FIXME_OBJECT (demux,
1112 "Frame-by-frame stereoscopic mode not fully implemented");
1119 GST_WARNING_OBJECT (demux,
1120 "Unknown TrackVideo subelement 0x%x - ignoring", id);
1122 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
1123 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
1124 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
1125 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
1126 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
1127 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
1128 ret = gst_ebml_read_skip (ebml);
1133 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
1137 /* tracktype specific stuff for audio */
1138 case GST_MATROSKA_ID_TRACKAUDIO:{
1139 GstMatroskaTrackAudioContext *audiocontext;
1141 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
1143 if (!gst_matroska_track_init_audio_context (&context)) {
1144 GST_WARNING_OBJECT (demux,
1145 "TrackAudio element in non-audio track - ignoring track");
1146 ret = GST_FLOW_ERROR;
1150 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
1153 audiocontext = (GstMatroskaTrackAudioContext *) context;
1155 while (ret == GST_FLOW_OK &&
1156 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1157 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1162 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
1165 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1170 GST_WARNING_OBJECT (demux,
1171 "Invalid TrackAudioSamplingFrequency %lf", num);
1175 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
1176 audiocontext->samplerate = num;
1181 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
1184 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1188 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
1192 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
1194 audiocontext->bitdepth = num;
1199 case GST_MATROSKA_ID_AUDIOCHANNELS:{
1202 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1206 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
1210 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
1212 audiocontext->channels = num;
1217 GST_WARNING_OBJECT (demux,
1218 "Unknown TrackAudio subelement 0x%x - ignoring", id);
1220 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
1221 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
1222 ret = gst_ebml_read_skip (ebml);
1227 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
1232 /* codec identifier */
1233 case GST_MATROSKA_ID_CODECID:{
1236 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
1239 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
1240 context->codec_id = text;
1244 /* codec private data */
1245 case GST_MATROSKA_ID_CODECPRIVATE:{
1250 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
1253 context->codec_priv = data;
1254 context->codec_priv_size = size;
1256 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1261 /* name of the codec */
1262 case GST_MATROSKA_ID_CODECNAME:{
1265 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1268 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1269 context->codec_name = text;
1274 case GST_MATROSKA_ID_CODECDELAY:{
1277 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1280 context->codec_delay = num;
1282 GST_DEBUG_OBJECT (demux, "CodecDelay: %" GST_TIME_FORMAT,
1283 GST_TIME_ARGS (num));
1288 case GST_MATROSKA_ID_SEEKPREROLL:{
1291 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1294 context->seek_preroll = num;
1296 GST_DEBUG_OBJECT (demux, "SeekPreroll: %" GST_TIME_FORMAT,
1297 GST_TIME_ARGS (num));
1301 /* name of this track */
1302 case GST_MATROSKA_ID_TRACKNAME:{
1305 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1308 context->name = text;
1309 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1313 /* language (matters for audio/subtitles, mostly) */
1314 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1317 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1321 context->language = text;
1324 if (strlen (context->language) >= 4 && context->language[3] == '-')
1325 context->language[3] = '\0';
1327 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1328 GST_STR_NULL (context->language));
1332 /* whether this is actually used */
1333 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1336 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1340 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1342 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1344 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1345 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1349 /* whether it's the default for this track type */
1350 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1353 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1357 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1359 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1361 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1362 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
1366 /* whether the track must be used during playback */
1367 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1370 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1374 context->flags |= GST_MATROSKA_TRACK_FORCED;
1376 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1378 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1379 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
1383 /* lacing (like MPEG, where blocks don't end/start on frame
1385 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1388 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1392 context->flags |= GST_MATROSKA_TRACK_LACING;
1394 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1396 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1397 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
1401 /* default length (in time) of one data block in this track */
1402 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1405 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1410 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1414 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1416 context->default_duration = num;
1420 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1421 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1426 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1429 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1433 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1437 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1438 context->timecodescale = num;
1443 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1446 /* we ignore these because they're nothing useful (i.e. crap)
1447 * or simply not implemented yet. */
1448 case GST_MATROSKA_ID_TRACKMINCACHE:
1449 case GST_MATROSKA_ID_TRACKMAXCACHE:
1450 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1451 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1452 case GST_MATROSKA_ID_TRACKOVERLAY:
1453 case GST_MATROSKA_ID_TRACKTRANSLATE:
1454 case GST_MATROSKA_ID_TRACKOFFSET:
1455 case GST_MATROSKA_ID_CODECSETTINGS:
1456 case GST_MATROSKA_ID_CODECINFOURL:
1457 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1458 case GST_MATROSKA_ID_CODECDECODEALL:
1459 ret = gst_ebml_read_skip (ebml);
1464 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1466 /* Decode codec private data if necessary */
1467 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1468 && context->codec_priv_size > 0) {
1469 if (!gst_matroska_decode_data (context->encodings,
1470 &context->codec_priv, &context->codec_priv_size,
1471 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1472 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1473 ret = GST_FLOW_ERROR;
1477 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1478 && ret != GST_FLOW_EOS)) {
1479 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1480 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1482 gst_matroska_track_free (context);
1484 *dest_context = NULL;
1488 /* check for a cached track taglist */
1490 (GstTagList *) g_hash_table_lookup (demux->common.cached_track_taglists,
1491 GUINT_TO_POINTER (context->uid));
1493 gst_tag_list_insert (context->tags, cached_taglist, GST_TAG_MERGE_APPEND);
1496 switch (context->type) {
1497 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1498 GstMatroskaTrackVideoContext *videocontext =
1499 (GstMatroskaTrackVideoContext *) context;
1501 caps = gst_matroska_demux_video_caps (videocontext,
1502 context->codec_id, context->codec_priv,
1503 context->codec_priv_size, &codec, &riff_fourcc);
1506 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1507 GST_TAG_VIDEO_CODEC, codec, NULL);
1508 context->tags_changed = TRUE;
1514 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1515 GstMatroskaTrackAudioContext *audiocontext =
1516 (GstMatroskaTrackAudioContext *) context;
1518 caps = gst_matroska_demux_audio_caps (audiocontext,
1519 context->codec_id, context->codec_priv, context->codec_priv_size,
1520 &codec, &riff_audio_fmt);
1523 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1524 GST_TAG_AUDIO_CODEC, codec, NULL);
1525 context->tags_changed = TRUE;
1531 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1532 GstMatroskaTrackSubtitleContext *subtitlecontext =
1533 (GstMatroskaTrackSubtitleContext *) context;
1535 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1536 context->codec_id, context->codec_priv, context->codec_priv_size);
1540 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1541 case GST_MATROSKA_TRACK_TYPE_LOGO:
1542 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1543 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1545 /* we should already have quit by now */
1546 g_assert_not_reached ();
1549 if ((context->language == NULL || *context->language == '\0') &&
1550 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1551 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1552 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1553 context->language = g_strdup ("eng");
1556 if (context->language) {
1559 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1560 lang = gst_tag_get_language_code (context->language);
1561 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1562 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1564 if (context->name) {
1565 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1566 GST_TAG_TITLE, context->name, NULL);
1568 context->tags_changed = TRUE;
1572 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1573 "codec_id='%s'", context->codec_id);
1574 switch (context->type) {
1575 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1576 caps = gst_caps_new_empty_simple ("video/x-unknown");
1578 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1579 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1581 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1582 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1584 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1586 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1589 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1592 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1593 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1594 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1595 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1596 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1597 GST_FOURCC_ARGS (riff_fourcc));
1598 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1601 } else if (context->stream_headers != NULL) {
1602 gst_matroska_demux_add_stream_headers_to_caps (demux,
1603 context->stream_headers, caps);
1606 if (context->encodings) {
1607 GstMatroskaTrackEncoding *enc;
1610 for (i = 0; i < context->encodings->len; i++) {
1611 enc = &g_array_index (context->encodings, GstMatroskaTrackEncoding, i);
1612 if (enc->type == GST_MATROSKA_ENCODING_ENCRYPTION /* encryption */ ) {
1613 GstStructure *s = gst_caps_get_structure (caps, 0);
1614 if (!gst_structure_has_name (s, "application/x-webm-enc")) {
1615 gst_structure_set (s, "original-media-type", G_TYPE_STRING,
1616 gst_structure_get_name (s), NULL);
1617 gst_structure_set (s, "encryption-algorithm", G_TYPE_STRING,
1618 gst_matroska_track_encryption_algorithm_name (enc->enc_algo),
1620 gst_structure_set (s, "encoding-scope", G_TYPE_STRING,
1621 gst_matroska_track_encoding_scope_name (enc->scope), NULL);
1622 gst_structure_set (s, "cipher-mode", G_TYPE_STRING,
1623 gst_matroska_track_encryption_cipher_mode_name
1624 (enc->enc_cipher_mode), NULL);
1625 gst_structure_set_name (s, "application/x-webm-enc");
1631 context->caps = caps;
1634 *dest_context = context;
1639 gst_matroska_demux_add_stream (GstMatroskaDemux * demux,
1640 GstMatroskaTrackContext * context)
1642 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
1643 gchar *padname = NULL;
1644 GstPadTemplate *templ = NULL;
1645 GstStreamFlags stream_flags;
1647 GstEvent *stream_start;
1651 g_ptr_array_add (demux->common.src, context);
1652 context->index = demux->common.num_streams++;
1653 g_assert (demux->common.src->len == demux->common.num_streams);
1654 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1) =
1657 /* now create the GStreamer connectivity */
1658 switch (context->type) {
1659 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1660 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1661 templ = gst_element_class_get_pad_template (klass, "video_%u");
1663 if (!context->intra_only)
1664 demux->have_nonintraonly_v_streams = TRUE;
1667 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1668 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1669 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1672 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1673 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1674 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1678 /* we should already have quit by now */
1679 g_assert_not_reached ();
1682 /* the pad in here */
1683 context->pad = gst_pad_new_from_template (templ, padname);
1685 gst_pad_set_event_function (context->pad,
1686 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1687 gst_pad_set_query_function (context->pad,
1688 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1690 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1691 padname, context->caps);
1693 gst_pad_set_element_private (context->pad, context);
1695 gst_pad_use_fixed_caps (context->pad);
1696 gst_pad_set_active (context->pad, TRUE);
1699 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1700 "%03" G_GUINT64_FORMAT ":%03" G_GUINT64_FORMAT,
1701 context->num, context->uid);
1703 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1706 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1707 demux->have_group_id = TRUE;
1709 demux->have_group_id = FALSE;
1710 gst_event_unref (stream_start);
1711 } else if (!demux->have_group_id) {
1712 demux->have_group_id = TRUE;
1713 demux->group_id = gst_util_group_id_next ();
1716 stream_start = gst_event_new_stream_start (stream_id);
1718 if (demux->have_group_id)
1719 gst_event_set_group_id (stream_start, demux->group_id);
1720 stream_flags = GST_STREAM_FLAG_NONE;
1721 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1722 stream_flags |= GST_STREAM_FLAG_SPARSE;
1723 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1724 stream_flags |= GST_STREAM_FLAG_SELECT;
1725 else if (!(context->flags & GST_MATROSKA_TRACK_ENABLED))
1726 stream_flags |= GST_STREAM_FLAG_UNSELECT;
1728 gst_event_set_stream_flags (stream_start, stream_flags);
1729 gst_pad_push_event (context->pad, stream_start);
1730 gst_pad_set_caps (context->pad, context->caps);
1733 if (demux->common.global_tags) {
1734 GstEvent *tag_event;
1736 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1737 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1738 GST_DEBUG_OBJECT (context->pad, "Sending global_tags %p: %" GST_PTR_FORMAT,
1739 demux->common.global_tags, demux->common.global_tags);
1742 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1744 gst_pad_push_event (context->pad, tag_event);
1747 if (G_UNLIKELY (context->tags_changed)) {
1748 GST_DEBUG_OBJECT (context->pad, "Sending tags %p: %"
1749 GST_PTR_FORMAT, context->tags, context->tags);
1750 gst_pad_push_event (context->pad,
1751 gst_event_new_tag (gst_tag_list_copy (context->tags)));
1752 context->tags_changed = FALSE;
1755 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1756 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1762 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1765 gboolean res = FALSE;
1766 GstMatroskaTrackContext *context = NULL;
1769 context = gst_pad_get_element_private (pad);
1772 switch (GST_QUERY_TYPE (query)) {
1773 case GST_QUERY_POSITION:
1777 gst_query_parse_position (query, &format, NULL);
1780 if (format == GST_FORMAT_TIME) {
1781 GST_OBJECT_LOCK (demux);
1783 gst_query_set_position (query, GST_FORMAT_TIME,
1784 MAX (context->pos, demux->stream_start_time) -
1785 demux->stream_start_time);
1787 gst_query_set_position (query, GST_FORMAT_TIME,
1788 MAX (demux->common.segment.position, demux->stream_start_time) -
1789 demux->stream_start_time);
1790 GST_OBJECT_UNLOCK (demux);
1791 } else if (format == GST_FORMAT_DEFAULT && context
1792 && context->default_duration) {
1793 GST_OBJECT_LOCK (demux);
1794 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1795 context->pos / context->default_duration);
1796 GST_OBJECT_UNLOCK (demux);
1798 GST_DEBUG_OBJECT (demux,
1799 "only position query in TIME and DEFAULT format is supported");
1805 case GST_QUERY_DURATION:
1809 gst_query_parse_duration (query, &format, NULL);
1812 if (format == GST_FORMAT_TIME) {
1813 GST_OBJECT_LOCK (demux);
1814 gst_query_set_duration (query, GST_FORMAT_TIME,
1815 demux->common.segment.duration);
1816 GST_OBJECT_UNLOCK (demux);
1817 } else if (format == GST_FORMAT_DEFAULT && context
1818 && context->default_duration) {
1819 GST_OBJECT_LOCK (demux);
1820 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1821 demux->common.segment.duration / context->default_duration);
1822 GST_OBJECT_UNLOCK (demux);
1824 GST_DEBUG_OBJECT (demux,
1825 "only duration query in TIME and DEFAULT format is supported");
1831 case GST_QUERY_SEEKING:
1835 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1836 GST_OBJECT_LOCK (demux);
1837 if (fmt == GST_FORMAT_TIME) {
1840 if (demux->streaming) {
1841 /* assuming we'll be able to get an index ... */
1842 seekable = demux->seekable;
1847 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1848 0, demux->common.segment.duration);
1851 GST_OBJECT_UNLOCK (demux);
1854 case GST_QUERY_SEGMENT:
1859 format = demux->common.segment.format;
1862 gst_segment_to_stream_time (&demux->common.segment, format,
1863 demux->common.segment.start);
1864 if ((stop = demux->common.segment.stop) == -1)
1865 stop = demux->common.segment.duration;
1868 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1870 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1877 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1880 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1889 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1891 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1895 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1898 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1900 return gst_matroska_demux_query (demux, pad, query);
1903 /* returns FALSE if there are no pads to deliver event to,
1904 * otherwise TRUE (whatever the outcome of event sending),
1905 * takes ownership of the passed event! */
1907 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1909 gboolean ret = FALSE;
1912 g_return_val_if_fail (event != NULL, FALSE);
1914 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1915 GST_EVENT_TYPE_NAME (event));
1917 g_assert (demux->common.src->len == demux->common.num_streams);
1918 for (i = 0; i < demux->common.src->len; i++) {
1919 GstMatroskaTrackContext *stream;
1921 stream = g_ptr_array_index (demux->common.src, i);
1922 gst_event_ref (event);
1923 gst_pad_push_event (stream->pad, event);
1927 gst_event_unref (event);
1932 gst_matroska_demux_send_tags (GstMatroskaDemux * demux)
1936 if (G_UNLIKELY (demux->common.global_tags_changed)) {
1937 GstEvent *tag_event;
1938 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1939 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1940 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1941 demux->common.global_tags, demux->common.global_tags);
1944 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1946 for (i = 0; i < demux->common.src->len; i++) {
1947 GstMatroskaTrackContext *stream;
1949 stream = g_ptr_array_index (demux->common.src, i);
1950 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1953 gst_event_unref (tag_event);
1954 demux->common.global_tags_changed = FALSE;
1957 g_assert (demux->common.src->len == demux->common.num_streams);
1958 for (i = 0; i < demux->common.src->len; i++) {
1959 GstMatroskaTrackContext *stream;
1961 stream = g_ptr_array_index (demux->common.src, i);
1963 if (G_UNLIKELY (stream->tags_changed)) {
1964 GST_DEBUG_OBJECT (demux, "Sending tags %p for pad %s:%s : %"
1965 GST_PTR_FORMAT, stream->tags,
1966 GST_DEBUG_PAD_NAME (stream->pad), stream->tags);
1967 gst_pad_push_event (stream->pad,
1968 gst_event_new_tag (gst_tag_list_copy (stream->tags)));
1969 stream->tags_changed = FALSE;
1975 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1977 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1980 g_return_val_if_fail (event != NULL, FALSE);
1982 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1983 /* no seeking until we are (safely) ready */
1984 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
1985 GST_DEBUG_OBJECT (demux,
1986 "not ready for seeking yet, deferring seek: %" GST_PTR_FORMAT, event);
1987 if (demux->deferred_seek_event)
1988 gst_event_unref (demux->deferred_seek_event);
1989 demux->deferred_seek_event = event;
1990 demux->deferred_seek_pad = NULL;
1993 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1995 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1996 GST_EVENT_TYPE_NAME (event));
1999 gst_event_unref (event);
2004 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
2005 GstMatroskaIndex * entry, gboolean reset, gboolean update)
2009 GST_OBJECT_LOCK (demux);
2012 /* seek (relative to matroska segment) */
2013 /* position might be invalid; will error when streaming resumes ... */
2014 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
2015 demux->next_cluster_offset = 0;
2017 GST_DEBUG_OBJECT (demux,
2018 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
2019 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
2020 entry->block, GST_TIME_ARGS (entry->time));
2022 /* update the time */
2023 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
2024 gst_flow_combiner_reset (demux->flowcombiner);
2025 demux->common.segment.position = entry->time;
2026 demux->seek_block = entry->block;
2027 demux->seek_first = TRUE;
2028 demux->last_stop_end = GST_CLOCK_TIME_NONE;
2031 for (i = 0; i < demux->common.src->len; i++) {
2032 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2035 stream->to_offset = G_MAXINT64;
2037 if (stream->from_offset != -1)
2038 stream->to_offset = stream->from_offset;
2040 stream->from_offset = -1;
2041 stream->from_time = GST_CLOCK_TIME_NONE;
2044 GST_OBJECT_UNLOCK (demux);
2050 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
2060 /* searches for a cluster start from @pos,
2061 * return GST_FLOW_OK and cluster position in @pos if found */
2062 static GstFlowReturn
2063 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos,
2066 gint64 newpos = *pos;
2068 GstFlowReturn ret = GST_FLOW_OK;
2069 const guint chunk = 128 * 1024;
2070 GstBuffer *buf = NULL;
2072 gpointer data = NULL;
2077 gint64 oldpos, oldlength;
2079 orig_offset = demux->common.offset;
2081 GST_LOG_OBJECT (demux, "searching cluster %s offset %" G_GINT64_FORMAT,
2082 forward ? "following" : "preceding", *pos);
2084 if (demux->clusters) {
2087 cpos = gst_util_array_binary_search (demux->clusters->data,
2088 demux->clusters->len, sizeof (gint64),
2089 (GCompareDataFunc) gst_matroska_cluster_compare,
2090 forward ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE, pos, NULL);
2093 GST_DEBUG_OBJECT (demux,
2094 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
2095 demux->common.offset = *cpos;
2096 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2097 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2098 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
2105 /* read in at newpos and scan for ebml cluster id */
2106 oldpos = oldlength = -1;
2108 GstByteReader reader;
2110 guint toread = chunk;
2113 /* never read beyond the requested target */
2114 if (G_UNLIKELY (newpos < chunk)) {
2122 gst_buffer_unmap (buf, &map);
2123 gst_buffer_unref (buf);
2126 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, toread, &buf);
2127 if (ret != GST_FLOW_OK)
2129 GST_DEBUG_OBJECT (demux,
2130 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
2131 gst_buffer_get_size (buf), newpos);
2132 gst_buffer_map (buf, &map, GST_MAP_READ);
2135 if (oldpos == newpos && oldlength == map.size) {
2136 GST_ERROR_OBJECT (demux, "Stuck at same position");
2137 ret = GST_FLOW_ERROR;
2141 oldlength = map.size;
2144 gst_byte_reader_init (&reader, data, size);
2147 gint found = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
2148 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
2150 cluster_pos = found;
2153 /* need last occurrence when searching backwards */
2155 cluster_pos = gst_byte_reader_get_pos (&reader) + found;
2156 gst_byte_reader_skip (&reader, found + 4);
2162 if (cluster_pos >= 0) {
2163 newpos += cluster_pos;
2164 GST_DEBUG_OBJECT (demux,
2165 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
2166 /* extra checks whether we really sync'ed to a cluster:
2167 * - either it is the first and only cluster
2168 * - either there is a cluster after this one
2169 * - either cluster length is undefined
2171 /* ok if first cluster (there may not a subsequent one) */
2172 if (newpos == demux->first_cluster_offset) {
2173 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
2176 demux->common.offset = newpos;
2177 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2178 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2179 if (ret != GST_FLOW_OK) {
2180 GST_DEBUG_OBJECT (demux, "need more data -> continue");
2183 g_assert (id == GST_MATROSKA_ID_CLUSTER);
2184 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
2186 /* ok if undefined length or first cluster */
2187 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
2188 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
2192 demux->common.offset += length + needed;
2193 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2194 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2195 if (ret != GST_FLOW_OK)
2197 GST_DEBUG_OBJECT (demux, "next element is %scluster",
2198 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
2199 if (id == GST_MATROSKA_ID_CLUSTER)
2205 /* partial cluster id may have been in tail of buffer */
2207 forward ? MAX (gst_byte_reader_get_remaining (&reader), 4) - 3 : 3;
2212 gst_buffer_unmap (buf, &map);
2213 gst_buffer_unref (buf);
2218 demux->common.offset = orig_offset;
2223 /* Three states to express: starts with I-frame, starts with delta, don't know */
2226 CLUSTER_STATUS_NONE = 0,
2227 CLUSTER_STATUS_STARTS_WITH_KEYFRAME,
2228 CLUSTER_STATUS_STARTS_WITH_DELTAUNIT,
2237 ClusterStatus status;
2240 static const gchar *
2241 cluster_status_get_nick (ClusterStatus status)
2244 case CLUSTER_STATUS_NONE:
2246 case CLUSTER_STATUS_STARTS_WITH_KEYFRAME:
2248 case CLUSTER_STATUS_STARTS_WITH_DELTAUNIT:
2254 /* Skip ebml-coded number:
2257 * 001x.. = 3 bytes, etc.
2260 bit_reader_skip_ebml_num (GstBitReader * br)
2264 if (!gst_bit_reader_peek_bits_uint8 (br, &v, 8))
2267 for (i = 0; i < 8; i++) {
2268 if ((v & (0x80 >> i)) != 0)
2271 return gst_bit_reader_skip (br, (i + 1) * 8);
2274 /* Don't probe more than that many bytes into the cluster for keyframe info
2275 * (random value, mostly for sanity checking) */
2276 #define MAX_CLUSTER_INFO_PROBE_LENGTH 256
2279 gst_matroska_demux_peek_cluster_info (GstMatroskaDemux * demux,
2280 ClusterInfo * cluster, guint64 offset)
2282 demux->common.offset = offset;
2283 demux->cluster_time = GST_CLOCK_TIME_NONE;
2285 cluster->offset = offset;
2287 cluster->prev_size = 0;
2288 cluster->time = GST_CLOCK_TIME_NONE;
2289 cluster->status = CLUSTER_STATUS_NONE;
2291 /* parse first few elements in cluster */
2298 flow = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2299 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2301 if (flow != GST_FLOW_OK)
2304 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2305 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
2308 /* Reached start of next cluster without finding data, stop processing */
2309 if (id == GST_MATROSKA_ID_CLUSTER && cluster->offset != offset)
2312 /* Not going to parse into these for now, stop processing */
2313 if (id == GST_MATROSKA_ID_ENCRYPTEDBLOCK
2314 || id == GST_MATROSKA_ID_BLOCKGROUP || id == GST_MATROSKA_ID_BLOCK)
2317 /* SimpleBlock: peek at headers to check if it's a keyframe */
2318 if (id == GST_MATROSKA_ID_SIMPLEBLOCK) {
2320 guint8 *d, hdr_len, v = 0;
2322 GST_DEBUG_OBJECT (demux, "SimpleBlock found");
2324 /* SimpleBlock header is max. 21 bytes */
2325 hdr_len = MIN (21, length);
2327 flow = gst_matroska_read_common_peek_bytes (&demux->common,
2328 demux->common.offset, hdr_len, NULL, &d);
2330 if (flow != GST_FLOW_OK)
2333 gst_bit_reader_init (&br, d, hdr_len);
2335 /* skip prefix: ebml id (SimpleBlock) + element length */
2336 if (!gst_bit_reader_skip (&br, 8 * needed))
2339 /* skip track number (ebml coded) */
2340 if (!bit_reader_skip_ebml_num (&br))
2344 if (!gst_bit_reader_skip (&br, 16))
2348 if (!gst_bit_reader_get_bits_uint8 (&br, &v, 8))
2351 if ((v & 0x80) != 0)
2352 cluster->status = CLUSTER_STATUS_STARTS_WITH_KEYFRAME;
2354 cluster->status = CLUSTER_STATUS_STARTS_WITH_DELTAUNIT;
2359 flow = gst_matroska_demux_parse_id (demux, id, length, needed);
2361 if (flow != GST_FLOW_OK)
2365 case GST_MATROSKA_ID_CLUSTER:
2366 if (length == G_MAXUINT64)
2369 cluster->size = length + needed;
2371 case GST_MATROSKA_ID_PREVSIZE:
2372 cluster->prev_size = demux->cluster_prevsize;
2374 case GST_MATROSKA_ID_CLUSTERTIMECODE:
2375 cluster->time = demux->cluster_time * demux->common.time_scale;
2377 case GST_MATROSKA_ID_SILENTTRACKS:
2378 case GST_EBML_ID_CRC32:
2379 /* ignore and continue */
2382 GST_WARNING_OBJECT (demux, "Unknown ebml id 0x%08x (possibly garbage), "
2386 } while (demux->common.offset - offset < MAX_CLUSTER_INFO_PROBE_LENGTH);
2390 GST_INFO_OBJECT (demux, "Cluster @ %" G_GUINT64_FORMAT ": "
2391 "time %" GST_TIME_FORMAT ", size %" G_GUINT64_FORMAT ", "
2392 "prev_size %" G_GUINT64_FORMAT ", %s", cluster->offset,
2393 GST_TIME_ARGS (cluster->time), cluster->size, cluster->prev_size,
2394 cluster_status_get_nick (cluster->status));
2396 /* return success as long as we could extract the minimum useful information */
2397 return cluster->time != GST_CLOCK_TIME_NONE;
2400 /* returns TRUE if the cluster offset was updated */
2402 gst_matroska_demux_scan_back_for_keyframe_cluster (GstMatroskaDemux * demux,
2403 gint64 * cluster_offset, GstClockTime * cluster_time)
2405 GstClockTime stream_start_time = demux->stream_start_time;
2406 guint64 first_cluster_offset = demux->first_cluster_offset;
2407 gint64 off = *cluster_offset;
2408 ClusterInfo cluster = { 0, };
2410 GST_INFO_OBJECT (demux, "Checking if cluster starts with keyframe");
2411 while (off > first_cluster_offset) {
2412 if (!gst_matroska_demux_peek_cluster_info (demux, &cluster, off)) {
2413 GST_LOG_OBJECT (demux,
2414 "Couldn't get info on cluster @ %" G_GUINT64_FORMAT, off);
2418 /* Keyframe? Then we're done */
2419 if (cluster.status == CLUSTER_STATUS_STARTS_WITH_KEYFRAME) {
2420 GST_LOG_OBJECT (demux,
2421 "Found keyframe at start of cluster @ %" G_GUINT64_FORMAT, off);
2425 /* We only scan back if we *know* we landed on a cluster that
2426 * starts with a delta frame. */
2427 if (cluster.status != CLUSTER_STATUS_STARTS_WITH_DELTAUNIT) {
2428 GST_LOG_OBJECT (demux,
2429 "No delta frame at start of cluster @ %" G_GUINT64_FORMAT, off);
2433 GST_DEBUG_OBJECT (demux, "Cluster starts with delta frame, backtracking");
2435 /* Don't scan back more than this much in time from the cluster we
2436 * originally landed on. This is mostly a sanity check in case a file
2437 * always has keyframes in the middle of clusters and never at the
2438 * beginning. Without this we would always scan back to the beginning
2439 * of the file in that case. */
2440 if (cluster.time != GST_CLOCK_TIME_NONE) {
2441 GstClockTimeDiff distance = GST_CLOCK_DIFF (cluster.time, *cluster_time);
2443 if (distance < 0 || distance > demux->max_backtrack_distance * GST_SECOND) {
2444 GST_DEBUG_OBJECT (demux, "Haven't found cluster with keyframe within "
2445 "%u secs of original seek target cluster, stopping",
2446 demux->max_backtrack_distance);
2451 /* If we have cluster prev_size we can skip back efficiently. If not,
2452 * we'll just do a brute force search for a cluster identifier */
2453 if (cluster.prev_size > 0 && off >= cluster.prev_size) {
2454 off -= cluster.prev_size;
2458 GST_LOG_OBJECT (demux, "Cluster has no or invalid prev size, searching "
2459 "for previous cluster instead then");
2461 flow = gst_matroska_demux_search_cluster (demux, &off, FALSE);
2462 if (flow != GST_FLOW_OK) {
2463 GST_DEBUG_OBJECT (demux, "cluster search yielded flow %s, stopping",
2464 gst_flow_get_name (flow));
2469 if (off <= first_cluster_offset) {
2470 GST_LOG_OBJECT (demux, "Reached first cluster, stopping");
2471 *cluster_offset = first_cluster_offset;
2472 *cluster_time = stream_start_time;
2475 GST_LOG_OBJECT (demux, "Trying prev cluster @ %" G_GUINT64_FORMAT, off);
2478 /* If we found a cluster starting with a keyframe jump to that instead,
2479 * otherwise leave everything as it was before */
2480 if (cluster.time != GST_CLOCK_TIME_NONE
2481 && (cluster.offset == first_cluster_offset
2482 || cluster.status == CLUSTER_STATUS_STARTS_WITH_KEYFRAME)) {
2483 *cluster_offset = cluster.offset;
2484 *cluster_time = cluster.time;
2491 /* bisect and scan through file for cluster starting before @time,
2492 * returns fake index entry with corresponding info on cluster */
2493 static GstMatroskaIndex *
2494 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
2496 GstMatroskaIndex *entry = NULL;
2497 GstMatroskaReadState current_state;
2498 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
2500 gint64 opos, newpos, current_offset;
2501 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
2502 gint64 apos, maxpos;
2503 guint64 cluster_size = 0;
2509 /* estimate new position, resync using cluster ebml id,
2510 * and bisect further or scan forward to appropriate cluster */
2512 /* save some current global state which will be touched by our scanning */
2513 current_state = demux->common.state;
2514 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
2516 current_cluster_offset = demux->cluster_offset;
2517 current_cluster_time = demux->cluster_time;
2518 current_offset = demux->common.offset;
2520 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
2522 /* estimate using start and last known cluster */
2523 GST_OBJECT_LOCK (demux);
2524 apos = demux->first_cluster_offset;
2525 atime = demux->stream_start_time;
2526 opos = demux->last_cluster_offset;
2527 otime = demux->stream_last_time;
2528 GST_OBJECT_UNLOCK (demux);
2531 time = MAX (time, atime);
2532 otime = MAX (otime, atime);
2533 opos = MAX (opos, apos);
2535 maxpos = gst_matroska_read_common_get_length (&demux->common);
2540 * apos always refer to a cluster before target time;
2541 * opos may or may not be after target time, but if it is once so,
2542 * then also in next iteration
2546 GST_LOG_OBJECT (demux,
2547 "apos: %" G_GUINT64_FORMAT ", atime: %" GST_TIME_FORMAT ", %"
2548 GST_TIME_FORMAT " in stream time, "
2549 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
2550 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
2551 GST_TIME_FORMAT, apos, GST_TIME_ARGS (atime),
2552 GST_TIME_ARGS (atime - demux->stream_start_time), opos,
2553 GST_TIME_ARGS (otime), GST_TIME_ARGS (otime - demux->stream_start_time),
2554 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
2556 g_assert (atime <= otime);
2557 g_assert (apos <= opos);
2558 if (time == GST_CLOCK_TIME_NONE) {
2559 GST_DEBUG_OBJECT (demux, "searching last cluster");
2562 GST_DEBUG_OBJECT (demux, "unknown file size; bailing out");
2565 } else if (otime <= atime) {
2569 gst_util_uint64_scale (opos - apos, time - atime, otime - atime);
2570 if (maxpos != -1 && newpos > maxpos)
2574 GST_DEBUG_OBJECT (demux,
2575 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
2576 GST_TIME_ARGS (time), newpos);
2578 /* search backwards */
2579 if (newpos > apos) {
2580 ret = gst_matroska_demux_search_cluster (demux, &newpos, FALSE);
2581 if (ret != GST_FLOW_OK)
2585 /* then start scanning and parsing for cluster time,
2586 * re-estimate if possible, otherwise next cluster and so on */
2587 /* note that each re-estimate is entered with a change in apos or opos,
2588 * avoiding infinite loop */
2589 demux->common.offset = newpos;
2590 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
2592 prev_cluster_time = GST_CLOCK_TIME_NONE;
2594 /* peek and parse some elements */
2595 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2596 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2597 if (ret != GST_FLOW_OK)
2599 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2600 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
2602 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
2603 if (ret != GST_FLOW_OK)
2606 if (id == GST_MATROSKA_ID_CLUSTER) {
2607 cluster_time = GST_CLOCK_TIME_NONE;
2608 if (length == G_MAXUINT64)
2611 cluster_size = length + needed;
2613 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
2614 cluster_time == GST_CLOCK_TIME_NONE) {
2615 cluster_time = demux->cluster_time * demux->common.time_scale;
2616 cluster_offset = demux->cluster_offset;
2617 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
2618 " with time %" GST_TIME_FORMAT, cluster_offset,
2619 GST_TIME_ARGS (cluster_time));
2620 if (time == GST_CLOCK_TIME_NONE) {
2621 GST_DEBUG_OBJECT (demux, "found last cluster");
2622 prev_cluster_time = cluster_time;
2623 prev_cluster_offset = cluster_offset;
2626 if (cluster_time > time) {
2627 GST_DEBUG_OBJECT (demux, "overshot target");
2628 /* cluster overshoots */
2629 if (cluster_offset == demux->first_cluster_offset) {
2630 /* but no prev one */
2631 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
2632 prev_cluster_time = cluster_time;
2633 prev_cluster_offset = cluster_offset;
2636 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
2637 /* prev cluster did not overshoot, so prev cluster is target */
2640 /* re-estimate using this new position info */
2641 opos = cluster_offset;
2642 otime = cluster_time;
2646 /* cluster undershoots */
2647 GST_DEBUG_OBJECT (demux, "undershot target");
2648 /* ok if close enough */
2649 if (GST_CLOCK_DIFF (cluster_time, time) < 5 * GST_SECOND) {
2650 GST_DEBUG_OBJECT (demux, "target close enough");
2651 prev_cluster_time = cluster_time;
2652 prev_cluster_offset = cluster_offset;
2656 /* we are in between atime and otime => can bisect if worthwhile */
2657 if (prev_cluster_time != GST_CLOCK_TIME_NONE &&
2658 cluster_time > prev_cluster_time &&
2659 (GST_CLOCK_DIFF (prev_cluster_time, cluster_time) * 10 <
2660 GST_CLOCK_DIFF (cluster_time, time))) {
2661 /* we moved at least one cluster forward,
2662 * and it looks like target is still far away,
2663 * let's estimate again */
2664 GST_DEBUG_OBJECT (demux, "bisecting with new apos");
2665 apos = cluster_offset;
2666 atime = cluster_time;
2670 /* cluster undershoots, goto next one */
2671 prev_cluster_time = cluster_time;
2672 prev_cluster_offset = cluster_offset;
2673 /* skip cluster if length is defined,
2674 * otherwise will be skippingly parsed into */
2676 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
2677 demux->common.offset = cluster_offset + cluster_size;
2678 demux->cluster_time = GST_CLOCK_TIME_NONE;
2680 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
2687 if (ret == GST_FLOW_EOS) {
2688 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
2694 /* In the bisect loop above we always undershoot and then jump forward
2695 * cluster-by-cluster until we overshoot, so if we get here we've gone
2696 * over and the previous cluster is where we need to go to. */
2697 cluster_offset = prev_cluster_offset;
2698 cluster_time = prev_cluster_time;
2700 /* If we have video and can easily backtrack, check if we landed on a cluster
2701 * that starts with a keyframe - and if not backtrack until we find one that
2703 if (demux->have_nonintraonly_v_streams && demux->max_backtrack_distance > 0) {
2704 if (gst_matroska_demux_scan_back_for_keyframe_cluster (demux,
2705 &cluster_offset, &cluster_time)) {
2706 GST_INFO_OBJECT (demux, "Adjusted cluster to %" GST_TIME_FORMAT " @ "
2707 "%" G_GUINT64_FORMAT, GST_TIME_ARGS (cluster_time), cluster_offset);
2711 entry = g_new0 (GstMatroskaIndex, 1);
2712 entry->time = cluster_time;
2713 entry->pos = cluster_offset - demux->common.ebml_segment_start;
2714 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
2715 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
2719 /* restore some state */
2720 demux->cluster_offset = current_cluster_offset;
2721 demux->cluster_time = current_cluster_time;
2722 demux->common.offset = current_offset;
2723 demux->common.state = current_state;
2729 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
2730 GstPad * pad, GstEvent * event)
2732 GstMatroskaIndex *entry = NULL;
2733 GstMatroskaIndex scan_entry;
2735 GstSeekType cur_type, stop_type;
2737 gboolean flush, keyunit, before, after, snap_next;
2740 GstMatroskaTrackContext *track = NULL;
2741 GstSegment seeksegment = { 0, };
2742 gboolean update = TRUE;
2743 gboolean pad_locked = FALSE;
2745 GstSearchMode snap_dir;
2747 g_return_val_if_fail (event != NULL, FALSE);
2750 track = gst_pad_get_element_private (pad);
2752 GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
2754 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2756 seqnum = gst_event_get_seqnum (event);
2758 /* we can only seek on time */
2759 if (format != GST_FORMAT_TIME) {
2760 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2764 /* copy segment, we need this because we still need the old
2765 * segment when we close the current segment. */
2766 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
2768 /* pull mode without index means that the actual duration is not known,
2769 * we might be playing a file that's still being recorded
2770 * so, invalidate our current duration, which is only a moving target,
2771 * and should not be used to clamp anything */
2772 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
2773 seeksegment.duration = GST_CLOCK_TIME_NONE;
2776 GST_DEBUG_OBJECT (demux, "configuring seek");
2777 /* Subtract stream_start_time so we always seek on a segment
2779 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2780 seeksegment.start -= demux->stream_start_time;
2781 seeksegment.position -= demux->stream_start_time;
2782 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2783 seeksegment.stop -= demux->stream_start_time;
2785 seeksegment.stop = seeksegment.duration;
2788 gst_segment_do_seek (&seeksegment, rate, format, flags,
2789 cur_type, cur, stop_type, stop, &update);
2791 /* Restore the clip timestamp offset */
2792 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2793 seeksegment.position += demux->stream_start_time;
2794 seeksegment.start += demux->stream_start_time;
2795 if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2796 seeksegment.stop = seeksegment.duration;
2797 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2798 seeksegment.stop += demux->stream_start_time;
2801 /* restore segment duration (if any effect),
2802 * would be determined again when parsing, but anyway ... */
2803 seeksegment.duration = demux->common.segment.duration;
2805 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2806 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2807 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
2808 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
2810 /* always do full update if flushing,
2811 * otherwise problems might arise downstream with missing keyframes etc */
2812 update = update || flush;
2814 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2816 /* check sanity before we start flushing and all that */
2817 snap_next = after && !before;
2818 if (seeksegment.rate < 0)
2819 snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
2821 snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
2823 GST_OBJECT_LOCK (demux);
2824 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2825 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2826 seeksegment.position, &demux->seek_index, &demux->seek_entry,
2827 snap_dir)) == NULL) {
2828 /* pull mode without index can scan later on */
2829 if (demux->streaming) {
2830 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2831 GST_OBJECT_UNLOCK (demux);
2833 } else if (rate < 0.0) {
2834 /* FIXME: We should build an index during playback or when scanning
2835 * that can be used here. The reverse playback code requires seek_index
2836 * and seek_entry to be set!
2838 GST_DEBUG_OBJECT (demux,
2839 "No matching seek entry in index, needed for reverse playback");
2840 GST_OBJECT_UNLOCK (demux);
2844 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2845 GST_OBJECT_UNLOCK (demux);
2848 /* only have to update some segment,
2849 * but also still have to honour flush and so on */
2850 GST_DEBUG_OBJECT (demux, "... no update");
2851 /* bad goto, bad ... */
2855 if (demux->streaming)
2860 GstEvent *flush_event = gst_event_new_flush_start ();
2861 gst_event_set_seqnum (flush_event, seqnum);
2862 GST_DEBUG_OBJECT (demux, "Starting flush");
2863 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2864 gst_matroska_demux_send_event (demux, flush_event);
2866 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2867 gst_pad_pause_task (demux->common.sinkpad);
2871 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2876 /* now grab the stream lock so that streaming cannot continue, for
2877 * non flushing seeks when the element is in PAUSED this could block
2879 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2880 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2883 /* pull mode without index can do some scanning */
2884 if (!demux->streaming && !entry) {
2885 GstEvent *flush_event;
2887 /* need to stop flushing upstream as we need it next */
2889 flush_event = gst_event_new_flush_stop (TRUE);
2890 gst_event_set_seqnum (flush_event, seqnum);
2891 gst_pad_push_event (demux->common.sinkpad, flush_event);
2893 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2894 /* keep local copy */
2896 scan_entry = *entry;
2898 entry = &scan_entry;
2900 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2902 flush_event = gst_event_new_flush_stop (TRUE);
2903 gst_event_set_seqnum (flush_event, seqnum);
2904 gst_matroska_demux_send_event (demux, flush_event);
2911 if (keyunit && seeksegment.rate > 0) {
2912 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2913 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2914 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2915 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2916 seeksegment.position = seeksegment.start;
2917 seeksegment.time = seeksegment.start - demux->stream_start_time;
2918 } else if (keyunit) {
2919 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment stop from %"
2920 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2921 GST_TIME_ARGS (seeksegment.stop), GST_TIME_ARGS (entry->time));
2922 seeksegment.stop = MAX (entry->time, demux->stream_start_time);
2923 seeksegment.position = seeksegment.stop;
2926 if (demux->streaming) {
2927 GST_OBJECT_LOCK (demux);
2928 /* track real position we should start at */
2929 GST_DEBUG_OBJECT (demux, "storing segment start");
2930 demux->requested_seek_time = seeksegment.position;
2931 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2932 GST_OBJECT_UNLOCK (demux);
2933 /* need to seek to cluster start to pick up cluster time */
2934 /* upstream takes care of flushing and all that
2935 * ... and newsegment event handling takes care of the rest */
2936 return perform_seek_to_offset (demux, rate,
2937 entry->pos + demux->common.ebml_segment_start, seqnum, flags);
2942 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2943 gst_event_set_seqnum (flush_event, seqnum);
2944 GST_DEBUG_OBJECT (demux, "Stopping flush");
2945 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2946 gst_matroska_demux_send_event (demux, flush_event);
2949 GST_OBJECT_LOCK (demux);
2950 /* now update the real segment info */
2951 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2952 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2953 GST_OBJECT_UNLOCK (demux);
2955 /* update some (segment) state */
2956 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2959 /* notify start of new segment */
2960 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2963 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2964 GST_FORMAT_TIME, demux->common.segment.start);
2965 gst_message_set_seqnum (msg, seqnum);
2966 gst_element_post_message (GST_ELEMENT (demux), msg);
2969 GST_OBJECT_LOCK (demux);
2970 if (demux->new_segment)
2971 gst_event_unref (demux->new_segment);
2973 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2974 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2975 gst_event_set_seqnum (demux->new_segment, seqnum);
2976 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2977 demux->to_time = demux->common.segment.position;
2979 demux->to_time = GST_CLOCK_TIME_NONE;
2980 demux->segment_seqnum = seqnum;
2981 GST_OBJECT_UNLOCK (demux);
2983 /* restart our task since it might have been stopped when we did the
2985 gst_pad_start_task (demux->common.sinkpad,
2986 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2988 /* streaming can continue now */
2990 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2998 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
3000 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
3006 * Handle whether we can perform the seek event or if we have to let the chain
3007 * function handle seeks to build the seek indexes first.
3010 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
3014 GstSeekType cur_type, stop_type;
3019 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
3024 /* we can only seek on time */
3025 if (format != GST_FORMAT_TIME) {
3026 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
3030 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
3031 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
3035 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
3036 GST_DEBUG_OBJECT (demux,
3037 "Non-flushing seek not supported in streaming mode");
3041 if (flags & GST_SEEK_FLAG_SEGMENT) {
3042 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
3046 /* check for having parsed index already */
3047 if (!demux->common.index_parsed) {
3048 gboolean building_index;
3051 if (!demux->index_offset) {
3052 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
3056 GST_OBJECT_LOCK (demux);
3057 /* handle the seek event in the chain function */
3058 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
3059 /* no more seek can be issued until state reset to _DATA */
3061 /* copy the event */
3062 if (demux->seek_event)
3063 gst_event_unref (demux->seek_event);
3064 demux->seek_event = gst_event_ref (event);
3066 /* set the building_index flag so that only one thread can setup the
3067 * structures for index seeking. */
3068 building_index = demux->building_index;
3069 if (!building_index) {
3070 demux->building_index = TRUE;
3071 offset = demux->index_offset;
3073 GST_OBJECT_UNLOCK (demux);
3075 if (!building_index) {
3076 /* seek to the first subindex or legacy index */
3077 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
3078 return perform_seek_to_offset (demux, rate, offset,
3079 gst_event_get_seqnum (event), GST_SEEK_FLAG_NONE);
3082 /* well, we are handling it already */
3086 /* delegate to tweaked regular seek */
3087 return gst_matroska_demux_handle_seek_event (demux, pad, event);
3091 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
3094 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
3095 gboolean res = TRUE;
3097 switch (GST_EVENT_TYPE (event)) {
3098 case GST_EVENT_SEEK:
3099 /* no seeking until we are (safely) ready */
3100 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
3101 GST_DEBUG_OBJECT (demux,
3102 "not ready for seeking yet, deferring seek event: %" GST_PTR_FORMAT,
3104 if (demux->deferred_seek_event)
3105 gst_event_unref (demux->deferred_seek_event);
3106 demux->deferred_seek_event = event;
3107 demux->deferred_seek_pad = pad;
3112 guint32 seqnum = gst_event_get_seqnum (event);
3113 if (seqnum == demux->segment_seqnum) {
3114 GST_LOG_OBJECT (pad,
3115 "Drop duplicated SEEK event seqnum %" G_GUINT32_FORMAT, seqnum);
3116 gst_event_unref (event);
3121 if (!demux->streaming)
3122 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
3124 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
3125 gst_event_unref (event);
3130 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
3131 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3132 GstMatroskaTrackVideoContext *videocontext =
3133 (GstMatroskaTrackVideoContext *) context;
3135 GstClockTimeDiff diff;
3136 GstClockTime timestamp;
3138 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
3140 GST_OBJECT_LOCK (demux);
3141 videocontext->earliest_time = timestamp + diff;
3142 GST_OBJECT_UNLOCK (demux);
3145 gst_event_unref (event);
3149 case GST_EVENT_TOC_SELECT:
3152 GstTocEntry *entry = NULL;
3153 GstEvent *seek_event;
3156 if (!demux->common.toc) {
3157 GST_DEBUG_OBJECT (demux, "no TOC to select");
3160 gst_event_parse_toc_select (event, &uid);
3162 GST_OBJECT_LOCK (demux);
3163 entry = gst_toc_find_entry (demux->common.toc, uid);
3164 if (entry == NULL) {
3165 GST_OBJECT_UNLOCK (demux);
3166 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
3169 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
3170 GST_OBJECT_UNLOCK (demux);
3171 seek_event = gst_event_new_seek (1.0,
3173 GST_SEEK_FLAG_FLUSH,
3174 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
3175 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
3176 gst_event_unref (seek_event);
3180 GST_WARNING_OBJECT (demux, "received empty TOC select event");
3184 gst_event_unref (event);
3188 /* events we don't need to handle */
3189 case GST_EVENT_NAVIGATION:
3190 gst_event_unref (event);
3194 case GST_EVENT_LATENCY:
3196 res = gst_pad_push_event (demux->common.sinkpad, event);
3204 gst_matroska_demux_handle_sink_query (GstPad * pad, GstObject * parent,
3207 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
3208 gboolean res = FALSE;
3210 switch (GST_QUERY_TYPE (query)) {
3211 case GST_QUERY_BITRATE:
3213 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
3214 demux->common.offset >= demux->cached_length)) {
3215 demux->cached_length =
3216 gst_matroska_read_common_get_length (&demux->common);
3219 if (demux->cached_length < G_MAXUINT64
3220 && demux->common.segment.duration > 0) {
3221 /* TODO: better results based on ranges/index tables */
3223 gst_util_uint64_scale (8 * demux->cached_length, GST_SECOND,
3224 demux->common.segment.duration);
3226 GST_LOG_OBJECT (demux, "bitrate query byte length: %" G_GUINT64_FORMAT
3227 " duration %" GST_TIME_FORMAT " resulting in a bitrate of %u",
3228 demux->cached_length,
3229 GST_TIME_ARGS (demux->common.segment.duration), bitrate);
3231 gst_query_set_bitrate (query, bitrate);
3237 res = gst_pad_query_default (pad, (GstObject *) demux, query);
3244 static GstFlowReturn
3245 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
3247 GstFlowReturn ret = GST_FLOW_EOS;
3248 gboolean done = TRUE;
3251 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
3252 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
3255 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
3257 if (!demux->seek_entry) {
3258 GST_DEBUG_OBJECT (demux, "no earlier index entry");
3262 for (i = 0; i < demux->common.src->len; i++) {
3263 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
3265 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
3266 ", stream %d at %" GST_TIME_FORMAT,
3267 GST_TIME_ARGS (demux->common.segment.start), stream->index,
3268 GST_TIME_ARGS (stream->from_time));
3269 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
3270 if (stream->from_time > demux->common.segment.start) {
3271 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
3275 /* nothing pushed for this stream;
3276 * likely seek entry did not start at keyframe, so all was skipped.
3277 * So we need an earlier entry */
3283 GstMatroskaIndex *entry;
3285 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
3286 --demux->seek_entry);
3287 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
3297 static GstFlowReturn
3298 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3300 GstFlowReturn ret = GST_FLOW_OK;
3303 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
3305 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3306 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3310 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3311 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3315 /* one track within the "all-tracks" header */
3316 case GST_MATROSKA_ID_TRACKENTRY:{
3317 GstMatroskaTrackContext *track;
3318 ret = gst_matroska_demux_parse_stream (demux, ebml, &track);
3319 if (track != NULL) {
3320 if (gst_matroska_read_common_tracknumber_unique (&demux->common,
3322 gst_matroska_demux_add_stream (demux, track);
3324 GST_ERROR_OBJECT (demux,
3325 "TrackNumber %" G_GUINT64_FORMAT " is not unique", track->num);
3326 ret = GST_FLOW_ERROR;
3327 gst_matroska_track_free (track);
3335 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3340 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3342 demux->tracks_parsed = TRUE;
3343 GST_DEBUG_OBJECT (demux, "signaling no more pads");
3344 gst_element_no_more_pads (GST_ELEMENT (demux));
3349 static GstFlowReturn
3350 gst_matroska_demux_update_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3352 GstFlowReturn ret = GST_FLOW_OK;
3353 guint num_tracks_found = 0;
3356 GST_INFO_OBJECT (demux, "Reparsing Tracks element");
3358 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
3360 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3361 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3365 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3366 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3370 /* one track within the "all-tracks" header */
3371 case GST_MATROSKA_ID_TRACKENTRY:{
3372 GstMatroskaTrackContext *new_track;
3373 gint old_track_index;
3374 GstMatroskaTrackContext *old_track;
3375 ret = gst_matroska_demux_parse_stream (demux, ebml, &new_track);
3376 if (new_track == NULL)
3380 if (gst_matroska_read_common_tracknumber_unique (&demux->common,
3382 GST_ERROR_OBJECT (demux,
3383 "Unexpected new TrackNumber: %" G_GUINT64_FORMAT, new_track->num);
3384 goto track_mismatch_error;
3388 gst_matroska_read_common_stream_from_num (&demux->common,
3390 g_assert (old_track_index != -1);
3391 old_track = g_ptr_array_index (demux->common.src, old_track_index);
3393 if (old_track->type != new_track->type) {
3394 GST_ERROR_OBJECT (demux,
3395 "Mismatch reparsing track %" G_GUINT64_FORMAT
3396 " on track type. Expected %d, found %d", new_track->num,
3397 old_track->type, new_track->type);
3398 goto track_mismatch_error;
3401 if (g_strcmp0 (old_track->codec_id, new_track->codec_id) != 0) {
3402 GST_ERROR_OBJECT (demux,
3403 "Mismatch reparsing track %" G_GUINT64_FORMAT
3404 " on codec id. Expected '%s', found '%s'", new_track->num,
3405 old_track->codec_id, new_track->codec_id);
3406 goto track_mismatch_error;
3409 /* The new track matches the old track. No problems on our side.
3410 * Let's make it replace the old track. */
3411 new_track->pad = old_track->pad;
3412 new_track->index = old_track->index;
3413 new_track->pos = old_track->pos;
3414 g_ptr_array_index (demux->common.src, old_track_index) = new_track;
3415 gst_pad_set_element_private (new_track->pad, new_track);
3417 if (!gst_caps_is_equal (old_track->caps, new_track->caps)) {
3418 gst_pad_set_caps (new_track->pad, new_track->caps);
3420 gst_caps_replace (&old_track->caps, NULL);
3422 if (!gst_tag_list_is_equal (old_track->tags, new_track->tags)) {
3423 GST_DEBUG_OBJECT (old_track->pad, "Sending tags %p: %"
3424 GST_PTR_FORMAT, new_track->tags, new_track->tags);
3425 gst_pad_push_event (new_track->pad,
3426 gst_event_new_tag (gst_tag_list_copy (new_track->tags)));
3429 gst_matroska_track_free (old_track);
3432 track_mismatch_error:
3433 gst_matroska_track_free (new_track);
3435 ret = GST_FLOW_ERROR;
3440 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3445 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3447 if (ret != GST_FLOW_ERROR && demux->common.num_streams != num_tracks_found) {
3448 GST_ERROR_OBJECT (demux,
3449 "Mismatch on the number of tracks. Expected %du tracks, found %du",
3450 demux->common.num_streams, num_tracks_found);
3451 ret = GST_FLOW_ERROR;
3458 * Read signed/unsigned "EBML" numbers.
3459 * Return: number of bytes processed.
3463 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
3465 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
3473 while (read <= 8 && !(total & len_mask)) {
3480 if ((total &= (len_mask - 1)) == len_mask - 1)
3485 if (data[n] == 0xff)
3487 total = (total << 8) | data[n];
3491 if (read == num_ffs && total != 0)
3500 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
3505 /* read as unsigned number first */
3506 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
3510 if (unum == G_MAXUINT64)
3513 *num = unum - ((1 << ((7 * res) - 1)) - 1);
3519 * Mostly used for subtitles. We add void filler data for each
3520 * lagging stream to make sure we don't deadlock.
3524 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
3526 GstClockTime gap_threshold;
3529 GST_OBJECT_LOCK (demux);
3531 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
3532 GST_TIME_ARGS (demux->common.segment.position));
3534 g_assert (demux->common.num_streams == demux->common.src->len);
3535 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
3536 GstMatroskaTrackContext *context;
3538 context = g_ptr_array_index (demux->common.src, stream_nr);
3540 GST_LOG_OBJECT (demux,
3541 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
3542 GST_TIME_ARGS (context->pos));
3544 /* Only send gap events on non-subtitle streams if lagging way behind.
3545 * The 0.5 second threshold for subtitle streams is also quite random. */
3546 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
3547 gap_threshold = GST_SECOND / 2;
3549 gap_threshold = 3 * GST_SECOND;
3551 /* Lag need only be considered if we have advanced into requested segment */
3552 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
3553 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3554 demux->common.segment.position > demux->common.segment.start &&
3555 context->pos + gap_threshold < demux->common.segment.position) {
3558 guint64 start = context->pos;
3559 guint64 stop = demux->common.segment.position - gap_threshold;
3561 GST_DEBUG_OBJECT (demux,
3562 "Synchronizing stream %d with other by advancing time from %"
3563 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
3564 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
3566 context->pos = stop;
3568 event = gst_event_new_gap (start, stop - start);
3569 GST_OBJECT_UNLOCK (demux);
3570 gst_pad_push_event (context->pad, event);
3571 GST_OBJECT_LOCK (demux);
3575 GST_OBJECT_UNLOCK (demux);
3578 static GstFlowReturn
3579 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
3580 GstMatroskaTrackContext * stream)
3582 GstFlowReturn ret = GST_FLOW_OK;
3585 num = gst_buffer_list_length (stream->stream_headers);
3586 for (i = 0; i < num; ++i) {
3589 buf = gst_buffer_list_get (stream->stream_headers, i);
3590 buf = gst_buffer_copy (buf);
3592 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
3594 if (stream->set_discont) {
3595 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
3596 stream->set_discont = FALSE;
3598 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
3601 /* push out all headers in one go and use last flow return */
3602 ret = gst_pad_push (stream->pad, buf);
3605 /* don't need these any longer */
3606 gst_buffer_list_unref (stream->stream_headers);
3607 stream->stream_headers = NULL;
3610 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3616 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
3617 GstMatroskaTrackContext * stream)
3621 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
3623 if (!stream->codec_priv)
3626 /* ideally, VobSub private data should be parsed and stored more convenient
3627 * elsewhere, but for now, only interested in a small part */
3629 /* make sure we have terminating 0 */
3630 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
3632 /* just locate and parse palette part */
3633 start = strstr (buf, "palette:");
3638 guint8 r, g, b, y, u, v;
3641 while (g_ascii_isspace (*start))
3643 for (i = 0; i < 16; i++) {
3644 if (sscanf (start, "%06x", &col) != 1)
3647 while ((*start == ',') || g_ascii_isspace (*start))
3649 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
3650 r = (col >> 16) & 0xff;
3651 g = (col >> 8) & 0xff;
3653 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
3655 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
3656 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
3657 clut[i] = (y << 16) | (u << 8) | v;
3660 /* got them all without problems; build and send event */
3664 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
3665 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
3666 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
3667 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
3668 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
3669 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
3670 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
3671 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
3672 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
3673 G_TYPE_INT, clut[15], NULL);
3675 gst_pad_push_event (stream->pad,
3676 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
3683 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
3687 g_assert (demux->common.num_streams == demux->common.src->len);
3688 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
3689 GstMatroskaTrackContext *stream;
3691 stream = g_ptr_array_index (demux->common.src, stream_nr);
3693 if (stream->send_stream_headers) {
3694 if (stream->stream_headers != NULL) {
3695 gst_matroska_demux_push_stream_headers (demux, stream);
3697 /* FIXME: perhaps we can just disable and skip this stream then */
3698 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
3699 ("Failed to extract stream headers from codec private data"));
3701 stream->send_stream_headers = FALSE;
3704 if (stream->send_dvd_event) {
3705 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
3706 /* FIXME: should we send this event again after (flushing) seek ? */
3707 stream->send_dvd_event = FALSE;
3713 static GstFlowReturn
3714 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
3715 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3718 guint seq_header_len;
3719 guint32 header, tmp;
3721 if (stream->codec_state) {
3722 seq_header = stream->codec_state;
3723 seq_header_len = stream->codec_state_size;
3724 } else if (stream->codec_priv) {
3725 seq_header = stream->codec_priv;
3726 seq_header_len = stream->codec_priv_size;
3731 /* Sequence header only needed for keyframes */
3732 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
3735 if (gst_buffer_get_size (*buf) < 4)
3738 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
3739 header = GUINT32_FROM_BE (tmp);
3741 /* Sequence start code, if not found prepend */
3742 if (header != 0x000001b3) {
3745 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
3747 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
3750 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
3751 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
3752 gst_buffer_get_size (*buf));
3754 gst_buffer_unref (*buf);
3761 static GstFlowReturn
3762 gst_matroska_demux_add_wvpk_header (GstElement * element,
3763 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3765 GstMatroskaTrackAudioContext *audiocontext =
3766 (GstMatroskaTrackAudioContext *) stream;
3767 GstBuffer *newbuf = NULL;
3768 GstMapInfo map, outmap;
3769 guint8 *buf_data, *data;
3777 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
3780 wvh.total_samples = -1;
3781 wvh.block_index = audiocontext->wvpk_block_index;
3783 if (audiocontext->channels <= 2) {
3784 guint32 block_samples, tmp;
3785 gsize size = gst_buffer_get_size (*buf);
3787 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
3788 block_samples = GUINT32_FROM_LE (tmp);
3789 /* we need to reconstruct the header of the wavpack block */
3791 /* -20 because ck_size is the size of the wavpack block -8
3792 * and lace_size is the size of the wavpack block + 12
3793 * (the three guint32 of the header that already are in the buffer) */
3794 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
3796 /* block_samples, flags and crc are already in the buffer */
3797 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
3799 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3805 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
3806 GST_WRITE_UINT16_LE (data + 8, wvh.version);
3807 GST_WRITE_UINT8 (data + 10, wvh.track_no);
3808 GST_WRITE_UINT8 (data + 11, wvh.index_no);
3809 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
3810 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
3811 gst_buffer_unmap (newbuf, &outmap);
3813 /* Append data from buf: */
3814 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
3815 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
3817 gst_buffer_unref (*buf);
3819 audiocontext->wvpk_block_index += block_samples;
3821 guint8 *outdata = NULL;
3823 gsize buf_size, size, out_size = 0;
3824 guint32 block_samples, flags, crc, blocksize;
3826 gst_buffer_map (*buf, &map, GST_MAP_READ);
3827 buf_data = map.data;
3828 buf_size = map.size;
3831 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
3832 gst_buffer_unmap (*buf, &map);
3833 return GST_FLOW_ERROR;
3839 block_samples = GST_READ_UINT32_LE (data);
3844 flags = GST_READ_UINT32_LE (data);
3847 crc = GST_READ_UINT32_LE (data);
3850 blocksize = GST_READ_UINT32_LE (data);
3854 if (blocksize == 0 || size < blocksize)
3857 g_assert ((newbuf == NULL) == (outdata == NULL));
3859 if (newbuf == NULL) {
3860 out_size = sizeof (Wavpack4Header) + blocksize;
3861 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
3863 gst_buffer_copy_into (newbuf, *buf,
3864 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
3867 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3868 outdata = outmap.data;
3870 gst_buffer_unmap (newbuf, &outmap);
3871 out_size += sizeof (Wavpack4Header) + blocksize;
3872 gst_buffer_set_size (newbuf, out_size);
3873 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3874 outdata = outmap.data;
3877 outdata[outpos] = 'w';
3878 outdata[outpos + 1] = 'v';
3879 outdata[outpos + 2] = 'p';
3880 outdata[outpos + 3] = 'k';
3883 GST_WRITE_UINT32_LE (outdata + outpos,
3884 blocksize + sizeof (Wavpack4Header) - 8);
3885 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
3886 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
3887 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
3888 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
3889 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
3890 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
3891 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
3892 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
3895 memmove (outdata + outpos, data, blocksize);
3896 outpos += blocksize;
3900 gst_buffer_unmap (*buf, &map);
3901 gst_buffer_unref (*buf);
3904 gst_buffer_unmap (newbuf, &outmap);
3907 audiocontext->wvpk_block_index += block_samples;
3913 static GstFlowReturn
3914 gst_matroska_demux_add_prores_header (GstElement * element,
3915 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3917 GstBuffer *newbuf = gst_buffer_new_allocate (NULL, 8, NULL);
3921 if (!gst_buffer_map (newbuf, &map, GST_MAP_WRITE)) {
3922 GST_ERROR ("Failed to map newly allocated buffer");
3923 return GST_FLOW_ERROR;
3926 frame_size = gst_buffer_get_size (*buf);
3928 GST_WRITE_UINT32_BE (map.data, frame_size);
3934 gst_buffer_unmap (newbuf, &map);
3935 *buf = gst_buffer_append (newbuf, *buf);
3940 /* @text must be null-terminated */
3942 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
3947 g_return_val_if_fail (text != NULL, FALSE);
3949 /* yes, this might all lead to false positives ... */
3950 tag = (gchar *) text;
3951 while ((tag = strchr (tag, '<'))) {
3953 if (*tag != '\0' && *(tag + 1) == '>') {
3954 /* some common convenience ones */
3955 /* maybe any character will do here ? */
3968 if (strstr (text, "<span"))
3974 static GstFlowReturn
3975 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
3976 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3978 GstMatroskaTrackSubtitleContext *sub_stream;
3979 const gchar *encoding;
3984 gboolean needs_unmap = TRUE;
3986 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3988 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
3991 /* The subtitle buffer we push out should not include a NUL terminator as
3992 * part of the data. */
3993 if (map.data[map.size - 1] == '\0') {
3994 gst_buffer_set_size (*buf, map.size - 1);
3995 gst_buffer_unmap (*buf, &map);
3996 gst_buffer_map (*buf, &map, GST_MAP_READ);
3999 if (!sub_stream->invalid_utf8) {
4000 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
4003 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
4004 " is not valid UTF-8, this is broken according to the matroska"
4005 " specification", stream->num);
4006 sub_stream->invalid_utf8 = TRUE;
4009 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
4010 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
4011 if (encoding == NULL || *encoding == '\0') {
4012 /* if local encoding is UTF-8 and no encoding specified
4013 * via the environment variable, assume ISO-8859-15 */
4014 if (g_get_charset (&encoding)) {
4015 encoding = "ISO-8859-15";
4020 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
4021 (char *) "*", NULL, NULL, &err);
4024 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
4025 encoding, err->message);
4029 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
4030 encoding = "ISO-8859-15";
4032 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
4033 encoding, (char *) "*", NULL, NULL, NULL);
4036 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
4037 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
4040 utf8 = g_strdup ("invalid subtitle");
4042 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
4043 gst_buffer_unmap (*buf, &map);
4044 gst_buffer_copy_into (newbuf, *buf,
4045 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
4047 gst_buffer_unref (*buf);
4050 gst_buffer_map (*buf, &map, GST_MAP_READ);
4054 if (sub_stream->check_markup) {
4055 /* caps claim markup text, so we need to escape text,
4056 * except if text is already markup and then needs no further escaping */
4057 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
4058 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
4060 if (!sub_stream->seen_markup_tag) {
4061 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
4063 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
4064 gst_buffer_unmap (*buf, &map);
4065 gst_buffer_copy_into (newbuf, *buf,
4066 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
4067 GST_BUFFER_COPY_META, 0, -1);
4068 gst_buffer_unref (*buf);
4071 needs_unmap = FALSE;
4076 gst_buffer_unmap (*buf, &map);
4081 static GstFlowReturn
4082 gst_matroska_demux_check_aac (GstElement * element,
4083 GstMatroskaTrackContext * stream, GstBuffer ** buf)
4088 gst_buffer_extract (*buf, 0, data, 2);
4089 size = gst_buffer_get_size (*buf);
4091 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
4094 /* tss, ADTS data, remove codec_data
4095 * still assume it is at least parsed */
4096 stream->caps = gst_caps_make_writable (stream->caps);
4097 s = gst_caps_get_structure (stream->caps, 0);
4099 gst_structure_remove_field (s, "codec_data");
4100 gst_pad_set_caps (stream->pad, stream->caps);
4101 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
4102 "new caps: %" GST_PTR_FORMAT, stream->caps);
4105 /* disable subsequent checking */
4106 stream->postprocess_frame = NULL;
4112 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
4113 GstBuffer * buffer, gsize alignment)
4117 gst_buffer_map (buffer, &map, GST_MAP_READ);
4119 if (map.size < sizeof (guintptr)) {
4120 gst_buffer_unmap (buffer, &map);
4124 if (((guintptr) map.data) & (alignment - 1)) {
4125 GstBuffer *new_buffer;
4126 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
4128 new_buffer = gst_buffer_new_allocate (NULL,
4129 gst_buffer_get_size (buffer), ¶ms);
4131 /* Copy data "by hand", so ensure alignment is kept: */
4132 gst_buffer_fill (new_buffer, 0, map.data, map.size);
4134 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
4135 GST_DEBUG_OBJECT (demux,
4136 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
4139 gst_buffer_unmap (buffer, &map);
4140 gst_buffer_unref (buffer);
4145 gst_buffer_unmap (buffer, &map);
4149 static GstFlowReturn
4150 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
4151 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
4152 gboolean is_simpleblock)
4154 GstMatroskaTrackContext *stream = NULL;
4155 GstFlowReturn ret = GST_FLOW_OK;
4156 gboolean readblock = FALSE;
4158 guint64 block_duration = -1;
4159 gint64 block_discardpadding = 0;
4160 GstBuffer *buf = NULL;
4162 gint stream_num = -1, n, laces = 0;
4164 gint *lace_size = NULL;
4167 gint64 referenceblock = 0;
4169 GstClockTime buffer_timestamp;
4171 offset = gst_ebml_read_get_offset (ebml);
4173 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4174 if (!is_simpleblock) {
4175 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
4179 id = GST_MATROSKA_ID_SIMPLEBLOCK;
4183 /* one block inside the group. Note, block parsing is one
4184 * of the harder things, so this code is a bit complicated.
4185 * See http://www.matroska.org/ for documentation. */
4186 case GST_MATROSKA_ID_SIMPLEBLOCK:
4187 case GST_MATROSKA_ID_BLOCK:
4193 gst_buffer_unmap (buf, &map);
4194 gst_buffer_unref (buf);
4197 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
4200 gst_buffer_map (buf, &map, GST_MAP_READ);
4204 /* first byte(s): blocknum */
4205 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
4210 /* fetch stream from num */
4211 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
4213 if (G_UNLIKELY (size < 3)) {
4214 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
4215 /* non-fatal, try next block(group) */
4218 } else if (G_UNLIKELY (stream_num < 0 ||
4219 stream_num >= demux->common.num_streams)) {
4220 /* let's not give up on a stray invalid track number */
4221 GST_WARNING_OBJECT (demux,
4222 "Invalid stream %d for track number %" G_GUINT64_FORMAT
4223 "; ignoring block", stream_num, num);
4227 stream = g_ptr_array_index (demux->common.src, stream_num);
4229 /* time (relative to cluster time) */
4230 time = ((gint16) GST_READ_UINT16_BE (data));
4233 flags = GST_READ_UINT8 (data);
4237 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
4240 switch ((flags & 0x06) >> 1) {
4241 case 0x0: /* no lacing */
4243 lace_size = g_new (gint, 1);
4244 lace_size[0] = size;
4247 case 0x1: /* xiph lacing */
4248 case 0x2: /* fixed-size lacing */
4249 case 0x3: /* EBML lacing */
4251 goto invalid_lacing;
4252 laces = GST_READ_UINT8 (data) + 1;
4255 lace_size = g_new0 (gint, laces);
4257 switch ((flags & 0x06) >> 1) {
4258 case 0x1: /* xiph lacing */ {
4259 guint temp, total = 0;
4261 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
4264 goto invalid_lacing;
4265 temp = GST_READ_UINT8 (data);
4266 lace_size[n] += temp;
4272 total += lace_size[n];
4274 lace_size[n] = size - total;
4278 case 0x2: /* fixed-size lacing */
4279 for (n = 0; n < laces; n++)
4280 lace_size[n] = size / laces;
4283 case 0x3: /* EBML lacing */ {
4286 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
4290 total = lace_size[0] = num;
4291 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
4295 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
4299 lace_size[n] = lace_size[n - 1] + snum;
4300 total += lace_size[n];
4303 lace_size[n] = size - total;
4310 if (ret != GST_FLOW_OK)
4317 case GST_MATROSKA_ID_BLOCKDURATION:{
4318 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
4319 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
4324 case GST_MATROSKA_ID_DISCARDPADDING:{
4325 ret = gst_ebml_read_sint (ebml, &id, &block_discardpadding);
4326 GST_DEBUG_OBJECT (demux, "DiscardPadding: %" GST_STIME_FORMAT,
4327 GST_STIME_ARGS (block_discardpadding));
4331 case GST_MATROSKA_ID_REFERENCEBLOCK:{
4332 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
4333 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
4338 case GST_MATROSKA_ID_CODECSTATE:{
4340 guint64 data_len = 0;
4343 gst_ebml_read_binary (ebml, &id, &data,
4344 &data_len)) != GST_FLOW_OK)
4347 if (G_UNLIKELY (stream == NULL)) {
4348 GST_WARNING_OBJECT (demux,
4349 "Unexpected CodecState subelement - ignoring");
4353 g_free (stream->codec_state);
4354 stream->codec_state = data;
4355 stream->codec_state_size = data_len;
4357 /* Decode if necessary */
4358 if (stream->encodings && stream->encodings->len > 0
4359 && stream->codec_state && stream->codec_state_size > 0) {
4360 if (!gst_matroska_decode_data (stream->encodings,
4361 &stream->codec_state, &stream->codec_state_size,
4362 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
4363 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
4367 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
4368 stream->codec_state_size);
4373 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
4377 case GST_MATROSKA_ID_BLOCKVIRTUAL:
4378 case GST_MATROSKA_ID_BLOCKADDITIONS:
4379 case GST_MATROSKA_ID_REFERENCEPRIORITY:
4380 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
4381 case GST_MATROSKA_ID_SLICES:
4382 GST_DEBUG_OBJECT (demux,
4383 "Skipping BlockGroup subelement 0x%x - ignoring", id);
4384 ret = gst_ebml_read_skip (ebml);
4392 /* reading a number or so could have failed */
4393 if (ret != GST_FLOW_OK)
4396 if (ret == GST_FLOW_OK && readblock) {
4397 gboolean invisible_frame = FALSE;
4398 gboolean delta_unit = FALSE;
4399 guint64 duration = 0;
4400 gint64 lace_time = 0;
4401 GstEvent *protect_event;
4403 stream = g_ptr_array_index (demux->common.src, stream_num);
4405 if (cluster_time != GST_CLOCK_TIME_NONE) {
4406 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
4407 * Drop unless the lace contains timestamp 0? */
4408 if (time < 0 && (-time) > cluster_time) {
4411 if (stream->timecodescale == 1.0)
4412 lace_time = (cluster_time + time) * demux->common.time_scale;
4415 gst_util_guint64_to_gdouble ((cluster_time + time) *
4416 demux->common.time_scale) * stream->timecodescale;
4419 lace_time = GST_CLOCK_TIME_NONE;
4421 /* Send the GST_PROTECTION event */
4422 while ((protect_event = g_queue_pop_head (&stream->protection_event_queue))) {
4423 GST_TRACE_OBJECT (demux, "pushing protection event for stream %d:%s",
4424 stream->index, GST_STR_NULL (stream->name));
4425 gst_pad_push_event (stream->pad, protect_event);
4428 /* need to refresh segment info ASAP */
4429 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
4430 GstSegment *segment = &demux->common.segment;
4432 GstEvent *segment_event;
4434 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
4435 demux->stream_start_time = lace_time;
4436 GST_DEBUG_OBJECT (demux,
4437 "Setting stream start time to %" GST_TIME_FORMAT,
4438 GST_TIME_ARGS (lace_time));
4440 clace_time = MAX (lace_time, demux->stream_start_time);
4441 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
4442 demux->common.segment.position != 0) {
4443 GST_DEBUG_OBJECT (demux,
4444 "using stored seek position %" GST_TIME_FORMAT,
4445 GST_TIME_ARGS (demux->common.segment.position));
4446 clace_time = demux->common.segment.position;
4447 segment->position = GST_CLOCK_TIME_NONE;
4449 segment->start = clace_time;
4450 segment->stop = GST_CLOCK_TIME_NONE;
4451 segment->time = segment->start - demux->stream_start_time;
4452 segment->position = segment->start - demux->stream_start_time;
4453 GST_DEBUG_OBJECT (demux,
4454 "generated segment starting at %" GST_TIME_FORMAT ": %"
4455 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
4456 /* now convey our segment notion downstream */
4457 segment_event = gst_event_new_segment (segment);
4458 if (demux->segment_seqnum)
4459 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
4460 gst_matroska_demux_send_event (demux, segment_event);
4461 demux->need_segment = FALSE;
4462 demux->segment_seqnum = 0;
4465 /* send pending codec data headers for all streams,
4466 * before we perform sync across all streams */
4467 gst_matroska_demux_push_codec_data_all (demux);
4469 if (block_duration != -1) {
4470 if (stream->timecodescale == 1.0)
4471 duration = gst_util_uint64_scale (block_duration,
4472 demux->common.time_scale, 1);
4475 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
4476 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
4477 1)) * stream->timecodescale);
4478 } else if (stream->default_duration) {
4479 duration = stream->default_duration * laces;
4481 /* else duration is diff between timecode of this and next block */
4483 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
4484 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
4485 a ReferenceBlock implies that this is not a keyframe. In either
4486 case, it only makes sense for video streams. */
4487 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
4489 invisible_frame = ((flags & 0x08)) &&
4490 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
4491 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9) ||
4492 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_AV1));
4495 /* If we're doing a keyframe-only trickmode, only push keyframes on video
4498 && demux->common.segment.
4499 flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) {
4500 GST_LOG_OBJECT (demux, "Skipping non-keyframe on stream %d",
4507 for (n = 0; n < laces; n++) {
4510 if (G_UNLIKELY (lace_size[n] > size)) {
4511 GST_WARNING_OBJECT (demux, "Invalid lace size");
4515 /* QoS for video track with an index. the assumption is that
4516 index entries point to keyframes, but if that is not true we
4517 will instad skip until the next keyframe. */
4518 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
4519 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
4520 stream->index_table && demux->common.segment.rate > 0.0) {
4521 GstMatroskaTrackVideoContext *videocontext =
4522 (GstMatroskaTrackVideoContext *) stream;
4523 GstClockTime earliest_time;
4524 GstClockTime earliest_stream_time;
4526 GST_OBJECT_LOCK (demux);
4527 earliest_time = videocontext->earliest_time;
4528 GST_OBJECT_UNLOCK (demux);
4529 earliest_stream_time =
4530 gst_segment_position_from_running_time (&demux->common.segment,
4531 GST_FORMAT_TIME, earliest_time);
4533 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
4534 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
4535 lace_time <= earliest_stream_time) {
4536 /* find index entry (keyframe) <= earliest_stream_time */
4537 GstMatroskaIndex *entry =
4538 gst_util_array_binary_search (stream->index_table->data,
4539 stream->index_table->len, sizeof (GstMatroskaIndex),
4540 (GCompareDataFunc) gst_matroska_index_seek_find,
4541 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
4543 /* if that entry (keyframe) is after the current the current
4544 buffer, we can skip pushing (and thus decoding) all
4545 buffers until that keyframe. */
4546 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
4547 entry->time > lace_time) {
4548 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
4549 stream->set_discont = TRUE;
4555 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
4556 gst_buffer_get_size (buf) - size, lace_size[n]);
4557 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
4560 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4562 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4564 if (invisible_frame)
4565 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
4567 if (stream->encodings != NULL && stream->encodings->len > 0)
4568 sub = gst_matroska_decode_buffer (stream, sub);
4571 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
4575 if (!stream->dts_only) {
4576 GST_BUFFER_PTS (sub) = lace_time;
4578 GST_BUFFER_DTS (sub) = lace_time;
4579 if (stream->intra_only)
4580 GST_BUFFER_PTS (sub) = lace_time;
4583 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
4585 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
4586 GstClockTime last_stop_end;
4588 /* Check if this stream is after segment stop */
4589 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
4590 lace_time >= demux->common.segment.stop) {
4591 GST_DEBUG_OBJECT (demux,
4592 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
4593 GST_TIME_ARGS (demux->common.segment.stop));
4594 gst_buffer_unref (sub);
4597 if (offset >= stream->to_offset
4598 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
4599 && lace_time > demux->to_time)) {
4600 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
4602 gst_buffer_unref (sub);
4606 /* handle gaps, e.g. non-zero start-time, or an cue index entry
4607 * that landed us with timestamps not quite intended */
4608 GST_OBJECT_LOCK (demux);
4609 if (demux->max_gap_time &&
4610 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
4611 demux->common.segment.rate > 0.0) {
4612 GstClockTimeDiff diff;
4614 /* only send segments with increasing start times,
4615 * otherwise if these go back and forth downstream (sinks) increase
4616 * accumulated time and running_time */
4617 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
4618 if (diff > 0 && diff > demux->max_gap_time
4619 && lace_time > demux->common.segment.start
4620 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
4621 || lace_time < demux->common.segment.stop)) {
4623 GST_DEBUG_OBJECT (demux,
4624 "Gap of %" G_GINT64_FORMAT " ns detected in"
4625 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
4626 "Sending updated SEGMENT events", diff,
4627 stream->index, GST_TIME_ARGS (stream->pos),
4628 GST_TIME_ARGS (lace_time));
4630 event = gst_event_new_gap (demux->last_stop_end, diff);
4631 GST_OBJECT_UNLOCK (demux);
4632 gst_pad_push_event (stream->pad, event);
4633 GST_OBJECT_LOCK (demux);
4637 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
4638 || demux->common.segment.position < lace_time) {
4639 demux->common.segment.position = lace_time;
4641 GST_OBJECT_UNLOCK (demux);
4643 last_stop_end = lace_time;
4645 GST_BUFFER_DURATION (sub) = duration / laces;
4646 last_stop_end += GST_BUFFER_DURATION (sub);
4649 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
4650 demux->last_stop_end < last_stop_end)
4651 demux->last_stop_end = last_stop_end;
4653 GST_OBJECT_LOCK (demux);
4654 if (demux->common.segment.duration == -1 ||
4655 demux->stream_start_time + demux->common.segment.duration <
4657 demux->common.segment.duration =
4658 last_stop_end - demux->stream_start_time;
4659 GST_OBJECT_UNLOCK (demux);
4660 if (!demux->invalid_duration) {
4661 gst_element_post_message (GST_ELEMENT_CAST (demux),
4662 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
4663 demux->invalid_duration = TRUE;
4666 GST_OBJECT_UNLOCK (demux);
4670 stream->pos = lace_time;
4672 gst_matroska_demux_sync_streams (demux);
4674 if (stream->set_discont) {
4675 GST_DEBUG_OBJECT (demux, "marking DISCONT");
4676 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
4677 stream->set_discont = FALSE;
4679 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
4682 /* reverse playback book-keeping */
4683 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
4684 stream->from_time = lace_time;
4685 if (stream->from_offset == -1)
4686 stream->from_offset = offset;
4688 GST_DEBUG_OBJECT (demux,
4689 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
4690 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
4691 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
4692 GST_TIME_ARGS (buffer_timestamp),
4693 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
4696 if (demux->common.element_index) {
4697 if (stream->index_writer_id == -1)
4698 gst_index_get_writer_id (demux->common.element_index,
4699 GST_OBJECT (stream->pad), &stream->index_writer_id);
4701 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4702 G_GUINT64_FORMAT " for writer id %d",
4703 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
4704 stream->index_writer_id);
4705 gst_index_add_association (demux->common.element_index,
4706 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
4707 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
4708 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
4713 /* Postprocess the buffers depending on the codec used */
4714 if (stream->postprocess_frame) {
4715 GST_LOG_OBJECT (demux, "running post process");
4716 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
4719 /* At this point, we have a sub-buffer pointing at data within a larger
4720 buffer. This data might not be aligned with anything. If the data is
4721 raw samples though, we want it aligned to the raw type (eg, 4 bytes
4722 for 32 bit samples, etc), or bad things will happen downstream as
4723 elements typically assume minimal alignment.
4724 Therefore, create an aligned copy if necessary. */
4725 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
4727 if (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
4728 guint64 start_clip = 0, end_clip = 0;
4730 /* Codec delay is part of the timestamps */
4731 if (GST_BUFFER_PTS_IS_VALID (sub) && stream->codec_delay) {
4732 if (GST_BUFFER_PTS (sub) > stream->codec_delay) {
4733 GST_BUFFER_PTS (sub) -= stream->codec_delay;
4735 GST_BUFFER_PTS (sub) = 0;
4737 /* Opus GstAudioClippingMeta units are scaled by 48000/sample_rate.
4738 That is, if a Opus track has audio encoded at 24000 Hz and 132
4739 samples need to be clipped, GstAudioClippingMeta.start will be
4740 set to 264. (This is also the case for buffer offsets.)
4741 Opus sample rates are always divisors of 48000 Hz, which is the
4742 maximum allowed sample rate. */
4744 gst_util_uint64_scale_round (stream->codec_delay, 48000,
4747 if (GST_BUFFER_DURATION_IS_VALID (sub)) {
4748 if (GST_BUFFER_DURATION (sub) > stream->codec_delay)
4749 GST_BUFFER_DURATION (sub) -= stream->codec_delay;
4751 GST_BUFFER_DURATION (sub) = 0;
4756 if (block_discardpadding) {
4758 gst_util_uint64_scale_round (block_discardpadding, 48000,
4762 if (start_clip || end_clip) {
4763 gst_buffer_add_audio_clipping_meta (sub, GST_FORMAT_DEFAULT,
4764 start_clip, end_clip);
4768 if (GST_BUFFER_PTS_IS_VALID (sub)) {
4769 stream->pos = GST_BUFFER_PTS (sub);
4770 if (GST_BUFFER_DURATION_IS_VALID (sub))
4771 stream->pos += GST_BUFFER_DURATION (sub);
4772 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
4773 stream->pos = GST_BUFFER_DTS (sub);
4774 if (GST_BUFFER_DURATION_IS_VALID (sub))
4775 stream->pos += GST_BUFFER_DURATION (sub);
4778 ret = gst_pad_push (stream->pad, sub);
4780 if (demux->common.segment.rate < 0) {
4781 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
4782 /* In reverse playback we can get a GST_FLOW_EOS when
4783 * we are at the end of the segment, so we just need to jump
4784 * back to the previous section. */
4785 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
4790 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
4794 size -= lace_size[n];
4795 if (lace_time != GST_CLOCK_TIME_NONE && duration)
4796 lace_time += duration / laces;
4798 lace_time = GST_CLOCK_TIME_NONE;
4804 gst_buffer_unmap (buf, &map);
4805 gst_buffer_unref (buf);
4817 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
4823 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
4824 /* non-fatal, try next block(group) */
4830 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
4831 /* non-fatal, try next block(group) */
4837 /* return FALSE if block(group) should be skipped (due to a seek) */
4838 static inline gboolean
4839 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
4841 if (G_UNLIKELY (demux->seek_block)) {
4842 if (!(--demux->seek_block)) {
4845 GST_LOG_OBJECT (demux, "should skip block due to seek");
4853 static GstFlowReturn
4854 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
4858 guint64 seek_pos = (guint64) - 1;
4859 guint32 seek_id = 0;
4862 DEBUG_ELEMENT_START (demux, ebml, "Seek");
4864 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4865 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4869 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4870 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4874 case GST_MATROSKA_ID_SEEKID:
4878 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4881 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
4886 case GST_MATROSKA_ID_SEEKPOSITION:
4890 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4893 if (t > G_MAXINT64) {
4894 GST_WARNING_OBJECT (demux,
4895 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
4899 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
4905 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
4911 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
4914 if (!seek_id || seek_pos == (guint64) - 1) {
4915 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
4916 G_GUINT64_FORMAT ")", seek_id, seek_pos);
4921 case GST_MATROSKA_ID_SEEKHEAD:
4924 case GST_MATROSKA_ID_CUES:
4925 case GST_MATROSKA_ID_TAGS:
4926 case GST_MATROSKA_ID_TRACKS:
4927 case GST_MATROSKA_ID_SEGMENTINFO:
4928 case GST_MATROSKA_ID_ATTACHMENTS:
4929 case GST_MATROSKA_ID_CHAPTERS:
4931 guint64 before_pos, length;
4935 length = gst_matroska_read_common_get_length (&demux->common);
4936 before_pos = demux->common.offset;
4938 if (length == (guint64) - 1) {
4939 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
4943 /* check for validity */
4944 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
4945 GST_WARNING_OBJECT (demux,
4946 "SeekHead reference lies outside file!" " (%"
4947 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
4948 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
4953 /* only pick up index location when streaming */
4954 if (demux->streaming) {
4955 if (seek_id == GST_MATROSKA_ID_CUES) {
4956 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
4957 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
4958 demux->index_offset);
4964 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
4967 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4968 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
4972 if (id != seek_id) {
4973 GST_WARNING_OBJECT (demux,
4974 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
4975 seek_id, id, seek_pos + demux->common.ebml_segment_start);
4978 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4983 demux->common.offset = before_pos;
4987 case GST_MATROSKA_ID_CLUSTER:
4989 guint64 pos = seek_pos + demux->common.ebml_segment_start;
4991 GST_LOG_OBJECT (demux, "Cluster position");
4992 if (G_UNLIKELY (!demux->clusters))
4993 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
4994 g_array_append_val (demux->clusters, pos);
4999 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
5002 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
5007 static GstFlowReturn
5008 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
5010 GstFlowReturn ret = GST_FLOW_OK;
5013 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
5015 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
5016 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
5020 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
5021 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
5025 case GST_MATROSKA_ID_SEEKENTRY:
5027 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
5028 /* Ignore EOS and errors here */
5029 if (ret != GST_FLOW_OK) {
5030 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
5037 ret = gst_matroska_read_common_parse_skip (&demux->common,
5038 ebml, "SeekHead", id);
5043 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
5045 /* Sort clusters by position for easier searching */
5046 if (demux->clusters)
5047 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
5052 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
5054 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
5056 static inline GstFlowReturn
5057 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
5059 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
5060 /* only a few blocks are expected/allowed to be large,
5061 * and will be recursed into, whereas others will be read and must fit */
5062 if (demux->streaming) {
5063 /* fatal in streaming case, as we can't step over easily */
5064 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5065 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
5066 "file might be corrupt.", bytes));
5067 return GST_FLOW_ERROR;
5069 /* indicate higher level to quietly give up */
5070 GST_DEBUG_OBJECT (demux,
5071 "too large block of size %" G_GUINT64_FORMAT, bytes);
5072 return GST_FLOW_ERROR;
5079 /* returns TRUE if we truely are in error state, and should give up */
5080 static inline GstFlowReturn
5081 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
5083 if (!demux->streaming && demux->next_cluster_offset > 0) {
5084 /* just repositioning to where next cluster should be and try from there */
5085 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
5086 G_GUINT64_FORMAT, demux->next_cluster_offset);
5087 demux->common.offset = demux->next_cluster_offset;
5088 demux->next_cluster_offset = 0;
5094 /* sigh, one last attempt above and beyond call of duty ...;
5095 * search for cluster mark following current pos */
5096 pos = demux->common.offset;
5097 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
5098 if ((ret = gst_matroska_demux_search_cluster (demux, &pos, TRUE)) !=
5100 /* did not work, give up */
5103 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
5104 /* try that position */
5105 demux->common.offset = pos;
5111 static inline GstFlowReturn
5112 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
5114 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
5115 demux->common.offset += flush;
5116 if (demux->streaming) {
5119 /* hard to skip large blocks when streaming */
5120 ret = gst_matroska_demux_check_read_size (demux, flush);
5121 if (ret != GST_FLOW_OK)
5123 if (flush <= gst_adapter_available (demux->common.adapter))
5124 gst_adapter_flush (demux->common.adapter, flush);
5126 return GST_FLOW_EOS;
5131 /* initializes @ebml with @bytes from input stream at current offset.
5132 * Returns EOS if insufficient available,
5133 * ERROR if too much was attempted to read. */
5134 static inline GstFlowReturn
5135 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
5138 GstBuffer *buffer = NULL;
5139 GstFlowReturn ret = GST_FLOW_OK;
5141 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
5143 ret = gst_matroska_demux_check_read_size (demux, bytes);
5144 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
5145 if (!demux->streaming) {
5146 /* in pull mode, we can skip */
5147 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
5148 ret = GST_FLOW_OVERFLOW;
5150 /* otherwise fatal */
5151 ret = GST_FLOW_ERROR;
5155 if (demux->streaming) {
5156 if (gst_adapter_available (demux->common.adapter) >= bytes)
5157 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
5161 ret = gst_matroska_read_common_peek_bytes (&demux->common,
5162 demux->common.offset, bytes, &buffer, NULL);
5163 if (G_LIKELY (buffer)) {
5164 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
5165 demux->common.offset);
5166 demux->common.offset += bytes;
5173 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
5176 gboolean seekable = FALSE;
5177 gint64 start = -1, stop = -1;
5179 query = gst_query_new_seeking (GST_FORMAT_BYTES);
5180 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
5181 GST_DEBUG_OBJECT (demux, "seeking query failed");
5185 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
5187 /* try harder to query upstream size if we didn't get it the first time */
5188 if (seekable && stop == -1) {
5189 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
5190 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
5194 /* if upstream doesn't know the size, it's likely that it's not seekable in
5195 * practice even if it technically may be seekable */
5196 if (seekable && (start != 0 || stop <= start)) {
5197 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
5202 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
5203 G_GUINT64_FORMAT ")", seekable, start, stop);
5204 demux->seekable = seekable;
5206 gst_query_unref (query);
5209 static GstFlowReturn
5210 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
5216 GstFlowReturn ret = GST_FLOW_OK;
5218 GST_WARNING_OBJECT (demux,
5219 "Found Cluster element before Tracks, searching Tracks");
5222 before_pos = demux->common.offset;
5224 /* Search Tracks element */
5226 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
5227 GST_ELEMENT_CAST (demux), &id, &length, &needed);
5228 if (ret != GST_FLOW_OK)
5231 if (id != GST_MATROSKA_ID_TRACKS) {
5232 /* we may be skipping large cluster here, so forego size check etc */
5233 /* ... but we can't skip undefined size; force error */
5234 if (length == G_MAXUINT64) {
5235 ret = gst_matroska_demux_check_read_size (demux, length);
5238 demux->common.offset += needed;
5239 demux->common.offset += length;
5244 /* will lead to track parsing ... */
5245 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5250 demux->common.offset = before_pos;
5255 #define GST_READ_CHECK(stmt) \
5257 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
5258 if (ret == GST_FLOW_OVERFLOW) { \
5259 ret = GST_FLOW_OK; \
5265 static GstFlowReturn
5266 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
5267 guint64 length, guint needed)
5269 GstEbmlRead ebml = { 0, };
5270 GstFlowReturn ret = GST_FLOW_OK;
5273 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
5274 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
5276 /* if we plan to read and parse this element, we need prefix (id + length)
5277 * and the contents */
5278 /* mind about overflow wrap-around when dealing with undefined size */
5280 if (G_LIKELY (length != G_MAXUINT64))
5283 switch (demux->common.state) {
5284 case GST_MATROSKA_READ_STATE_START:
5286 case GST_EBML_ID_HEADER:
5287 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5288 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
5289 if (ret != GST_FLOW_OK)
5291 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
5292 gst_matroska_demux_check_seekability (demux);
5295 goto invalid_header;
5299 case GST_MATROSKA_READ_STATE_SEGMENT:
5301 case GST_MATROSKA_ID_SEGMENT:
5302 /* eat segment prefix */
5303 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
5304 GST_DEBUG_OBJECT (demux,
5305 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
5306 G_GUINT64_FORMAT, demux->common.offset, length);
5307 /* seeks are from the beginning of the segment,
5308 * after the segment ID/length */
5309 demux->common.ebml_segment_start = demux->common.offset;
5311 length = G_MAXUINT64;
5312 demux->common.ebml_segment_length = length;
5313 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
5316 GST_WARNING_OBJECT (demux,
5317 "Expected a Segment ID (0x%x), but received 0x%x!",
5318 GST_MATROSKA_ID_SEGMENT, id);
5319 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5323 case GST_MATROSKA_READ_STATE_SCANNING:
5324 if (id != GST_MATROSKA_ID_CLUSTER &&
5325 id != GST_MATROSKA_ID_PREVSIZE &&
5326 id != GST_MATROSKA_ID_CLUSTERTIMECODE) {
5327 if (demux->common.start_resync_offset != -1) {
5328 /* we need to skip byte per byte if we are scanning for a new cluster
5329 * after invalid data is found
5335 if (demux->common.start_resync_offset != -1) {
5336 GST_LOG_OBJECT (demux, "Resync done, new cluster found!");
5337 demux->common.start_resync_offset = -1;
5338 demux->common.state = demux->common.state_to_restore;
5342 case GST_MATROSKA_READ_STATE_HEADER:
5343 case GST_MATROSKA_READ_STATE_DATA:
5344 case GST_MATROSKA_READ_STATE_SEEK:
5346 case GST_EBML_ID_HEADER:
5347 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5348 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
5349 gst_matroska_demux_check_seekability (demux);
5351 case GST_MATROSKA_ID_SEGMENTINFO:
5352 if (!demux->common.segmentinfo_parsed) {
5353 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5354 ret = gst_matroska_read_common_parse_info (&demux->common,
5355 GST_ELEMENT_CAST (demux), &ebml);
5356 if (ret == GST_FLOW_OK)
5357 gst_matroska_demux_send_tags (demux);
5359 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5362 case GST_MATROSKA_ID_TRACKS:
5363 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5364 if (!demux->tracks_parsed) {
5365 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
5367 ret = gst_matroska_demux_update_tracks (demux, &ebml);
5370 case GST_MATROSKA_ID_CLUSTER:
5371 if (G_UNLIKELY (!demux->tracks_parsed)) {
5372 if (demux->streaming) {
5373 GST_DEBUG_OBJECT (demux, "Cluster before Track");
5374 goto not_streamable;
5376 ret = gst_matroska_demux_find_tracks (demux);
5377 if (!demux->tracks_parsed)
5381 if (demux->common.state == GST_MATROSKA_READ_STATE_HEADER) {
5382 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
5383 demux->first_cluster_offset = demux->common.offset;
5385 if (!demux->streaming &&
5386 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.duration)) {
5387 GstMatroskaIndex *last = NULL;
5389 GST_DEBUG_OBJECT (demux,
5390 "estimating duration using last cluster");
5391 if ((last = gst_matroska_demux_search_pos (demux,
5392 GST_CLOCK_TIME_NONE)) != NULL) {
5393 demux->last_cluster_offset =
5394 last->pos + demux->common.ebml_segment_start;
5395 demux->stream_last_time = last->time;
5396 demux->common.segment.duration =
5397 demux->stream_last_time - demux->stream_start_time;
5398 /* above estimate should not be taken all too strongly */
5399 demux->invalid_duration = TRUE;
5400 GST_DEBUG_OBJECT (demux,
5401 "estimated duration as %" GST_TIME_FORMAT,
5402 GST_TIME_ARGS (demux->common.segment.duration));
5408 /* Peek at second cluster in order to figure out if we have cluster
5409 * prev_size or not (which is never set on the first cluster for
5410 * obvious reasons). This is useful in case someone initiates a
5411 * seek or direction change before we reach the second cluster. */
5412 if (!demux->streaming) {
5413 ClusterInfo cluster = { 0, };
5415 if (gst_matroska_demux_peek_cluster_info (demux, &cluster,
5416 demux->first_cluster_offset) && cluster.size > 0) {
5417 gst_matroska_demux_peek_cluster_info (demux, &cluster,
5418 demux->first_cluster_offset + cluster.size);
5420 demux->common.offset = demux->first_cluster_offset;
5423 if (demux->deferred_seek_event) {
5424 GstEvent *seek_event;
5426 seek_event = demux->deferred_seek_event;
5427 seek_pad = demux->deferred_seek_pad;
5428 demux->deferred_seek_event = NULL;
5429 demux->deferred_seek_pad = NULL;
5430 GST_DEBUG_OBJECT (demux,
5431 "Handling deferred seek event: %" GST_PTR_FORMAT, seek_event);
5432 gst_matroska_demux_handle_seek_event (demux, seek_pad,
5434 gst_event_unref (seek_event);
5437 /* send initial segment - we wait till we know the first
5438 incoming timestamp, so we can properly set the start of
5440 demux->need_segment = TRUE;
5442 demux->cluster_time = GST_CLOCK_TIME_NONE;
5443 demux->cluster_offset = demux->common.offset;
5444 demux->cluster_prevsize = 0;
5445 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
5446 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
5447 " not found in Cluster, trying next Cluster's first block instead",
5449 demux->seek_block = 0;
5451 demux->seek_first = FALSE;
5452 /* record next cluster for recovery */
5453 if (read != G_MAXUINT64)
5454 demux->next_cluster_offset = demux->cluster_offset + read;
5455 /* eat cluster prefix */
5456 gst_matroska_demux_flush (demux, needed);
5458 case GST_MATROSKA_ID_CLUSTERTIMECODE:
5462 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5463 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
5465 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
5466 demux->cluster_time = num;
5467 /* track last cluster */
5468 if (demux->cluster_offset > demux->last_cluster_offset) {
5469 demux->last_cluster_offset = demux->cluster_offset;
5470 demux->stream_last_time =
5471 demux->cluster_time * demux->common.time_scale;
5474 if (demux->common.element_index) {
5475 if (demux->common.element_index_writer_id == -1)
5476 gst_index_get_writer_id (demux->common.element_index,
5477 GST_OBJECT (demux), &demux->common.element_index_writer_id);
5478 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
5479 G_GUINT64_FORMAT " for writer id %d",
5480 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
5481 demux->common.element_index_writer_id);
5482 gst_index_add_association (demux->common.element_index,
5483 demux->common.element_index_writer_id,
5484 GST_ASSOCIATION_FLAG_KEY_UNIT,
5485 GST_FORMAT_TIME, demux->cluster_time,
5486 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
5491 case GST_MATROSKA_ID_BLOCKGROUP:
5492 if (!gst_matroska_demux_seek_block (demux))
5494 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5495 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
5496 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
5497 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
5498 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
5500 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
5502 case GST_MATROSKA_ID_SIMPLEBLOCK:
5503 if (!gst_matroska_demux_seek_block (demux))
5505 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5506 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
5507 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
5508 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
5509 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
5511 case GST_MATROSKA_ID_ATTACHMENTS:
5512 if (!demux->common.attachments_parsed) {
5513 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5514 ret = gst_matroska_read_common_parse_attachments (&demux->common,
5515 GST_ELEMENT_CAST (demux), &ebml);
5516 if (ret == GST_FLOW_OK)
5517 gst_matroska_demux_send_tags (demux);
5519 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5522 case GST_MATROSKA_ID_TAGS:
5523 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5524 ret = gst_matroska_read_common_parse_metadata (&demux->common,
5525 GST_ELEMENT_CAST (demux), &ebml);
5526 if (ret == GST_FLOW_OK)
5527 gst_matroska_demux_send_tags (demux);
5529 case GST_MATROSKA_ID_CHAPTERS:
5530 if (!demux->common.chapters_parsed) {
5531 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5533 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
5535 if (demux->common.toc) {
5536 gst_matroska_demux_send_event (demux,
5537 gst_event_new_toc (demux->common.toc, FALSE));
5540 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5542 case GST_MATROSKA_ID_SEEKHEAD:
5543 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5544 ret = gst_matroska_demux_parse_contents (demux, &ebml);
5546 case GST_MATROSKA_ID_CUES:
5547 if (demux->common.index_parsed) {
5548 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5551 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5552 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
5553 /* only push based; delayed index building */
5554 if (ret == GST_FLOW_OK
5555 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
5558 GST_OBJECT_LOCK (demux);
5559 event = demux->seek_event;
5560 demux->seek_event = NULL;
5561 GST_OBJECT_UNLOCK (demux);
5564 /* unlikely to fail, since we managed to seek to this point */
5565 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
5566 gst_event_unref (event);
5569 gst_event_unref (event);
5570 /* resume data handling, main thread clear to seek again */
5571 GST_OBJECT_LOCK (demux);
5572 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
5573 GST_OBJECT_UNLOCK (demux);
5576 case GST_MATROSKA_ID_PREVSIZE:{
5579 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5580 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
5582 GST_LOG_OBJECT (demux, "ClusterPrevSize: %" G_GUINT64_FORMAT, num);
5583 demux->cluster_prevsize = num;
5584 demux->seen_cluster_prevsize = TRUE;
5587 case GST_MATROSKA_ID_POSITION:
5588 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
5589 /* The WebM doesn't support the EncryptedBlock element.
5590 * The Matroska spec doesn't give us more detail, how to parse this element,
5591 * for example the field TransformID isn't specified yet.*/
5592 case GST_MATROSKA_ID_SILENTTRACKS:
5593 GST_DEBUG_OBJECT (demux,
5594 "Skipping Cluster subelement 0x%x - ignoring", id);
5598 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
5599 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5605 if (ret == GST_FLOW_PARSE)
5609 gst_ebml_read_clear (&ebml);
5615 /* simply exit, maybe not enough data yet */
5616 /* no ebml to clear if read error */
5621 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5622 ("Failed to parse Element 0x%x", id));
5623 ret = GST_FLOW_ERROR;
5628 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5629 ("File layout does not permit streaming"));
5630 ret = GST_FLOW_ERROR;
5635 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5636 ("No Tracks element found"));
5637 ret = GST_FLOW_ERROR;
5642 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
5643 ret = GST_FLOW_ERROR;
5648 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
5649 ret = GST_FLOW_ERROR;
5655 gst_matroska_demux_loop (GstPad * pad)
5657 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
5663 /* If we have to close a segment, send a new segment to do this now */
5664 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
5665 if (G_UNLIKELY (demux->new_segment)) {
5666 gst_matroska_demux_send_event (demux, demux->new_segment);
5667 demux->new_segment = NULL;
5671 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
5672 GST_ELEMENT_CAST (demux), &id, &length, &needed);
5673 if (ret == GST_FLOW_EOS) {
5675 } else if (ret == GST_FLOW_FLUSHING) {
5677 } else if (ret != GST_FLOW_OK) {
5678 ret = gst_matroska_demux_check_parse_error (demux);
5680 /* Only handle EOS as no error if we're outside the segment already */
5681 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
5682 && demux->common.offset >=
5683 demux->common.ebml_segment_start +
5684 demux->common.ebml_segment_length))
5686 else if (ret != GST_FLOW_OK)
5692 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
5693 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
5696 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5697 if (ret == GST_FLOW_EOS)
5699 if (ret != GST_FLOW_OK)
5702 /* check if we're at the end of a configured segment */
5703 if (G_LIKELY (demux->common.src->len)) {
5706 g_assert (demux->common.num_streams == demux->common.src->len);
5707 for (i = 0; i < demux->common.src->len; i++) {
5708 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
5710 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
5711 GST_TIME_ARGS (context->pos));
5712 if (context->eos == FALSE)
5716 GST_INFO_OBJECT (demux, "All streams are EOS");
5722 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
5723 demux->common.offset >= demux->cached_length)) {
5724 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
5725 if (demux->common.offset == demux->cached_length) {
5726 GST_LOG_OBJECT (demux, "Reached end of stream");
5737 if (demux->common.segment.rate < 0.0) {
5738 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
5739 if (ret == GST_FLOW_OK)
5746 const gchar *reason = gst_flow_get_name (ret);
5747 gboolean push_eos = FALSE;
5749 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
5750 gst_pad_pause_task (demux->common.sinkpad);
5752 if (ret == GST_FLOW_EOS) {
5753 /* perform EOS logic */
5755 /* If we were in the headers, make sure we send no-more-pads.
5756 This will ensure decodebin does not get stuck thinking
5757 the chain is not complete yet, and waiting indefinitely. */
5758 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
5759 if (demux->common.src->len == 0) {
5760 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
5761 ("No pads created"));
5763 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
5764 ("Failed to finish reading headers"));
5766 gst_element_no_more_pads (GST_ELEMENT (demux));
5769 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
5774 /* for segment playback we need to post when (in stream time)
5775 * we stopped, this is either stop (when set) or the duration. */
5776 if ((stop = demux->common.segment.stop) == -1)
5777 stop = demux->last_stop_end;
5779 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
5780 msg = gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
5782 if (demux->segment_seqnum)
5783 gst_message_set_seqnum (msg, demux->segment_seqnum);
5784 gst_element_post_message (GST_ELEMENT (demux), msg);
5786 event = gst_event_new_segment_done (GST_FORMAT_TIME, stop);
5787 if (demux->segment_seqnum)
5788 gst_event_set_seqnum (event, demux->segment_seqnum);
5789 gst_matroska_demux_send_event (demux, event);
5793 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
5794 /* for fatal errors we post an error message */
5795 GST_ELEMENT_FLOW_ERROR (demux, ret);
5801 /* send EOS, and prevent hanging if no streams yet */
5802 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
5803 event = gst_event_new_eos ();
5804 if (demux->segment_seqnum)
5805 gst_event_set_seqnum (event, demux->segment_seqnum);
5806 if (!gst_matroska_demux_send_event (demux, event) &&
5807 (ret == GST_FLOW_EOS)) {
5808 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5809 (NULL), ("got eos but no streams (yet)"));
5817 * Create and push a flushing seek event upstream
5820 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
5821 guint32 seqnum, GstSeekFlags flags)
5826 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
5829 gst_event_new_seek (rate, GST_FORMAT_BYTES,
5830 flags | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
5831 GST_SEEK_TYPE_SET, offset, GST_SEEK_TYPE_NONE, -1);
5832 gst_event_set_seqnum (event, seqnum);
5834 res = gst_pad_push_event (demux->common.sinkpad, event);
5836 /* segment event will update offset */
5840 static GstFlowReturn
5841 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
5843 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5845 GstFlowReturn ret = GST_FLOW_OK;
5850 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
5851 GST_DEBUG_OBJECT (demux, "got DISCONT");
5852 gst_adapter_clear (demux->common.adapter);
5853 GST_OBJECT_LOCK (demux);
5854 gst_matroska_read_common_reset_streams (&demux->common,
5855 GST_CLOCK_TIME_NONE, FALSE);
5856 GST_OBJECT_UNLOCK (demux);
5859 gst_adapter_push (demux->common.adapter, buffer);
5863 available = gst_adapter_available (demux->common.adapter);
5865 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
5866 GST_ELEMENT_CAST (demux), &id, &length, &needed);
5867 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
5868 if (demux->common.ebml_segment_length != G_MAXUINT64
5869 && demux->common.offset >=
5870 demux->common.ebml_segment_start + demux->common.ebml_segment_length) {
5873 gint64 bytes_scanned;
5874 if (demux->common.start_resync_offset == -1) {
5875 demux->common.start_resync_offset = demux->common.offset;
5876 demux->common.state_to_restore = demux->common.state;
5878 bytes_scanned = demux->common.offset - demux->common.start_resync_offset;
5879 if (bytes_scanned <= INVALID_DATA_THRESHOLD) {
5880 GST_WARNING_OBJECT (demux,
5881 "parse error, looking for next cluster, actual offset %"
5882 G_GUINT64_FORMAT ", start resync offset %" G_GUINT64_FORMAT,
5883 demux->common.offset, demux->common.start_resync_offset);
5884 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
5887 GST_WARNING_OBJECT (demux,
5888 "unrecoverable parse error, next cluster not found and threshold "
5889 "exceeded, bytes scanned %" G_GINT64_FORMAT, bytes_scanned);
5895 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
5896 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
5897 demux->common.offset, id, length, needed, available);
5899 if (needed > available)
5902 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5903 if (ret == GST_FLOW_EOS) {
5904 /* need more data */
5906 } else if (ret != GST_FLOW_OK) {
5913 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
5916 gboolean res = TRUE;
5917 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5919 GST_DEBUG_OBJECT (demux,
5920 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
5922 switch (GST_EVENT_TYPE (event)) {
5923 case GST_EVENT_SEGMENT:
5925 const GstSegment *segment;
5927 /* some debug output */
5928 gst_event_parse_segment (event, &segment);
5929 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
5930 GST_DEBUG_OBJECT (demux,
5931 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
5934 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
5935 GST_DEBUG_OBJECT (demux, "still starting");
5939 /* we only expect a BYTE segment, e.g. following a seek */
5940 if (segment->format != GST_FORMAT_BYTES) {
5941 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
5945 GST_DEBUG_OBJECT (demux, "clearing segment state");
5946 GST_OBJECT_LOCK (demux);
5947 /* clear current segment leftover */
5948 gst_adapter_clear (demux->common.adapter);
5949 /* and some streaming setup */
5950 demux->common.offset = segment->start;
5951 /* accumulate base based on current position */
5952 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
5953 demux->common.segment.base +=
5954 (MAX (demux->common.segment.position, demux->stream_start_time)
5955 - demux->stream_start_time) / fabs (demux->common.segment.rate);
5956 /* do not know where we are;
5957 * need to come across a cluster and generate segment */
5958 demux->common.segment.position = GST_CLOCK_TIME_NONE;
5959 demux->cluster_time = GST_CLOCK_TIME_NONE;
5960 demux->cluster_offset = 0;
5961 demux->cluster_prevsize = 0;
5962 demux->need_segment = TRUE;
5963 demux->segment_seqnum = gst_event_get_seqnum (event);
5964 /* but keep some of the upstream segment */
5965 demux->common.segment.rate = segment->rate;
5966 demux->common.segment.flags = segment->flags;
5967 /* also check if need to keep some of the requested seek position */
5968 if (demux->seek_offset == segment->start) {
5969 GST_DEBUG_OBJECT (demux, "position matches requested seek");
5970 demux->common.segment.position = demux->requested_seek_time;
5972 GST_DEBUG_OBJECT (demux, "unexpected segment position");
5974 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
5975 demux->seek_offset = -1;
5976 GST_OBJECT_UNLOCK (demux);
5978 /* chain will send initial segment after pads have been added,
5979 * or otherwise come up with one */
5980 GST_DEBUG_OBJECT (demux, "eating event");
5981 gst_event_unref (event);
5987 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA
5988 && demux->common.state != GST_MATROSKA_READ_STATE_SCANNING) {
5989 gst_event_unref (event);
5990 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5991 (NULL), ("got eos and didn't receive a complete header object"));
5992 } else if (demux->common.num_streams == 0) {
5993 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5994 (NULL), ("got eos but no streams (yet)"));
5996 gst_matroska_demux_send_event (demux, event);
6000 case GST_EVENT_FLUSH_STOP:
6004 gst_adapter_clear (demux->common.adapter);
6005 GST_OBJECT_LOCK (demux);
6006 gst_matroska_read_common_reset_streams (&demux->common,
6007 GST_CLOCK_TIME_NONE, TRUE);
6008 gst_flow_combiner_reset (demux->flowcombiner);
6009 dur = demux->common.segment.duration;
6010 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
6011 demux->common.segment.duration = dur;
6012 demux->cluster_time = GST_CLOCK_TIME_NONE;
6013 demux->cluster_offset = 0;
6014 demux->cluster_prevsize = 0;
6015 GST_OBJECT_UNLOCK (demux);
6019 res = gst_pad_event_default (pad, parent, event);
6027 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
6029 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
6031 gboolean pull_mode = FALSE;
6033 query = gst_query_new_scheduling ();
6035 if (gst_pad_peer_query (sinkpad, query))
6036 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
6037 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
6039 gst_query_unref (query);
6042 GST_DEBUG ("going to pull mode");
6043 demux->streaming = FALSE;
6044 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
6046 GST_DEBUG ("going to push (streaming) mode");
6047 demux->streaming = TRUE;
6048 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
6053 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
6054 GstPadMode mode, gboolean active)
6057 case GST_PAD_MODE_PULL:
6059 /* if we have a scheduler we can start the task */
6060 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
6063 gst_pad_stop_task (sinkpad);
6066 case GST_PAD_MODE_PUSH:
6074 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
6075 videocontext, const gchar * codec_id, guint8 * data, guint size,
6076 gchar ** codec_name, guint32 * riff_fourcc)
6078 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
6079 GstCaps *caps = NULL;
6081 g_assert (videocontext != NULL);
6082 g_assert (codec_name != NULL);
6087 /* TODO: check if we have all codec types from matroska-ids.h
6088 * check if we have to do more special things with codec_private
6091 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
6092 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
6095 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
6096 gst_riff_strf_vids *vids = NULL;
6099 GstBuffer *buf = NULL;
6101 vids = (gst_riff_strf_vids *) data;
6103 /* assure size is big enough */
6105 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
6108 if (size < sizeof (gst_riff_strf_vids)) {
6109 vids = g_new (gst_riff_strf_vids, 1);
6110 memcpy (vids, data, size);
6113 context->dts_only = TRUE; /* VFW files only store DTS */
6115 /* little-endian -> byte-order */
6116 vids->size = GUINT32_FROM_LE (vids->size);
6117 vids->width = GUINT32_FROM_LE (vids->width);
6118 vids->height = GUINT32_FROM_LE (vids->height);
6119 vids->planes = GUINT16_FROM_LE (vids->planes);
6120 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
6121 vids->compression = GUINT32_FROM_LE (vids->compression);
6122 vids->image_size = GUINT32_FROM_LE (vids->image_size);
6123 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
6124 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
6125 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
6126 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
6128 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
6129 gsize offset = sizeof (gst_riff_strf_vids);
6132 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
6133 size - offset), size - offset);
6137 *riff_fourcc = vids->compression;
6139 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
6140 buf, NULL, codec_name);
6143 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
6144 GST_FOURCC_ARGS (vids->compression));
6146 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
6147 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
6148 "video/x-compressed-yuv");
6149 context->intra_only =
6150 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
6154 gst_buffer_unref (buf);
6156 if (vids != (gst_riff_strf_vids *) data)
6159 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
6161 GstVideoFormat format;
6163 gst_video_info_init (&info);
6164 switch (videocontext->fourcc) {
6165 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
6166 format = GST_VIDEO_FORMAT_I420;
6168 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
6169 format = GST_VIDEO_FORMAT_YUY2;
6171 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
6172 format = GST_VIDEO_FORMAT_YV12;
6174 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
6175 format = GST_VIDEO_FORMAT_UYVY;
6177 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
6178 format = GST_VIDEO_FORMAT_AYUV;
6180 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
6181 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
6182 format = GST_VIDEO_FORMAT_GRAY8;
6184 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
6185 format = GST_VIDEO_FORMAT_RGB;
6187 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
6188 format = GST_VIDEO_FORMAT_BGR;
6191 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
6192 GST_FOURCC_ARGS (videocontext->fourcc));
6196 context->intra_only = TRUE;
6198 gst_video_info_set_format (&info, format, videocontext->pixel_width,
6199 videocontext->pixel_height);
6200 caps = gst_video_info_to_caps (&info);
6201 *codec_name = gst_pb_utils_get_codec_description (caps);
6202 context->alignment = 32;
6203 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
6204 caps = gst_caps_new_simple ("video/x-divx",
6205 "divxversion", G_TYPE_INT, 4, NULL);
6206 *codec_name = g_strdup ("MPEG-4 simple profile");
6207 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
6208 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
6209 caps = gst_caps_new_simple ("video/mpeg",
6210 "mpegversion", G_TYPE_INT, 4,
6211 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
6215 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
6216 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6217 gst_buffer_unref (priv);
6219 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
6221 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
6222 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
6224 *codec_name = g_strdup ("MPEG-4 advanced profile");
6225 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
6227 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
6228 "divxversion", G_TYPE_INT, 3, NULL),
6229 gst_structure_new ("video/x-msmpeg",
6230 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
6232 caps = gst_caps_new_simple ("video/x-msmpeg",
6233 "msmpegversion", G_TYPE_INT, 43, NULL);
6234 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
6235 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
6236 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
6239 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
6244 caps = gst_caps_new_simple ("video/mpeg",
6245 "systemstream", G_TYPE_BOOLEAN, FALSE,
6246 "mpegversion", G_TYPE_INT, mpegversion, NULL);
6247 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
6248 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
6249 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
6250 caps = gst_caps_new_empty_simple ("image/jpeg");
6251 *codec_name = g_strdup ("Motion-JPEG");
6252 context->intra_only = TRUE;
6253 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
6254 caps = gst_caps_new_empty_simple ("video/x-h264");
6258 /* First byte is the version, second is the profile indication, and third
6259 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
6260 * level indication. */
6261 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
6264 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
6265 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6266 gst_buffer_unref (priv);
6268 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
6269 "alignment", G_TYPE_STRING, "au", NULL);
6271 GST_WARNING ("No codec data found, assuming output is byte-stream");
6272 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
6275 *codec_name = g_strdup ("H264");
6276 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
6277 caps = gst_caps_new_empty_simple ("video/x-h265");
6281 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
6284 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
6285 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6286 gst_buffer_unref (priv);
6288 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
6289 "alignment", G_TYPE_STRING, "au", NULL);
6291 GST_WARNING ("No codec data found, assuming output is byte-stream");
6292 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
6295 *codec_name = g_strdup ("HEVC");
6296 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
6297 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
6298 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
6299 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
6300 gint rmversion = -1;
6302 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
6304 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
6306 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
6308 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
6311 caps = gst_caps_new_simple ("video/x-pn-realvideo",
6312 "rmversion", G_TYPE_INT, rmversion, NULL);
6313 GST_DEBUG ("data:%p, size:0x%x", data, size);
6314 /* We need to extract the extradata ! */
6315 if (data && (size >= 0x22)) {
6320 subformat = GST_READ_UINT32_BE (data + 0x1a);
6321 rformat = GST_READ_UINT32_BE (data + 0x1e);
6324 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
6326 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
6327 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
6328 gst_buffer_unref (priv);
6331 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
6332 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
6333 caps = gst_caps_new_empty_simple ("video/x-theora");
6334 context->stream_headers =
6335 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6336 context->codec_priv_size);
6337 /* FIXME: mark stream as broken and skip if there are no stream headers */
6338 context->send_stream_headers = TRUE;
6339 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
6340 caps = gst_caps_new_empty_simple ("video/x-dirac");
6341 *codec_name = g_strdup_printf ("Dirac");
6342 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
6343 caps = gst_caps_new_empty_simple ("video/x-vp8");
6344 *codec_name = g_strdup_printf ("On2 VP8");
6345 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
6346 caps = gst_caps_new_empty_simple ("video/x-vp9");
6347 *codec_name = g_strdup_printf ("On2 VP9");
6348 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_AV1)) {
6349 caps = gst_caps_new_empty_simple ("video/x-av1");
6353 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
6354 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6355 gst_buffer_unref (priv);
6357 GST_WARNING ("No AV1 codec data found!");
6359 *codec_name = g_strdup_printf ("AOM AV1");
6360 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
6362 const gchar *variant, *variant_descr = "";
6364 /* Expect a fourcc in the codec private data */
6365 if (!data || size < 4) {
6366 GST_WARNING ("No or too small PRORESS fourcc (%d bytes)", size);
6370 fourcc = GST_STR_FOURCC (data);
6372 case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
6373 variant_descr = " 4:2:2 LT";
6376 case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
6378 variant_descr = " 4:2:2 HQ";
6380 case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
6382 variant_descr = " 4:4:4:4";
6384 case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
6386 variant_descr = " 4:2:2 Proxy";
6388 case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
6390 variant = "standard";
6391 variant_descr = " 4:2:2 SD";
6395 GST_LOG ("Prores video, codec fourcc %" GST_FOURCC_FORMAT,
6396 GST_FOURCC_ARGS (fourcc));
6398 caps = gst_caps_new_simple ("video/x-prores",
6399 "format", G_TYPE_STRING, variant, NULL);
6400 *codec_name = g_strdup_printf ("Apple ProRes%s", variant_descr);
6401 context->postprocess_frame = gst_matroska_demux_add_prores_header;
6403 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6409 GstStructure *structure;
6411 for (i = 0; i < gst_caps_get_size (caps); i++) {
6412 structure = gst_caps_get_structure (caps, i);
6414 /* FIXME: use the real unit here! */
6415 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
6416 videocontext->pixel_width,
6417 videocontext->pixel_height,
6418 videocontext->display_width, videocontext->display_height);
6420 /* pixel width and height are the w and h of the video in pixels */
6421 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
6422 gint w = videocontext->pixel_width;
6423 gint h = videocontext->pixel_height;
6425 gst_structure_set (structure,
6426 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
6429 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
6432 if (videocontext->display_width <= 0)
6433 videocontext->display_width = videocontext->pixel_width;
6434 if (videocontext->display_height <= 0)
6435 videocontext->display_height = videocontext->pixel_height;
6437 /* calculate the pixel aspect ratio using the display and pixel w/h */
6438 n = videocontext->display_width * videocontext->pixel_height;
6439 d = videocontext->display_height * videocontext->pixel_width;
6440 GST_DEBUG ("setting PAR to %d/%d", n, d);
6441 gst_structure_set (structure, "pixel-aspect-ratio",
6443 videocontext->display_width * videocontext->pixel_height,
6444 videocontext->display_height * videocontext->pixel_width, NULL);
6447 if (videocontext->default_fps > 0.0) {
6450 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
6452 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
6454 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
6456 } else if (context->default_duration > 0) {
6459 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
6461 GST_INFO ("using default duration %" G_GUINT64_FORMAT
6462 " framerate %d/%d", context->default_duration, fps_n, fps_d);
6464 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
6465 fps_n, fps_d, NULL);
6467 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
6471 switch (videocontext->interlace_mode) {
6472 case GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE:
6473 gst_structure_set (structure,
6474 "interlace-mode", G_TYPE_STRING, "progressive", NULL);
6476 case GST_MATROSKA_INTERLACE_MODE_INTERLACED:
6477 gst_structure_set (structure,
6478 "interlace-mode", G_TYPE_STRING, "interleaved", NULL);
6480 if (videocontext->field_order != GST_VIDEO_FIELD_ORDER_UNKNOWN)
6481 gst_structure_set (structure, "field-order", G_TYPE_STRING,
6482 gst_video_field_order_to_string (videocontext->field_order),
6489 if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
6490 if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
6491 videocontext->pixel_width, videocontext->pixel_height,
6492 videocontext->display_width * videocontext->pixel_height,
6493 videocontext->display_height * videocontext->pixel_width)) {
6494 videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
6496 gst_caps_set_simple (caps,
6497 "multiview-mode", G_TYPE_STRING,
6498 gst_video_multiview_mode_to_caps_string
6499 (videocontext->multiview_mode), "multiview-flags",
6500 GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
6501 GST_FLAG_SET_MASK_EXACT, NULL);
6504 if (videocontext->colorimetry.range != GST_VIDEO_COLOR_RANGE_UNKNOWN ||
6505 videocontext->colorimetry.matrix != GST_VIDEO_COLOR_MATRIX_UNKNOWN ||
6506 videocontext->colorimetry.transfer != GST_VIDEO_TRANSFER_UNKNOWN ||
6507 videocontext->colorimetry.primaries !=
6508 GST_VIDEO_COLOR_PRIMARIES_UNKNOWN) {
6509 gchar *colorimetry =
6510 gst_video_colorimetry_to_string (&videocontext->colorimetry);
6511 gst_caps_set_simple (caps, "colorimetry", G_TYPE_STRING, colorimetry,
6513 GST_DEBUG ("setting colorimetry to %s", colorimetry);
6514 g_free (colorimetry);
6517 if (videocontext->mastering_display_info_present) {
6518 if (!gst_video_mastering_display_info_add_to_caps
6519 (&videocontext->mastering_display_info, caps)) {
6520 GST_WARNING ("couldn't set mastering display info to caps");
6524 if (videocontext->content_light_level.maxCLL_n &&
6525 videocontext->content_light_level.maxFALL_n) {
6526 if (!gst_video_content_light_level_add_to_caps
6527 (&videocontext->content_light_level, caps)) {
6528 GST_WARNING ("couldn't set content light level to caps");
6532 caps = gst_caps_simplify (caps);
6539 * Some AAC specific code... *sigh*
6540 * FIXME: maybe we should use '15' and code the sample rate explicitly
6541 * if the sample rate doesn't match the predefined rates exactly? (tpm)
6545 aac_rate_idx (gint rate)
6549 else if (75132 <= rate)
6551 else if (55426 <= rate)
6553 else if (46009 <= rate)
6555 else if (37566 <= rate)
6557 else if (27713 <= rate)
6559 else if (23004 <= rate)
6561 else if (18783 <= rate)
6563 else if (13856 <= rate)
6565 else if (11502 <= rate)
6567 else if (9391 <= rate)
6574 aac_profile_idx (const gchar * codec_id)
6578 if (strlen (codec_id) <= 12)
6580 else if (!strncmp (&codec_id[12], "MAIN", 4))
6582 else if (!strncmp (&codec_id[12], "LC", 2))
6584 else if (!strncmp (&codec_id[12], "SSR", 3))
6593 round_up_pow2 (guint n)
6604 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
6607 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
6608 audiocontext, const gchar * codec_id, guint8 * data, guint size,
6609 gchar ** codec_name, guint16 * riff_audio_fmt)
6611 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
6612 GstCaps *caps = NULL;
6614 g_assert (audiocontext != NULL);
6615 g_assert (codec_name != NULL);
6618 *riff_audio_fmt = 0;
6620 /* TODO: check if we have all codec types from matroska-ids.h
6621 * check if we have to do more special things with codec_private
6622 * check if we need bitdepth in different places too
6623 * implement channel position magic
6625 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
6626 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
6627 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
6628 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
6631 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
6632 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
6633 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
6636 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
6638 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
6643 caps = gst_caps_new_simple ("audio/mpeg",
6644 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
6645 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
6646 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
6647 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
6650 GstAudioFormat format;
6652 sign = (audiocontext->bitdepth != 8);
6653 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
6654 endianness = G_BIG_ENDIAN;
6656 endianness = G_LITTLE_ENDIAN;
6658 format = gst_audio_format_build_integer (sign, endianness,
6659 audiocontext->bitdepth, audiocontext->bitdepth);
6661 /* FIXME: Channel mask and reordering */
6662 caps = gst_caps_new_simple ("audio/x-raw",
6663 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
6664 "layout", G_TYPE_STRING, "interleaved",
6665 "channel-mask", GST_TYPE_BITMASK,
6666 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
6668 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
6669 audiocontext->bitdepth);
6670 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
6671 context->alignment = round_up_pow2 (context->alignment);
6672 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
6673 const gchar *format;
6674 if (audiocontext->bitdepth == 32)
6678 /* FIXME: Channel mask and reordering */
6679 caps = gst_caps_new_simple ("audio/x-raw",
6680 "format", G_TYPE_STRING, format,
6681 "layout", G_TYPE_STRING, "interleaved",
6682 "channel-mask", GST_TYPE_BITMASK,
6683 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
6684 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
6685 audiocontext->bitdepth);
6686 context->alignment = audiocontext->bitdepth / 8;
6687 context->alignment = round_up_pow2 (context->alignment);
6688 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
6689 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
6690 caps = gst_caps_new_simple ("audio/x-ac3",
6691 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6692 *codec_name = g_strdup ("AC-3 audio");
6693 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
6694 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
6695 caps = gst_caps_new_simple ("audio/x-eac3",
6696 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6697 *codec_name = g_strdup ("E-AC-3 audio");
6698 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
6699 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
6700 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
6701 *codec_name = g_strdup ("Dolby TrueHD");
6702 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
6703 caps = gst_caps_new_empty_simple ("audio/x-dts");
6704 *codec_name = g_strdup ("DTS audio");
6705 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
6706 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
6707 context->stream_headers =
6708 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6709 context->codec_priv_size);
6710 /* FIXME: mark stream as broken and skip if there are no stream headers */
6711 context->send_stream_headers = TRUE;
6712 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
6713 caps = gst_caps_new_empty_simple ("audio/x-flac");
6714 context->stream_headers =
6715 gst_matroska_parse_flac_stream_headers (context->codec_priv,
6716 context->codec_priv_size);
6717 /* FIXME: mark stream as broken and skip if there are no stream headers */
6718 context->send_stream_headers = TRUE;
6719 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
6720 caps = gst_caps_new_empty_simple ("audio/x-speex");
6721 context->stream_headers =
6722 gst_matroska_parse_speex_stream_headers (context->codec_priv,
6723 context->codec_priv_size);
6724 /* FIXME: mark stream as broken and skip if there are no stream headers */
6725 context->send_stream_headers = TRUE;
6726 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
6729 if (context->codec_priv_size >= 19) {
6730 if (audiocontext->samplerate)
6731 GST_WRITE_UINT32_LE ((guint8 *) context->codec_priv + 12,
6732 audiocontext->samplerate);
6733 if (context->codec_delay) {
6735 gst_util_uint64_scale_round (context->codec_delay, 48000,
6737 GST_WRITE_UINT16_LE ((guint8 *) context->codec_priv + 10, delay);
6741 gst_buffer_new_wrapped (g_memdup (context->codec_priv,
6742 context->codec_priv_size), context->codec_priv_size);
6743 caps = gst_codec_utils_opus_create_caps_from_header (tmp, NULL);
6744 gst_buffer_unref (tmp);
6745 *codec_name = g_strdup ("Opus");
6746 } else if (context->codec_priv_size == 0) {
6747 GST_WARNING ("No Opus codec data found, trying to create one");
6748 if (audiocontext->channels <= 2) {
6749 guint8 streams, coupled, channels;
6753 audiocontext->samplerate == 0 ? 48000 : audiocontext->samplerate;
6754 channels = audiocontext->channels == 0 ? 2 : audiocontext->channels;
6755 if (channels == 1) {
6764 gst_codec_utils_opus_create_caps (samplerate, channels, 0, streams,
6767 *codec_name = g_strdup ("Opus");
6769 GST_WARNING ("Failed to create Opus caps from audio context");
6772 GST_WARNING ("No Opus codec data, and not enough info to create one");
6775 GST_WARNING ("Invalid Opus codec data size (got %" G_GSIZE_FORMAT
6776 ", expected 19)", context->codec_priv_size);
6778 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
6779 gst_riff_strf_auds auds;
6781 if (data && size >= 18) {
6782 GstBuffer *codec_data = NULL;
6784 /* little-endian -> byte-order */
6785 auds.format = GST_READ_UINT16_LE (data);
6786 auds.channels = GST_READ_UINT16_LE (data + 2);
6787 auds.rate = GST_READ_UINT32_LE (data + 4);
6788 auds.av_bps = GST_READ_UINT32_LE (data + 8);
6789 auds.blockalign = GST_READ_UINT16_LE (data + 12);
6790 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
6792 /* 18 is the waveformatex size */
6794 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
6795 data + 18, size - 18, 0, size - 18, NULL, NULL);
6799 *riff_audio_fmt = auds.format;
6801 /* FIXME: Handle reorder map */
6802 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, codec_data,
6803 NULL, codec_name, NULL);
6805 gst_buffer_unref (codec_data);
6808 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
6811 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
6813 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
6814 GstBuffer *priv = NULL;
6816 gint rate_idx, profile;
6817 guint8 *data = NULL;
6819 /* unspecified AAC profile with opaque private codec data */
6820 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
6821 if (context->codec_priv_size >= 2) {
6822 guint obj_type, freq_index, explicit_freq_bytes = 0;
6824 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6826 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
6827 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
6828 if (freq_index == 15)
6829 explicit_freq_bytes = 3;
6830 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
6831 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
6832 context->codec_priv_size), context->codec_priv_size);
6833 /* assume SBR if samplerate <= 24kHz */
6834 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
6835 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
6836 audiocontext->samplerate *= 2;
6839 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
6840 /* this is pretty broken;
6841 * maybe we need to make up some default private,
6842 * or maybe ADTS data got dumped in.
6843 * Let's set up some private data now, and check actual data later */
6844 /* just try this and see what happens ... */
6845 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6846 context->postprocess_frame = gst_matroska_demux_check_aac;
6850 /* make up decoder-specific data if it is not supplied */
6854 priv = gst_buffer_new_allocate (NULL, 5, NULL);
6855 gst_buffer_map (priv, &map, GST_MAP_WRITE);
6857 rate_idx = aac_rate_idx (audiocontext->samplerate);
6858 profile = aac_profile_idx (codec_id);
6860 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
6861 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
6863 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
6864 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
6866 gst_buffer_unmap (priv, &map);
6867 gst_buffer_set_size (priv, 2);
6868 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
6869 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
6872 if (g_strrstr (codec_id, "SBR")) {
6873 /* HE-AAC (aka SBR AAC) */
6874 audiocontext->samplerate *= 2;
6875 rate_idx = aac_rate_idx (audiocontext->samplerate);
6876 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
6877 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
6878 data[4] = (1 << 7) | (rate_idx << 3);
6879 gst_buffer_unmap (priv, &map);
6881 gst_buffer_unmap (priv, &map);
6882 gst_buffer_set_size (priv, 2);
6885 gst_buffer_unmap (priv, &map);
6886 gst_buffer_unref (priv);
6888 GST_ERROR ("Unknown AAC profile and no codec private data");
6893 caps = gst_caps_new_simple ("audio/mpeg",
6894 "mpegversion", G_TYPE_INT, mpegversion,
6895 "framed", G_TYPE_BOOLEAN, TRUE,
6896 "stream-format", G_TYPE_STRING, "raw", NULL);
6897 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6898 if (context->codec_priv && context->codec_priv_size > 0)
6899 gst_codec_utils_aac_caps_set_level_and_profile (caps,
6900 context->codec_priv, context->codec_priv_size);
6901 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
6902 gst_buffer_unref (priv);
6904 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
6905 caps = gst_caps_new_simple ("audio/x-tta",
6906 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
6907 *codec_name = g_strdup ("TTA audio");
6908 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
6909 caps = gst_caps_new_simple ("audio/x-wavpack",
6910 "width", G_TYPE_INT, audiocontext->bitdepth,
6911 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6912 *codec_name = g_strdup ("Wavpack audio");
6913 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
6914 audiocontext->wvpk_block_index = 0;
6915 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
6916 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
6917 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
6918 gint raversion = -1;
6920 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
6922 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
6927 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
6928 "raversion", G_TYPE_INT, raversion, NULL);
6929 /* Extract extra information from caps, mapping varies based on codec */
6930 if (data && (size >= 0x50)) {
6937 guint extra_data_size;
6939 GST_DEBUG ("real audio raversion:%d", raversion);
6940 if (raversion == 8) {
6942 flavor = GST_READ_UINT16_BE (data + 22);
6943 packet_size = GST_READ_UINT32_BE (data + 24);
6944 height = GST_READ_UINT16_BE (data + 40);
6945 leaf_size = GST_READ_UINT16_BE (data + 44);
6946 sample_width = GST_READ_UINT16_BE (data + 58);
6947 extra_data_size = GST_READ_UINT32_BE (data + 74);
6950 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
6951 flavor, packet_size, height, leaf_size, sample_width,
6953 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
6954 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
6955 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
6957 if ((size - 78) >= extra_data_size) {
6958 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
6960 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6961 gst_buffer_unref (priv);
6966 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
6967 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
6968 caps = gst_caps_new_empty_simple ("audio/x-sipro");
6969 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
6970 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
6971 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
6972 *codec_name = g_strdup ("Real Audio Lossless");
6973 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
6974 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
6975 *codec_name = g_strdup ("Sony ATRAC3");
6977 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6982 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
6985 for (i = 0; i < gst_caps_get_size (caps); i++) {
6986 gst_structure_set (gst_caps_get_structure (caps, i),
6987 "channels", G_TYPE_INT, audiocontext->channels,
6988 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
6992 caps = gst_caps_simplify (caps);
6999 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
7000 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
7002 GstCaps *caps = NULL;
7003 GstMatroskaTrackContext *context =
7004 (GstMatroskaTrackContext *) subtitlecontext;
7006 /* for backwards compatibility */
7007 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
7008 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
7009 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
7010 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
7011 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
7012 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
7013 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
7014 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
7016 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
7017 * Check if we have to do something with codec_private */
7018 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
7019 /* well, plain text simply does not have a lot of markup ... */
7020 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
7021 "pango-markup", NULL);
7022 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
7023 subtitlecontext->check_markup = TRUE;
7024 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
7025 caps = gst_caps_new_empty_simple ("application/x-ssa");
7026 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
7027 subtitlecontext->check_markup = FALSE;
7028 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
7029 caps = gst_caps_new_empty_simple ("application/x-ass");
7030 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
7031 subtitlecontext->check_markup = FALSE;
7032 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
7033 caps = gst_caps_new_empty_simple ("application/x-usf");
7034 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
7035 subtitlecontext->check_markup = FALSE;
7036 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
7037 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
7038 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
7039 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
7040 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
7041 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
7042 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
7043 context->stream_headers =
7044 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
7045 context->codec_priv_size);
7046 /* FIXME: mark stream as broken and skip if there are no stream headers */
7047 context->send_stream_headers = TRUE;
7049 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
7050 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
7053 if (data != NULL && size > 0) {
7056 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
7057 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
7058 gst_buffer_unref (buf);
7066 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
7068 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
7070 GST_OBJECT_LOCK (demux);
7071 if (demux->common.element_index)
7072 gst_object_unref (demux->common.element_index);
7073 demux->common.element_index = index ? gst_object_ref (index) : NULL;
7074 GST_OBJECT_UNLOCK (demux);
7075 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
7076 demux->common.element_index);
7080 gst_matroska_demux_get_index (GstElement * element)
7082 GstIndex *result = NULL;
7083 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
7085 GST_OBJECT_LOCK (demux);
7086 if (demux->common.element_index)
7087 result = gst_object_ref (demux->common.element_index);
7088 GST_OBJECT_UNLOCK (demux);
7090 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
7096 static GstStateChangeReturn
7097 gst_matroska_demux_change_state (GstElement * element,
7098 GstStateChange transition)
7100 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
7101 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
7103 /* handle upwards state changes here */
7104 switch (transition) {
7109 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
7111 /* handle downwards state changes */
7112 switch (transition) {
7113 case GST_STATE_CHANGE_PAUSED_TO_READY:
7114 gst_matroska_demux_reset (GST_ELEMENT (demux));
7124 gst_matroska_demux_set_property (GObject * object,
7125 guint prop_id, const GValue * value, GParamSpec * pspec)
7127 GstMatroskaDemux *demux;
7129 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
7130 demux = GST_MATROSKA_DEMUX (object);
7133 case PROP_MAX_GAP_TIME:
7134 GST_OBJECT_LOCK (demux);
7135 demux->max_gap_time = g_value_get_uint64 (value);
7136 GST_OBJECT_UNLOCK (demux);
7138 case PROP_MAX_BACKTRACK_DISTANCE:
7139 GST_OBJECT_LOCK (demux);
7140 demux->max_backtrack_distance = g_value_get_uint (value);
7141 GST_OBJECT_UNLOCK (demux);
7144 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
7150 gst_matroska_demux_get_property (GObject * object,
7151 guint prop_id, GValue * value, GParamSpec * pspec)
7153 GstMatroskaDemux *demux;
7155 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
7156 demux = GST_MATROSKA_DEMUX (object);
7159 case PROP_MAX_GAP_TIME:
7160 GST_OBJECT_LOCK (demux);
7161 g_value_set_uint64 (value, demux->max_gap_time);
7162 GST_OBJECT_UNLOCK (demux);
7164 case PROP_MAX_BACKTRACK_DISTANCE:
7165 GST_OBJECT_LOCK (demux);
7166 g_value_set_uint (value, demux->max_backtrack_distance);
7167 GST_OBJECT_UNLOCK (demux);
7170 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
7175 static const gchar *
7176 gst_matroska_track_encryption_algorithm_name (gint val)
7179 GEnumClass *enum_class =
7180 g_type_class_ref (MATROSKA_TRACK_ENCRYPTION_ALGORITHM_TYPE);
7181 en = g_enum_get_value (G_ENUM_CLASS (enum_class), val);
7182 return en ? en->value_nick : NULL;
7185 static const gchar *
7186 gst_matroska_track_encryption_cipher_mode_name (gint val)
7189 GEnumClass *enum_class =
7190 g_type_class_ref (MATROSKA_TRACK_ENCRYPTION_CIPHER_MODE_TYPE);
7191 en = g_enum_get_value (G_ENUM_CLASS (enum_class), val);
7192 return en ? en->value_nick : NULL;
7195 static const gchar *
7196 gst_matroska_track_encoding_scope_name (gint val)
7199 GEnumClass *enum_class =
7200 g_type_class_ref (MATROSKA_TRACK_ENCODING_SCOPE_TYPE);
7202 en = g_enum_get_value (G_ENUM_CLASS (enum_class), val);
7203 return en ? en->value_nick : NULL;
7207 gst_matroska_demux_plugin_init (GstPlugin * plugin)
7211 /* parser helper separate debug */
7212 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
7213 0, "EBML stream helper class");
7215 /* create an elementfactory for the matroska_demux element */
7216 if (!gst_element_register (plugin, "matroskademux",
7217 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))