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
37 * matroskademux demuxes a Matroska file into the different contained streams.
40 * <title>Example launch line</title>
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 /* For AVI compatibility mode
57 and for fourcc stuff */
58 #include <gst/riff/riff-read.h>
59 #include <gst/riff/riff-ids.h>
60 #include <gst/riff/riff-media.h>
62 #include <gst/audio/audio.h>
63 #include <gst/tag/tag.h>
64 #include <gst/pbutils/pbutils.h>
65 #include <gst/video/video.h>
67 #include "matroska-demux.h"
68 #include "matroska-ids.h"
70 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
71 #define GST_CAT_DEFAULT matroskademux_debug
73 #define DEBUG_ELEMENT_START(demux, ebml, element) \
74 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
75 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
77 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
78 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
79 " finished with '%s'", gst_flow_get_name (ret))
89 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
90 #define INVALID_DATA_THRESHOLD (2 * 1024 * 1024)
92 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
95 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
96 "video/x-matroska-3d; audio/webm; video/webm")
99 /* TODO: fill in caps! */
101 static GstStaticPadTemplate audio_src_templ =
102 GST_STATIC_PAD_TEMPLATE ("audio_%u",
105 GST_STATIC_CAPS ("ANY")
108 static GstStaticPadTemplate video_src_templ =
109 GST_STATIC_PAD_TEMPLATE ("video_%u",
112 GST_STATIC_CAPS ("ANY")
115 static GstStaticPadTemplate subtitle_src_templ =
116 GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
119 GST_STATIC_CAPS ("text/x-raw, format=pango-markup; application/x-ssa; "
120 "application/x-ass;application/x-usf; subpicture/x-dvd; "
121 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
124 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
125 guint32 id, guint64 length, guint needed);
127 /* element functions */
128 static void gst_matroska_demux_loop (GstPad * pad);
130 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
132 static gboolean gst_matroska_demux_element_query (GstElement * element,
136 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad,
138 static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
139 GstObject * parent, GstPadMode mode, gboolean active);
141 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
142 GstPad * pad, GstEvent * event);
143 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
144 GstObject * parent, GstEvent * event);
145 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
146 GstObject * parent, GstQuery * query);
148 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
149 GstObject * parent, GstEvent * event);
150 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
151 GstObject * object, GstBuffer * buffer);
153 static GstStateChangeReturn
154 gst_matroska_demux_change_state (GstElement * element,
155 GstStateChange transition);
158 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
159 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
163 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
164 * videocontext, const gchar * codec_id, guint8 * data, guint size,
165 gchar ** codec_name, guint32 * riff_fourcc);
166 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
167 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
168 gchar ** codec_name, guint16 * riff_audio_fmt);
170 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
171 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
174 static void gst_matroska_demux_reset (GstElement * element);
175 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
176 gdouble rate, guint64 offset, guint32 seqnum, GstSeekFlags flags);
178 /* gobject functions */
179 static void gst_matroska_demux_set_property (GObject * object,
180 guint prop_id, const GValue * value, GParamSpec * pspec);
181 static void gst_matroska_demux_get_property (GObject * object,
182 guint prop_id, GValue * value, GParamSpec * pspec);
184 GType gst_matroska_demux_get_type (void);
185 #define parent_class gst_matroska_demux_parent_class
186 G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
189 gst_matroska_demux_finalize (GObject * object)
191 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
193 gst_matroska_read_common_finalize (&demux->common);
194 gst_flow_combiner_free (demux->flowcombiner);
195 G_OBJECT_CLASS (parent_class)->finalize (object);
199 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
201 GObjectClass *gobject_class = (GObjectClass *) klass;
202 GstElementClass *gstelement_class = (GstElementClass *) klass;
204 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
207 gobject_class->finalize = gst_matroska_demux_finalize;
209 gobject_class->get_property = gst_matroska_demux_get_property;
210 gobject_class->set_property = gst_matroska_demux_set_property;
212 g_object_class_install_property (gobject_class, PROP_MAX_GAP_TIME,
213 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
214 "The demuxer sends out segment events for skipping "
215 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
216 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
218 gstelement_class->change_state =
219 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
220 gstelement_class->send_event =
221 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
222 gstelement_class->query =
223 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
225 gstelement_class->set_index =
226 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
227 gstelement_class->get_index =
228 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
231 gst_element_class_add_static_pad_template (gstelement_class,
233 gst_element_class_add_static_pad_template (gstelement_class,
235 gst_element_class_add_static_pad_template (gstelement_class,
236 &subtitle_src_templ);
237 gst_element_class_add_static_pad_template (gstelement_class, &sink_templ);
239 gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
241 "Demuxes Matroska/WebM streams into video/audio/subtitles",
242 "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
246 gst_matroska_demux_init (GstMatroskaDemux * demux)
248 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
250 gst_pad_set_activate_function (demux->common.sinkpad,
251 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
252 gst_pad_set_activatemode_function (demux->common.sinkpad,
253 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
254 gst_pad_set_chain_function (demux->common.sinkpad,
255 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
256 gst_pad_set_event_function (demux->common.sinkpad,
257 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
258 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
260 /* init defaults for common read context */
261 gst_matroska_read_common_init (&demux->common);
263 /* property defaults */
264 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
266 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
268 demux->flowcombiner = gst_flow_combiner_new ();
271 gst_matroska_demux_reset (GST_ELEMENT (demux));
275 gst_matroska_demux_reset (GstElement * element)
277 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
279 GST_DEBUG_OBJECT (demux, "Resetting state");
281 gst_matroska_read_common_reset (GST_ELEMENT (demux), &demux->common);
283 demux->num_a_streams = 0;
284 demux->num_t_streams = 0;
285 demux->num_v_streams = 0;
287 demux->have_group_id = FALSE;
288 demux->group_id = G_MAXUINT;
291 demux->tracks_parsed = FALSE;
293 if (demux->clusters) {
294 g_array_free (demux->clusters, TRUE);
295 demux->clusters = NULL;
298 g_list_foreach (demux->seek_parsed,
299 (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
300 g_list_free (demux->seek_parsed);
301 demux->seek_parsed = NULL;
303 demux->last_stop_end = GST_CLOCK_TIME_NONE;
304 demux->seek_block = 0;
305 demux->stream_start_time = GST_CLOCK_TIME_NONE;
306 demux->to_time = GST_CLOCK_TIME_NONE;
307 demux->cluster_time = GST_CLOCK_TIME_NONE;
308 demux->cluster_offset = 0;
309 demux->next_cluster_offset = 0;
310 demux->stream_last_time = GST_CLOCK_TIME_NONE;
311 demux->last_cluster_offset = 0;
312 demux->index_offset = 0;
313 demux->seekable = FALSE;
314 demux->need_segment = FALSE;
315 demux->segment_seqnum = 0;
316 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
317 demux->seek_offset = -1;
318 demux->building_index = FALSE;
319 if (demux->seek_event) {
320 gst_event_unref (demux->seek_event);
321 demux->seek_event = NULL;
324 demux->seek_index = NULL;
325 demux->seek_entry = 0;
327 if (demux->new_segment) {
328 gst_event_unref (demux->new_segment);
329 demux->new_segment = NULL;
332 demux->invalid_duration = FALSE;
334 demux->cached_length = G_MAXUINT64;
336 gst_flow_combiner_clear (demux->flowcombiner);
340 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
346 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
348 GST_DEBUG ("decoding buffer %p", buf);
350 gst_buffer_map (buf, &map, GST_MAP_READ);
354 g_return_val_if_fail (size > 0, buf);
356 if (gst_matroska_decode_data (context->encodings, &data, &size,
357 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
358 gst_buffer_unmap (buf, &map);
359 gst_buffer_unref (buf);
360 return gst_buffer_new_wrapped (data, size);
362 GST_DEBUG ("decode data failed");
363 gst_buffer_unmap (buf, &map);
364 gst_buffer_unref (buf);
370 gst_matroska_demux_add_stream_headers_to_caps (GstMatroskaDemux * demux,
371 GstBufferList * list, GstCaps * caps)
374 GValue arr_val = G_VALUE_INIT;
375 GValue buf_val = G_VALUE_INIT;
378 g_assert (gst_caps_is_writable (caps));
380 g_value_init (&arr_val, GST_TYPE_ARRAY);
381 g_value_init (&buf_val, GST_TYPE_BUFFER);
383 num = gst_buffer_list_length (list);
384 for (i = 0; i < num; ++i) {
385 g_value_set_boxed (&buf_val, gst_buffer_list_get (list, i));
386 gst_value_array_append_value (&arr_val, &buf_val);
389 s = gst_caps_get_structure (caps, 0);
390 gst_structure_take_value (s, "streamheader", &arr_val);
391 g_value_unset (&buf_val);
395 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
397 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
398 GstMatroskaTrackContext *context;
399 GstPadTemplate *templ = NULL;
400 GstStreamFlags stream_flags;
401 GstCaps *caps = NULL;
402 GstTagList *cached_taglist;
403 gchar *padname = NULL;
405 guint32 id, riff_fourcc = 0;
406 guint16 riff_audio_fmt = 0;
407 GstEvent *stream_start;
411 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
413 /* start with the master */
414 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
415 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
419 /* allocate generic... if we know the type, we'll g_renew()
420 * with the precise type */
421 context = g_new0 (GstMatroskaTrackContext, 1);
422 g_ptr_array_add (demux->common.src, context);
423 context->index = demux->common.num_streams;
424 context->index_writer_id = -1;
425 context->type = 0; /* no type yet */
426 context->default_duration = 0;
428 context->set_discont = TRUE;
429 context->timecodescale = 1.0;
431 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
432 GST_MATROSKA_TRACK_LACING;
433 context->from_time = GST_CLOCK_TIME_NONE;
434 context->from_offset = -1;
435 context->to_offset = G_MAXINT64;
436 context->alignment = 1;
437 context->dts_only = FALSE;
438 context->intra_only = FALSE;
439 context->tags = gst_tag_list_new_empty ();
440 demux->common.num_streams++;
441 g_assert (demux->common.src->len == demux->common.num_streams);
443 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
445 /* try reading the trackentry headers */
446 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
447 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
451 /* track number (unique stream ID) */
452 case GST_MATROSKA_ID_TRACKNUMBER:{
455 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
459 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
460 ret = GST_FLOW_ERROR;
462 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
464 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
465 " is not unique", num);
466 ret = GST_FLOW_ERROR;
470 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
474 /* track UID (unique identifier) */
475 case GST_MATROSKA_ID_TRACKUID:{
478 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
482 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
483 ret = GST_FLOW_ERROR;
487 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
492 /* track type (video, audio, combined, subtitle, etc.) */
493 case GST_MATROSKA_ID_TRACKTYPE:{
496 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
500 if (context->type != 0 && context->type != track_type) {
501 GST_WARNING_OBJECT (demux,
502 "More than one tracktype defined in a TrackEntry - skipping");
504 } else if (track_type < 1 || track_type > 254) {
505 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
510 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
512 /* ok, so we're actually going to reallocate this thing */
513 switch (track_type) {
514 case GST_MATROSKA_TRACK_TYPE_VIDEO:
515 gst_matroska_track_init_video_context (&context);
517 case GST_MATROSKA_TRACK_TYPE_AUDIO:
518 gst_matroska_track_init_audio_context (&context);
520 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
521 gst_matroska_track_init_subtitle_context (&context);
523 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
524 case GST_MATROSKA_TRACK_TYPE_LOGO:
525 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
526 case GST_MATROSKA_TRACK_TYPE_CONTROL:
528 GST_WARNING_OBJECT (demux,
529 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
534 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
539 /* tracktype specific stuff for video */
540 case GST_MATROSKA_ID_TRACKVIDEO:{
541 GstMatroskaTrackVideoContext *videocontext;
543 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
545 if (!gst_matroska_track_init_video_context (&context)) {
546 GST_WARNING_OBJECT (demux,
547 "TrackVideo element in non-video track - ignoring track");
548 ret = GST_FLOW_ERROR;
550 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
553 videocontext = (GstMatroskaTrackVideoContext *) context;
554 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
557 while (ret == GST_FLOW_OK &&
558 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
559 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
563 /* Should be one level up but some broken muxers write it here. */
564 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
567 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
571 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
575 GST_DEBUG_OBJECT (demux,
576 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
577 context->default_duration = num;
581 /* video framerate */
582 /* NOTE: This one is here only for backward compatibility.
583 * Use _TRACKDEFAULDURATION one level up. */
584 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
587 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
591 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
595 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
596 if (context->default_duration == 0)
597 context->default_duration =
598 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
599 videocontext->default_fps = num;
603 /* width of the size to display the video at */
604 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
607 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
611 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
615 GST_DEBUG_OBJECT (demux,
616 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
617 videocontext->display_width = num;
621 /* height of the size to display the video at */
622 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
625 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
629 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
633 GST_DEBUG_OBJECT (demux,
634 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
635 videocontext->display_height = num;
639 /* width of the video in the file */
640 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
643 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
647 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
651 GST_DEBUG_OBJECT (demux,
652 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
653 videocontext->pixel_width = num;
657 /* height of the video in the file */
658 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
661 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
665 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
669 GST_DEBUG_OBJECT (demux,
670 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
671 videocontext->pixel_height = num;
675 /* whether the video is interlaced */
676 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
679 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
683 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
685 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
686 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
687 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
692 /* aspect ratio behaviour */
693 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
696 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
699 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
700 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
701 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
702 GST_WARNING_OBJECT (demux,
703 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
706 GST_DEBUG_OBJECT (demux,
707 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
708 videocontext->asr_mode = num;
712 /* colourspace (only matters for raw video) fourcc */
713 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
718 gst_ebml_read_binary (ebml, &id, &data,
719 &datalen)) != GST_FLOW_OK)
724 GST_WARNING_OBJECT (demux,
725 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
730 memcpy (&videocontext->fourcc, data, 4);
731 GST_DEBUG_OBJECT (demux,
732 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
733 GST_FOURCC_ARGS (videocontext->fourcc));
737 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
741 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
744 GST_DEBUG_OBJECT (demux, "StereoMode: %" G_GUINT64_FORMAT, num);
747 case GST_MATROSKA_STEREO_MODE_SBS_RL:
748 videocontext->multiview_flags =
749 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
751 case GST_MATROSKA_STEREO_MODE_SBS_LR:
752 videocontext->multiview_mode =
753 GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
755 case GST_MATROSKA_STEREO_MODE_TB_RL:
756 videocontext->multiview_flags =
757 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
759 case GST_MATROSKA_STEREO_MODE_TB_LR:
760 videocontext->multiview_mode =
761 GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM;
763 case GST_MATROSKA_STEREO_MODE_CHECKER_RL:
764 videocontext->multiview_flags =
765 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
767 case GST_MATROSKA_STEREO_MODE_CHECKER_LR:
768 videocontext->multiview_mode =
769 GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD;
771 case GST_MATROSKA_STEREO_MODE_FBF_RL:
772 videocontext->multiview_flags =
773 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
775 case GST_MATROSKA_STEREO_MODE_FBF_LR:
776 videocontext->multiview_mode =
777 GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
778 /* FIXME: In frame-by-frame mode, left/right frame buffers are
779 * laced within one block, and we'll need to apply FIRST_IN_BUNDLE
780 * accordingly. See http://www.matroska.org/technical/specs/index.html#StereoMode */
781 GST_FIXME_OBJECT (demux,
782 "Frame-by-frame stereoscopic mode not fully implemented");
789 GST_WARNING_OBJECT (demux,
790 "Unknown TrackVideo subelement 0x%x - ignoring", id);
792 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
793 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
794 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
795 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
796 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
797 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
798 ret = gst_ebml_read_skip (ebml);
803 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
807 /* tracktype specific stuff for audio */
808 case GST_MATROSKA_ID_TRACKAUDIO:{
809 GstMatroskaTrackAudioContext *audiocontext;
811 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
813 if (!gst_matroska_track_init_audio_context (&context)) {
814 GST_WARNING_OBJECT (demux,
815 "TrackAudio element in non-audio track - ignoring track");
816 ret = GST_FLOW_ERROR;
820 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
823 audiocontext = (GstMatroskaTrackAudioContext *) context;
824 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
827 while (ret == GST_FLOW_OK &&
828 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
829 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
834 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
837 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
842 GST_WARNING_OBJECT (demux,
843 "Invalid TrackAudioSamplingFrequency %lf", num);
847 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
848 audiocontext->samplerate = num;
853 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
856 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
860 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
864 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
866 audiocontext->bitdepth = num;
871 case GST_MATROSKA_ID_AUDIOCHANNELS:{
874 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
878 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
882 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
884 audiocontext->channels = num;
889 GST_WARNING_OBJECT (demux,
890 "Unknown TrackAudio subelement 0x%x - ignoring", id);
892 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
893 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
894 ret = gst_ebml_read_skip (ebml);
899 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
904 /* codec identifier */
905 case GST_MATROSKA_ID_CODECID:{
908 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
911 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
912 context->codec_id = text;
916 /* codec private data */
917 case GST_MATROSKA_ID_CODECPRIVATE:{
922 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
925 context->codec_priv = data;
926 context->codec_priv_size = size;
928 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
933 /* name of the codec */
934 case GST_MATROSKA_ID_CODECNAME:{
937 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
940 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
941 context->codec_name = text;
946 case GST_MATROSKA_ID_CODECDELAY:{
949 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
952 context->codec_delay = num;
954 GST_DEBUG_OBJECT (demux, "CodecDelay: %" GST_TIME_FORMAT,
955 GST_TIME_ARGS (num));
960 case GST_MATROSKA_ID_SEEKPREROLL:{
963 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
966 context->seek_preroll = num;
968 GST_DEBUG_OBJECT (demux, "SeekPreroll: %" GST_TIME_FORMAT,
969 GST_TIME_ARGS (num));
973 /* name of this track */
974 case GST_MATROSKA_ID_TRACKNAME:{
977 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
980 context->name = text;
981 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
985 /* language (matters for audio/subtitles, mostly) */
986 case GST_MATROSKA_ID_TRACKLANGUAGE:{
989 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
993 context->language = text;
996 if (strlen (context->language) >= 4 && context->language[3] == '-')
997 context->language[3] = '\0';
999 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1000 GST_STR_NULL (context->language));
1004 /* whether this is actually used */
1005 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1008 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1012 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1014 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1016 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1017 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1021 /* whether it's the default for this track type */
1022 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1025 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1029 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1031 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1033 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1034 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
1038 /* whether the track must be used during playback */
1039 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1042 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1046 context->flags |= GST_MATROSKA_TRACK_FORCED;
1048 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1050 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1051 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
1055 /* lacing (like MPEG, where blocks don't end/start on frame
1057 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1060 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1064 context->flags |= GST_MATROSKA_TRACK_LACING;
1066 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1068 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1069 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
1073 /* default length (in time) of one data block in this track */
1074 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1077 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1082 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1086 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1088 context->default_duration = num;
1092 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1093 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1098 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1101 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1105 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1109 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1110 context->timecodescale = num;
1115 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1118 /* we ignore these because they're nothing useful (i.e. crap)
1119 * or simply not implemented yet. */
1120 case GST_MATROSKA_ID_TRACKMINCACHE:
1121 case GST_MATROSKA_ID_TRACKMAXCACHE:
1122 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1123 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1124 case GST_MATROSKA_ID_TRACKOVERLAY:
1125 case GST_MATROSKA_ID_TRACKTRANSLATE:
1126 case GST_MATROSKA_ID_TRACKOFFSET:
1127 case GST_MATROSKA_ID_CODECSETTINGS:
1128 case GST_MATROSKA_ID_CODECINFOURL:
1129 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1130 case GST_MATROSKA_ID_CODECDECODEALL:
1131 ret = gst_ebml_read_skip (ebml);
1136 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1138 /* Decode codec private data if necessary */
1139 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1140 && context->codec_priv_size > 0) {
1141 if (!gst_matroska_decode_data (context->encodings,
1142 &context->codec_priv, &context->codec_priv_size,
1143 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1144 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1145 ret = GST_FLOW_ERROR;
1149 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1150 && ret != GST_FLOW_EOS)) {
1151 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1152 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1154 demux->common.num_streams--;
1155 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1156 g_assert (demux->common.src->len == demux->common.num_streams);
1157 gst_matroska_track_free (context);
1162 /* check for a cached track taglist */
1164 (GstTagList *) g_hash_table_lookup (demux->common.cached_track_taglists,
1165 GUINT_TO_POINTER (context->uid));
1167 gst_tag_list_insert (context->tags, cached_taglist, GST_TAG_MERGE_APPEND);
1169 /* now create the GStreamer connectivity */
1170 switch (context->type) {
1171 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1172 GstMatroskaTrackVideoContext *videocontext =
1173 (GstMatroskaTrackVideoContext *) context;
1175 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1176 templ = gst_element_class_get_pad_template (klass, "video_%u");
1177 caps = gst_matroska_demux_video_caps (videocontext,
1178 context->codec_id, context->codec_priv,
1179 context->codec_priv_size, &codec, &riff_fourcc);
1182 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1183 GST_TAG_VIDEO_CODEC, codec, NULL);
1184 context->tags_changed = TRUE;
1190 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1191 GstMatroskaTrackAudioContext *audiocontext =
1192 (GstMatroskaTrackAudioContext *) context;
1194 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1195 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1196 caps = gst_matroska_demux_audio_caps (audiocontext,
1197 context->codec_id, context->codec_priv, context->codec_priv_size,
1198 &codec, &riff_audio_fmt);
1201 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1202 GST_TAG_AUDIO_CODEC, codec, NULL);
1203 context->tags_changed = TRUE;
1209 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1210 GstMatroskaTrackSubtitleContext *subtitlecontext =
1211 (GstMatroskaTrackSubtitleContext *) context;
1213 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1214 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1215 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1216 context->codec_id, context->codec_priv, context->codec_priv_size);
1220 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1221 case GST_MATROSKA_TRACK_TYPE_LOGO:
1222 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1223 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1225 /* we should already have quit by now */
1226 g_assert_not_reached ();
1229 if ((context->language == NULL || *context->language == '\0') &&
1230 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1231 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1232 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1233 context->language = g_strdup ("eng");
1236 if (context->language) {
1239 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1240 lang = gst_tag_get_language_code (context->language);
1241 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1242 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1243 context->tags_changed = TRUE;
1247 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1248 "codec_id='%s'", context->codec_id);
1249 switch (context->type) {
1250 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1251 caps = gst_caps_new_empty_simple ("video/x-unknown");
1253 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1254 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1256 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1257 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1259 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1261 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1264 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1267 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1268 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1269 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1270 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1271 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1272 GST_FOURCC_ARGS (riff_fourcc));
1273 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1276 } else if (context->stream_headers != NULL) {
1277 gst_matroska_demux_add_stream_headers_to_caps (demux,
1278 context->stream_headers, caps);
1281 /* the pad in here */
1282 context->pad = gst_pad_new_from_template (templ, padname);
1283 context->caps = caps;
1285 gst_pad_set_event_function (context->pad,
1286 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1287 gst_pad_set_query_function (context->pad,
1288 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1290 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1293 gst_pad_set_element_private (context->pad, context);
1295 gst_pad_use_fixed_caps (context->pad);
1296 gst_pad_set_active (context->pad, TRUE);
1299 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1300 "%03" G_GUINT64_FORMAT ":%03" G_GUINT64_FORMAT,
1301 context->num, context->uid);
1303 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1306 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1307 demux->have_group_id = TRUE;
1309 demux->have_group_id = FALSE;
1310 gst_event_unref (stream_start);
1311 } else if (!demux->have_group_id) {
1312 demux->have_group_id = TRUE;
1313 demux->group_id = gst_util_group_id_next ();
1316 stream_start = gst_event_new_stream_start (stream_id);
1318 if (demux->have_group_id)
1319 gst_event_set_group_id (stream_start, demux->group_id);
1320 stream_flags = GST_STREAM_FLAG_NONE;
1321 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1322 stream_flags |= GST_STREAM_FLAG_SPARSE;
1323 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1324 stream_flags |= GST_STREAM_FLAG_SELECT;
1325 gst_event_set_stream_flags (stream_start, stream_flags);
1326 gst_pad_push_event (context->pad, stream_start);
1327 gst_pad_set_caps (context->pad, context->caps);
1330 if (demux->common.global_tags) {
1331 GstEvent *tag_event;
1333 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1334 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1335 GST_DEBUG_OBJECT (context->pad, "Sending global_tags %p: %" GST_PTR_FORMAT,
1336 demux->common.global_tags, demux->common.global_tags);
1339 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1341 gst_pad_push_event (context->pad, tag_event);
1344 if (G_UNLIKELY (context->tags_changed)) {
1345 GST_DEBUG_OBJECT (context->pad, "Sending tags %p: %"
1346 GST_PTR_FORMAT, context->tags, context->tags);
1347 gst_pad_push_event (context->pad,
1348 gst_event_new_tag (gst_tag_list_copy (context->tags)));
1349 context->tags_changed = FALSE;
1352 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1353 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1362 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1365 gboolean res = FALSE;
1366 GstMatroskaTrackContext *context = NULL;
1369 context = gst_pad_get_element_private (pad);
1372 switch (GST_QUERY_TYPE (query)) {
1373 case GST_QUERY_POSITION:
1377 gst_query_parse_position (query, &format, NULL);
1380 if (format == GST_FORMAT_TIME) {
1381 GST_OBJECT_LOCK (demux);
1383 gst_query_set_position (query, GST_FORMAT_TIME,
1384 MAX (context->pos, demux->stream_start_time) -
1385 demux->stream_start_time);
1387 gst_query_set_position (query, GST_FORMAT_TIME,
1388 MAX (demux->common.segment.position, demux->stream_start_time) -
1389 demux->stream_start_time);
1390 GST_OBJECT_UNLOCK (demux);
1391 } else if (format == GST_FORMAT_DEFAULT && context
1392 && context->default_duration) {
1393 GST_OBJECT_LOCK (demux);
1394 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1395 context->pos / context->default_duration);
1396 GST_OBJECT_UNLOCK (demux);
1398 GST_DEBUG_OBJECT (demux,
1399 "only position query in TIME and DEFAULT format is supported");
1405 case GST_QUERY_DURATION:
1409 gst_query_parse_duration (query, &format, NULL);
1412 if (format == GST_FORMAT_TIME) {
1413 GST_OBJECT_LOCK (demux);
1414 gst_query_set_duration (query, GST_FORMAT_TIME,
1415 demux->common.segment.duration);
1416 GST_OBJECT_UNLOCK (demux);
1417 } else if (format == GST_FORMAT_DEFAULT && context
1418 && context->default_duration) {
1419 GST_OBJECT_LOCK (demux);
1420 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1421 demux->common.segment.duration / context->default_duration);
1422 GST_OBJECT_UNLOCK (demux);
1424 GST_DEBUG_OBJECT (demux,
1425 "only duration query in TIME and DEFAULT format is supported");
1431 case GST_QUERY_SEEKING:
1435 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1436 GST_OBJECT_LOCK (demux);
1437 if (fmt == GST_FORMAT_TIME) {
1440 if (demux->streaming) {
1441 /* assuming we'll be able to get an index ... */
1442 seekable = demux->seekable;
1447 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1448 0, demux->common.segment.duration);
1451 GST_OBJECT_UNLOCK (demux);
1454 case GST_QUERY_SEGMENT:
1459 format = demux->common.segment.format;
1462 gst_segment_to_stream_time (&demux->common.segment, format,
1463 demux->common.segment.start);
1464 if ((stop = demux->common.segment.stop) == -1)
1465 stop = demux->common.segment.duration;
1468 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1470 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1477 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1480 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1489 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1491 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1495 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1498 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1500 return gst_matroska_demux_query (demux, pad, query);
1503 /* returns FALSE if there are no pads to deliver event to,
1504 * otherwise TRUE (whatever the outcome of event sending),
1505 * takes ownership of the passed event! */
1507 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1509 gboolean ret = FALSE;
1512 g_return_val_if_fail (event != NULL, FALSE);
1514 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1515 GST_EVENT_TYPE_NAME (event));
1517 g_assert (demux->common.src->len == demux->common.num_streams);
1518 for (i = 0; i < demux->common.src->len; i++) {
1519 GstMatroskaTrackContext *stream;
1521 stream = g_ptr_array_index (demux->common.src, i);
1522 gst_event_ref (event);
1523 gst_pad_push_event (stream->pad, event);
1527 gst_event_unref (event);
1532 gst_matroska_demux_send_tags (GstMatroskaDemux * demux)
1536 if (G_UNLIKELY (demux->common.global_tags_changed)) {
1537 GstEvent *tag_event;
1538 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1539 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1540 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1541 demux->common.global_tags, demux->common.global_tags);
1544 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1546 for (i = 0; i < demux->common.src->len; i++) {
1547 GstMatroskaTrackContext *stream;
1549 stream = g_ptr_array_index (demux->common.src, i);
1550 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1553 gst_event_unref (tag_event);
1554 demux->common.global_tags_changed = FALSE;
1557 g_assert (demux->common.src->len == demux->common.num_streams);
1558 for (i = 0; i < demux->common.src->len; i++) {
1559 GstMatroskaTrackContext *stream;
1561 stream = g_ptr_array_index (demux->common.src, i);
1563 if (G_UNLIKELY (stream->tags_changed)) {
1564 GST_DEBUG_OBJECT (demux, "Sending tags %p for pad %s:%s : %"
1565 GST_PTR_FORMAT, stream->tags,
1566 GST_DEBUG_PAD_NAME (stream->pad), stream->tags);
1567 gst_pad_push_event (stream->pad,
1568 gst_event_new_tag (gst_tag_list_copy (stream->tags)));
1569 stream->tags_changed = FALSE;
1575 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1577 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1580 g_return_val_if_fail (event != NULL, FALSE);
1582 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1583 /* no seeking until we are (safely) ready */
1584 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
1585 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
1586 gst_event_unref (event);
1589 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1591 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1592 GST_EVENT_TYPE_NAME (event));
1595 gst_event_unref (event);
1600 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1601 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1605 GST_OBJECT_LOCK (demux);
1608 /* seek (relative to matroska segment) */
1609 /* position might be invalid; will error when streaming resumes ... */
1610 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1611 demux->next_cluster_offset = 0;
1613 GST_DEBUG_OBJECT (demux,
1614 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1615 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1616 entry->block, GST_TIME_ARGS (entry->time));
1618 /* update the time */
1619 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1620 gst_flow_combiner_reset (demux->flowcombiner);
1621 demux->common.segment.position = entry->time;
1622 demux->seek_block = entry->block;
1623 demux->seek_first = TRUE;
1624 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1627 for (i = 0; i < demux->common.src->len; i++) {
1628 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1631 stream->to_offset = G_MAXINT64;
1633 if (stream->from_offset != -1)
1634 stream->to_offset = stream->from_offset;
1636 stream->from_offset = -1;
1637 stream->from_time = GST_CLOCK_TIME_NONE;
1640 GST_OBJECT_UNLOCK (demux);
1646 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1656 /* searches for a cluster start from @pos,
1657 * return GST_FLOW_OK and cluster position in @pos if found */
1658 static GstFlowReturn
1659 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos,
1662 gint64 newpos = *pos;
1664 GstFlowReturn ret = GST_FLOW_OK;
1665 const guint chunk = 128 * 1024;
1666 GstBuffer *buf = NULL;
1668 gpointer data = NULL;
1673 gint64 oldpos, oldlength;
1675 orig_offset = demux->common.offset;
1677 GST_LOG_OBJECT (demux, "searching cluster %s offset %" G_GINT64_FORMAT,
1678 forward ? "following" : "preceding", *pos);
1680 if (demux->clusters) {
1683 cpos = gst_util_array_binary_search (demux->clusters->data,
1684 demux->clusters->len, sizeof (gint64),
1685 (GCompareDataFunc) gst_matroska_cluster_compare,
1686 forward ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE, pos, NULL);
1689 GST_DEBUG_OBJECT (demux,
1690 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1691 demux->common.offset = *cpos;
1692 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1693 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1694 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1701 /* read in at newpos and scan for ebml cluster id */
1702 oldpos = oldlength = -1;
1704 GstByteReader reader;
1706 guint toread = chunk;
1709 /* never read beyond the requested target */
1710 if (G_UNLIKELY (newpos < chunk)) {
1718 gst_buffer_unmap (buf, &map);
1719 gst_buffer_unref (buf);
1722 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, toread, &buf);
1723 if (ret != GST_FLOW_OK)
1725 GST_DEBUG_OBJECT (demux,
1726 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1727 gst_buffer_get_size (buf), newpos);
1728 gst_buffer_map (buf, &map, GST_MAP_READ);
1731 if (oldpos == newpos && oldlength == map.size) {
1732 GST_ERROR_OBJECT (demux, "Stuck at same position");
1733 ret = GST_FLOW_ERROR;
1737 oldlength = map.size;
1740 gst_byte_reader_init (&reader, data, size);
1743 gint found = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1744 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1746 cluster_pos = found;
1749 /* need last occurrence when searching backwards */
1751 cluster_pos = gst_byte_reader_get_pos (&reader) + found;
1752 gst_byte_reader_skip (&reader, found + 4);
1758 if (cluster_pos >= 0) {
1759 newpos += cluster_pos;
1760 GST_DEBUG_OBJECT (demux,
1761 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1762 /* extra checks whether we really sync'ed to a cluster:
1763 * - either it is the first and only cluster
1764 * - either there is a cluster after this one
1765 * - either cluster length is undefined
1767 /* ok if first cluster (there may not a subsequent one) */
1768 if (newpos == demux->first_cluster_offset) {
1769 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1772 demux->common.offset = newpos;
1773 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1774 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1775 if (ret != GST_FLOW_OK) {
1776 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1779 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1780 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1782 /* ok if undefined length or first cluster */
1783 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1784 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1788 demux->common.offset += length + needed;
1789 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1790 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1791 if (ret != GST_FLOW_OK)
1793 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1794 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1795 if (id == GST_MATROSKA_ID_CLUSTER)
1801 /* partial cluster id may have been in tail of buffer */
1803 forward ? MAX (gst_byte_reader_get_remaining (&reader), 4) - 3 : 3;
1808 gst_buffer_unmap (buf, &map);
1809 gst_buffer_unref (buf);
1814 demux->common.offset = orig_offset;
1819 /* bisect and scan through file for cluster starting before @time,
1820 * returns fake index entry with corresponding info on cluster */
1821 static GstMatroskaIndex *
1822 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1824 GstMatroskaIndex *entry = NULL;
1825 GstMatroskaReadState current_state;
1826 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1828 gint64 opos, newpos, current_offset;
1829 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1830 gint64 apos, maxpos;
1831 guint64 cluster_size = 0;
1837 /* estimate new position, resync using cluster ebml id,
1838 * and bisect further or scan forward to appropriate cluster */
1840 /* store some current state */
1841 current_state = demux->common.state;
1842 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1844 current_cluster_offset = demux->cluster_offset;
1845 current_cluster_time = demux->cluster_time;
1846 current_offset = demux->common.offset;
1848 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1850 /* estimate using start and last known cluster */
1851 GST_OBJECT_LOCK (demux);
1852 apos = demux->first_cluster_offset;
1853 atime = demux->stream_start_time;
1854 opos = demux->last_cluster_offset;
1855 otime = demux->stream_last_time;
1856 GST_OBJECT_UNLOCK (demux);
1859 time = MAX (time, atime);
1860 otime = MAX (otime, atime);
1861 opos = MAX (opos, apos);
1863 maxpos = gst_matroska_read_common_get_length (&demux->common);
1868 * apos always refer to a cluster before target time;
1869 * opos may or may not be after target time, but if it is once so,
1870 * then also in next iteration
1874 GST_LOG_OBJECT (demux,
1875 "apos: %" G_GUINT64_FORMAT ", atime: %" GST_TIME_FORMAT ", %"
1876 GST_TIME_FORMAT " in stream time, "
1877 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1878 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1879 GST_TIME_FORMAT, apos, GST_TIME_ARGS (atime),
1880 GST_TIME_ARGS (atime - demux->stream_start_time), opos,
1881 GST_TIME_ARGS (otime), GST_TIME_ARGS (otime - demux->stream_start_time),
1882 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1884 g_assert (atime <= otime);
1885 g_assert (apos <= opos);
1886 if (time == GST_CLOCK_TIME_NONE) {
1887 GST_DEBUG_OBJECT (demux, "searching last cluster");
1890 GST_DEBUG_OBJECT (demux, "unknown file size; bailing out");
1893 } else if (otime <= atime) {
1897 gst_util_uint64_scale (opos - apos, time - atime, otime - atime);
1898 if (maxpos != -1 && newpos > maxpos)
1902 GST_DEBUG_OBJECT (demux,
1903 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1904 GST_TIME_ARGS (time), newpos);
1906 /* search backwards */
1907 if (newpos > apos) {
1908 ret = gst_matroska_demux_search_cluster (demux, &newpos, FALSE);
1909 if (ret != GST_FLOW_OK)
1913 /* then start scanning and parsing for cluster time,
1914 * re-estimate if possible, otherwise next cluster and so on */
1915 /* note that each re-estimate is entered with a change in apos or opos,
1916 * avoiding infinite loop */
1917 demux->common.offset = newpos;
1918 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1920 prev_cluster_time = GST_CLOCK_TIME_NONE;
1922 /* peek and parse some elements */
1923 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1924 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1925 if (ret != GST_FLOW_OK)
1927 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1928 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1930 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1931 if (ret != GST_FLOW_OK)
1934 if (id == GST_MATROSKA_ID_CLUSTER) {
1935 cluster_time = GST_CLOCK_TIME_NONE;
1936 if (length == G_MAXUINT64)
1939 cluster_size = length + needed;
1941 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1942 cluster_time == GST_CLOCK_TIME_NONE) {
1943 cluster_time = demux->cluster_time * demux->common.time_scale;
1944 cluster_offset = demux->cluster_offset;
1945 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1946 " with time %" GST_TIME_FORMAT, cluster_offset,
1947 GST_TIME_ARGS (cluster_time));
1948 if (time == GST_CLOCK_TIME_NONE) {
1949 GST_DEBUG_OBJECT (demux, "found last cluster");
1950 prev_cluster_time = cluster_time;
1951 prev_cluster_offset = cluster_offset;
1954 if (cluster_time > time) {
1955 GST_DEBUG_OBJECT (demux, "overshot target");
1956 /* cluster overshoots */
1957 if (cluster_offset == demux->first_cluster_offset) {
1958 /* but no prev one */
1959 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1960 prev_cluster_time = cluster_time;
1961 prev_cluster_offset = cluster_offset;
1964 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1965 /* prev cluster did not overshoot, so prev cluster is target */
1968 /* re-estimate using this new position info */
1969 opos = cluster_offset;
1970 otime = cluster_time;
1974 /* cluster undershoots */
1975 GST_DEBUG_OBJECT (demux, "undershot target");
1976 /* ok if close enough */
1977 if (GST_CLOCK_DIFF (cluster_time, time) < 5 * GST_SECOND) {
1978 GST_DEBUG_OBJECT (demux, "target close enough");
1979 prev_cluster_time = cluster_time;
1980 prev_cluster_offset = cluster_offset;
1984 /* we are in between atime and otime => can bisect if worthwhile */
1985 if (prev_cluster_time != GST_CLOCK_TIME_NONE &&
1986 cluster_time > prev_cluster_time &&
1987 (GST_CLOCK_DIFF (prev_cluster_time, cluster_time) * 10 <
1988 GST_CLOCK_DIFF (cluster_time, time))) {
1989 /* we moved at least one cluster forward,
1990 * and it looks like target is still far away,
1991 * let's estimate again */
1992 GST_DEBUG_OBJECT (demux, "bisecting with new apos");
1993 apos = cluster_offset;
1994 atime = cluster_time;
1998 /* cluster undershoots, goto next one */
1999 prev_cluster_time = cluster_time;
2000 prev_cluster_offset = cluster_offset;
2001 /* skip cluster if length is defined,
2002 * otherwise will be skippingly parsed into */
2004 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
2005 demux->common.offset = cluster_offset + cluster_size;
2006 demux->cluster_time = GST_CLOCK_TIME_NONE;
2008 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
2015 if (ret == GST_FLOW_EOS) {
2016 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
2022 entry = g_new0 (GstMatroskaIndex, 1);
2023 entry->time = prev_cluster_time;
2024 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
2025 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
2026 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
2030 /* restore some state */
2031 demux->cluster_offset = current_cluster_offset;
2032 demux->cluster_time = current_cluster_time;
2033 demux->common.offset = current_offset;
2034 demux->common.state = current_state;
2040 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
2041 GstPad * pad, GstEvent * event)
2043 GstMatroskaIndex *entry = NULL;
2044 GstMatroskaIndex scan_entry;
2046 GstSeekType cur_type, stop_type;
2048 gboolean flush, keyunit, before, after, snap_next;
2051 GstMatroskaTrackContext *track = NULL;
2052 GstSegment seeksegment = { 0, };
2053 gboolean update = TRUE;
2054 gboolean pad_locked = FALSE;
2056 GstSearchMode snap_dir;
2058 g_return_val_if_fail (event != NULL, FALSE);
2061 track = gst_pad_get_element_private (pad);
2063 GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
2065 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2067 seqnum = gst_event_get_seqnum (event);
2069 /* we can only seek on time */
2070 if (format != GST_FORMAT_TIME) {
2071 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2075 /* copy segment, we need this because we still need the old
2076 * segment when we close the current segment. */
2077 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
2079 /* pull mode without index means that the actual duration is not known,
2080 * we might be playing a file that's still being recorded
2081 * so, invalidate our current duration, which is only a moving target,
2082 * and should not be used to clamp anything */
2083 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
2084 seeksegment.duration = GST_CLOCK_TIME_NONE;
2087 GST_DEBUG_OBJECT (demux, "configuring seek");
2088 /* Subtract stream_start_time so we always seek on a segment
2090 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2091 seeksegment.start -= demux->stream_start_time;
2092 seeksegment.position -= demux->stream_start_time;
2093 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2094 seeksegment.stop -= demux->stream_start_time;
2096 seeksegment.stop = seeksegment.duration;
2099 gst_segment_do_seek (&seeksegment, rate, format, flags,
2100 cur_type, cur, stop_type, stop, &update);
2102 /* Restore the clip timestamp offset */
2103 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2104 seeksegment.position += demux->stream_start_time;
2105 seeksegment.start += demux->stream_start_time;
2106 if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2107 seeksegment.stop = seeksegment.duration;
2108 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2109 seeksegment.stop += demux->stream_start_time;
2112 /* restore segment duration (if any effect),
2113 * would be determined again when parsing, but anyway ... */
2114 seeksegment.duration = demux->common.segment.duration;
2116 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2117 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2118 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
2119 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
2121 /* always do full update if flushing,
2122 * otherwise problems might arise downstream with missing keyframes etc */
2123 update = update || flush;
2125 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2127 /* check sanity before we start flushing and all that */
2128 snap_next = after && !before;
2129 if (seeksegment.rate < 0)
2130 snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
2132 snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
2134 GST_OBJECT_LOCK (demux);
2135 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2136 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2137 seeksegment.position, &demux->seek_index, &demux->seek_entry,
2138 snap_dir)) == NULL) {
2139 /* pull mode without index can scan later on */
2140 if (demux->streaming) {
2141 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2142 GST_OBJECT_UNLOCK (demux);
2144 } else if (rate < 0.0) {
2145 /* FIXME: We should build an index during playback or when scanning
2146 * that can be used here. The reverse playback code requires seek_index
2147 * and seek_entry to be set!
2149 GST_DEBUG_OBJECT (demux,
2150 "No matching seek entry in index, needed for reverse playback");
2151 GST_OBJECT_UNLOCK (demux);
2155 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2156 GST_OBJECT_UNLOCK (demux);
2159 /* only have to update some segment,
2160 * but also still have to honour flush and so on */
2161 GST_DEBUG_OBJECT (demux, "... no update");
2162 /* bad goto, bad ... */
2166 if (demux->streaming)
2171 GstEvent *flush_event = gst_event_new_flush_start ();
2172 gst_event_set_seqnum (flush_event, seqnum);
2173 GST_DEBUG_OBJECT (demux, "Starting flush");
2174 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2175 gst_matroska_demux_send_event (demux, flush_event);
2177 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2178 gst_pad_pause_task (demux->common.sinkpad);
2182 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2187 /* now grab the stream lock so that streaming cannot continue, for
2188 * non flushing seeks when the element is in PAUSED this could block
2190 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2191 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2194 /* pull mode without index can do some scanning */
2195 if (!demux->streaming && !entry) {
2196 GstEvent *flush_event;
2198 /* need to stop flushing upstream as we need it next */
2200 flush_event = gst_event_new_flush_stop (TRUE);
2201 gst_event_set_seqnum (flush_event, seqnum);
2202 gst_pad_push_event (demux->common.sinkpad, flush_event);
2204 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2205 /* keep local copy */
2207 scan_entry = *entry;
2209 entry = &scan_entry;
2211 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2213 flush_event = gst_event_new_flush_stop (TRUE);
2214 gst_event_set_seqnum (flush_event, seqnum);
2215 gst_matroska_demux_send_event (demux, flush_event);
2222 if (keyunit && seeksegment.rate > 0) {
2223 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2224 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2225 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2226 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2227 seeksegment.position = seeksegment.start;
2228 seeksegment.time = seeksegment.start - demux->stream_start_time;
2229 } else if (keyunit) {
2230 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment stop from %"
2231 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2232 GST_TIME_ARGS (seeksegment.stop), GST_TIME_ARGS (entry->time));
2233 seeksegment.stop = MAX (entry->time, demux->stream_start_time);
2234 seeksegment.position = seeksegment.stop;
2237 if (demux->streaming) {
2238 GST_OBJECT_LOCK (demux);
2239 /* track real position we should start at */
2240 GST_DEBUG_OBJECT (demux, "storing segment start");
2241 demux->requested_seek_time = seeksegment.position;
2242 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2243 GST_OBJECT_UNLOCK (demux);
2244 /* need to seek to cluster start to pick up cluster time */
2245 /* upstream takes care of flushing and all that
2246 * ... and newsegment event handling takes care of the rest */
2247 return perform_seek_to_offset (demux, rate,
2248 entry->pos + demux->common.ebml_segment_start, seqnum, flags);
2253 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2254 gst_event_set_seqnum (flush_event, seqnum);
2255 GST_DEBUG_OBJECT (demux, "Stopping flush");
2256 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2257 gst_matroska_demux_send_event (demux, flush_event);
2260 GST_OBJECT_LOCK (demux);
2261 /* now update the real segment info */
2262 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2263 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2264 GST_OBJECT_UNLOCK (demux);
2266 /* update some (segment) state */
2267 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2270 /* notify start of new segment */
2271 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2274 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2275 GST_FORMAT_TIME, demux->common.segment.start);
2276 gst_message_set_seqnum (msg, seqnum);
2277 gst_element_post_message (GST_ELEMENT (demux), msg);
2280 GST_OBJECT_LOCK (demux);
2281 if (demux->new_segment)
2282 gst_event_unref (demux->new_segment);
2284 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2285 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2286 gst_event_set_seqnum (demux->new_segment, seqnum);
2287 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2288 demux->to_time = demux->common.segment.position;
2290 demux->to_time = GST_CLOCK_TIME_NONE;
2291 demux->segment_seqnum = seqnum;
2292 GST_OBJECT_UNLOCK (demux);
2294 /* restart our task since it might have been stopped when we did the
2296 gst_pad_start_task (demux->common.sinkpad,
2297 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2299 /* streaming can continue now */
2301 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2309 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2311 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2317 * Handle whether we can perform the seek event or if we have to let the chain
2318 * function handle seeks to build the seek indexes first.
2321 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2325 GstSeekType cur_type, stop_type;
2330 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2335 /* we can only seek on time */
2336 if (format != GST_FORMAT_TIME) {
2337 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2341 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2342 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2346 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2347 GST_DEBUG_OBJECT (demux,
2348 "Non-flushing seek not supported in streaming mode");
2352 if (flags & GST_SEEK_FLAG_SEGMENT) {
2353 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2357 /* check for having parsed index already */
2358 if (!demux->common.index_parsed) {
2359 gboolean building_index;
2362 if (!demux->index_offset) {
2363 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2367 GST_OBJECT_LOCK (demux);
2368 /* handle the seek event in the chain function */
2369 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2370 /* no more seek can be issued until state reset to _DATA */
2372 /* copy the event */
2373 if (demux->seek_event)
2374 gst_event_unref (demux->seek_event);
2375 demux->seek_event = gst_event_ref (event);
2377 /* set the building_index flag so that only one thread can setup the
2378 * structures for index seeking. */
2379 building_index = demux->building_index;
2380 if (!building_index) {
2381 demux->building_index = TRUE;
2382 offset = demux->index_offset;
2384 GST_OBJECT_UNLOCK (demux);
2386 if (!building_index) {
2387 /* seek to the first subindex or legacy index */
2388 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2389 return perform_seek_to_offset (demux, rate, offset,
2390 gst_event_get_seqnum (event), GST_SEEK_FLAG_NONE);
2393 /* well, we are handling it already */
2397 /* delegate to tweaked regular seek */
2398 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2402 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2405 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2406 gboolean res = TRUE;
2408 switch (GST_EVENT_TYPE (event)) {
2409 case GST_EVENT_SEEK:
2410 /* no seeking until we are (safely) ready */
2411 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2412 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2413 gst_event_unref (event);
2418 guint32 seqnum = gst_event_get_seqnum (event);
2419 if (seqnum == demux->segment_seqnum) {
2420 GST_LOG_OBJECT (pad,
2421 "Drop duplicated SEEK event seqnum %" G_GUINT32_FORMAT, seqnum);
2422 gst_event_unref (event);
2427 if (!demux->streaming)
2428 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2430 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2431 gst_event_unref (event);
2436 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2437 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2438 GstMatroskaTrackVideoContext *videocontext =
2439 (GstMatroskaTrackVideoContext *) context;
2441 GstClockTimeDiff diff;
2442 GstClockTime timestamp;
2444 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2446 GST_OBJECT_LOCK (demux);
2447 videocontext->earliest_time = timestamp + diff;
2448 GST_OBJECT_UNLOCK (demux);
2451 gst_event_unref (event);
2455 case GST_EVENT_TOC_SELECT:
2458 GstTocEntry *entry = NULL;
2459 GstEvent *seek_event;
2462 if (!demux->common.toc) {
2463 GST_DEBUG_OBJECT (demux, "no TOC to select");
2466 gst_event_parse_toc_select (event, &uid);
2468 GST_OBJECT_LOCK (demux);
2469 entry = gst_toc_find_entry (demux->common.toc, uid);
2470 if (entry == NULL) {
2471 GST_OBJECT_UNLOCK (demux);
2472 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2475 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2476 GST_OBJECT_UNLOCK (demux);
2477 seek_event = gst_event_new_seek (1.0,
2479 GST_SEEK_FLAG_FLUSH,
2480 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2481 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2482 gst_event_unref (seek_event);
2486 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2490 gst_event_unref (event);
2494 /* events we don't need to handle */
2495 case GST_EVENT_NAVIGATION:
2496 gst_event_unref (event);
2500 case GST_EVENT_LATENCY:
2502 res = gst_pad_push_event (demux->common.sinkpad, event);
2509 static GstFlowReturn
2510 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2512 GstFlowReturn ret = GST_FLOW_EOS;
2513 gboolean done = TRUE;
2516 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2517 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2520 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2522 if (!demux->seek_entry) {
2523 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2527 for (i = 0; i < demux->common.src->len; i++) {
2528 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2530 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2531 ", stream %d at %" GST_TIME_FORMAT,
2532 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2533 GST_TIME_ARGS (stream->from_time));
2534 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2535 if (stream->from_time > demux->common.segment.start) {
2536 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2540 /* nothing pushed for this stream;
2541 * likely seek entry did not start at keyframe, so all was skipped.
2542 * So we need an earlier entry */
2548 GstMatroskaIndex *entry;
2550 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2551 --demux->seek_entry);
2552 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2562 static GstFlowReturn
2563 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2565 GstFlowReturn ret = GST_FLOW_OK;
2568 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2570 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2571 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2575 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2576 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2580 /* one track within the "all-tracks" header */
2581 case GST_MATROSKA_ID_TRACKENTRY:
2582 ret = gst_matroska_demux_add_stream (demux, ebml);
2586 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2591 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2593 demux->tracks_parsed = TRUE;
2599 * Read signed/unsigned "EBML" numbers.
2600 * Return: number of bytes processed.
2604 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2606 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2614 while (read <= 8 && !(total & len_mask)) {
2621 if ((total &= (len_mask - 1)) == len_mask - 1)
2626 if (data[n] == 0xff)
2628 total = (total << 8) | data[n];
2632 if (read == num_ffs && total != 0)
2641 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2646 /* read as unsigned number first */
2647 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2651 if (unum == G_MAXUINT64)
2654 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2660 * Mostly used for subtitles. We add void filler data for each
2661 * lagging stream to make sure we don't deadlock.
2665 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2667 GstClockTime gap_threshold;
2670 GST_OBJECT_LOCK (demux);
2672 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2673 GST_TIME_ARGS (demux->common.segment.position));
2675 g_assert (demux->common.num_streams == demux->common.src->len);
2676 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2677 GstMatroskaTrackContext *context;
2679 context = g_ptr_array_index (demux->common.src, stream_nr);
2681 GST_LOG_OBJECT (demux,
2682 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2683 GST_TIME_ARGS (context->pos));
2685 /* Only send gap events on non-subtitle streams if lagging way behind.
2686 * The 0.5 second threshold for subtitle streams is also quite random. */
2687 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
2688 gap_threshold = GST_SECOND / 2;
2690 gap_threshold = 3 * GST_SECOND;
2692 /* Lag need only be considered if we have advanced into requested segment */
2693 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2694 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2695 demux->common.segment.position > demux->common.segment.start &&
2696 context->pos + gap_threshold < demux->common.segment.position) {
2699 guint64 start = context->pos;
2700 guint64 stop = demux->common.segment.position - gap_threshold;
2702 GST_DEBUG_OBJECT (demux,
2703 "Synchronizing stream %d with other by advancing time from %"
2704 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2705 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2707 context->pos = stop;
2709 event = gst_event_new_gap (start, stop - start);
2710 GST_OBJECT_UNLOCK (demux);
2711 gst_pad_push_event (context->pad, event);
2712 GST_OBJECT_LOCK (demux);
2716 GST_OBJECT_UNLOCK (demux);
2719 static GstFlowReturn
2720 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2721 GstMatroskaTrackContext * stream)
2723 GstFlowReturn ret = GST_FLOW_OK;
2726 num = gst_buffer_list_length (stream->stream_headers);
2727 for (i = 0; i < num; ++i) {
2730 buf = gst_buffer_list_get (stream->stream_headers, i);
2731 buf = gst_buffer_copy (buf);
2733 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2735 if (stream->set_discont) {
2736 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2737 stream->set_discont = FALSE;
2739 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2742 /* push out all headers in one go and use last flow return */
2743 ret = gst_pad_push (stream->pad, buf);
2746 /* don't need these any longer */
2747 gst_buffer_list_unref (stream->stream_headers);
2748 stream->stream_headers = NULL;
2751 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2757 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2758 GstMatroskaTrackContext * stream)
2762 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2764 if (!stream->codec_priv)
2767 /* ideally, VobSub private data should be parsed and stored more convenient
2768 * elsewhere, but for now, only interested in a small part */
2770 /* make sure we have terminating 0 */
2771 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2773 /* just locate and parse palette part */
2774 start = strstr (buf, "palette:");
2779 guint8 r, g, b, y, u, v;
2782 while (g_ascii_isspace (*start))
2784 for (i = 0; i < 16; i++) {
2785 if (sscanf (start, "%06x", &col) != 1)
2788 while ((*start == ',') || g_ascii_isspace (*start))
2790 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2791 r = (col >> 16) & 0xff;
2792 g = (col >> 8) & 0xff;
2794 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2796 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2797 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2798 clut[i] = (y << 16) | (u << 8) | v;
2801 /* got them all without problems; build and send event */
2805 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2806 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2807 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2808 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2809 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2810 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2811 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2812 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2813 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2814 G_TYPE_INT, clut[15], NULL);
2816 gst_pad_push_event (stream->pad,
2817 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2824 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2828 g_assert (demux->common.num_streams == demux->common.src->len);
2829 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2830 GstMatroskaTrackContext *stream;
2832 stream = g_ptr_array_index (demux->common.src, stream_nr);
2834 if (stream->send_stream_headers) {
2835 if (stream->stream_headers != NULL) {
2836 gst_matroska_demux_push_stream_headers (demux, stream);
2838 /* FIXME: perhaps we can just disable and skip this stream then */
2839 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2840 ("Failed to extract stream headers from codec private data"));
2842 stream->send_stream_headers = FALSE;
2845 if (stream->send_dvd_event) {
2846 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2847 /* FIXME: should we send this event again after (flushing) seek ? */
2848 stream->send_dvd_event = FALSE;
2854 static GstFlowReturn
2855 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2856 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2859 guint seq_header_len;
2860 guint32 header, tmp;
2862 if (stream->codec_state) {
2863 seq_header = stream->codec_state;
2864 seq_header_len = stream->codec_state_size;
2865 } else if (stream->codec_priv) {
2866 seq_header = stream->codec_priv;
2867 seq_header_len = stream->codec_priv_size;
2872 /* Sequence header only needed for keyframes */
2873 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2876 if (gst_buffer_get_size (*buf) < 4)
2879 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2880 header = GUINT32_FROM_BE (tmp);
2882 /* Sequence start code, if not found prepend */
2883 if (header != 0x000001b3) {
2886 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2888 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2891 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2892 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2893 gst_buffer_get_size (*buf));
2895 gst_buffer_unref (*buf);
2902 static GstFlowReturn
2903 gst_matroska_demux_add_wvpk_header (GstElement * element,
2904 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2906 GstMatroskaTrackAudioContext *audiocontext =
2907 (GstMatroskaTrackAudioContext *) stream;
2908 GstBuffer *newbuf = NULL;
2909 GstMapInfo map, outmap;
2910 guint8 *buf_data, *data;
2918 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2921 wvh.total_samples = -1;
2922 wvh.block_index = audiocontext->wvpk_block_index;
2924 if (audiocontext->channels <= 2) {
2925 guint32 block_samples, tmp;
2926 gsize size = gst_buffer_get_size (*buf);
2928 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2929 block_samples = GUINT32_FROM_LE (tmp);
2930 /* we need to reconstruct the header of the wavpack block */
2932 /* -20 because ck_size is the size of the wavpack block -8
2933 * and lace_size is the size of the wavpack block + 12
2934 * (the three guint32 of the header that already are in the buffer) */
2935 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2937 /* block_samples, flags and crc are already in the buffer */
2938 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2940 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2946 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2947 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2948 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2949 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2950 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2951 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2952 gst_buffer_unmap (newbuf, &outmap);
2954 /* Append data from buf: */
2955 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2956 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2958 gst_buffer_unref (*buf);
2960 audiocontext->wvpk_block_index += block_samples;
2962 guint8 *outdata = NULL;
2964 gsize buf_size, size, out_size = 0;
2965 guint32 block_samples, flags, crc, blocksize;
2967 gst_buffer_map (*buf, &map, GST_MAP_READ);
2968 buf_data = map.data;
2969 buf_size = map.size;
2972 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2973 gst_buffer_unmap (*buf, &map);
2974 return GST_FLOW_ERROR;
2980 block_samples = GST_READ_UINT32_LE (data);
2985 flags = GST_READ_UINT32_LE (data);
2988 crc = GST_READ_UINT32_LE (data);
2991 blocksize = GST_READ_UINT32_LE (data);
2995 if (blocksize == 0 || size < blocksize)
2998 g_assert ((newbuf == NULL) == (outdata == NULL));
3000 if (newbuf == NULL) {
3001 out_size = sizeof (Wavpack4Header) + blocksize;
3002 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
3004 gst_buffer_copy_into (newbuf, *buf,
3005 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
3008 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3009 outdata = outmap.data;
3011 gst_buffer_unmap (newbuf, &outmap);
3012 out_size += sizeof (Wavpack4Header) + blocksize;
3013 gst_buffer_set_size (newbuf, out_size);
3014 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3015 outdata = outmap.data;
3018 outdata[outpos] = 'w';
3019 outdata[outpos + 1] = 'v';
3020 outdata[outpos + 2] = 'p';
3021 outdata[outpos + 3] = 'k';
3024 GST_WRITE_UINT32_LE (outdata + outpos,
3025 blocksize + sizeof (Wavpack4Header) - 8);
3026 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
3027 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
3028 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
3029 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
3030 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
3031 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
3032 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
3033 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
3036 memmove (outdata + outpos, data, blocksize);
3037 outpos += blocksize;
3041 gst_buffer_unmap (*buf, &map);
3042 gst_buffer_unref (*buf);
3045 gst_buffer_unmap (newbuf, &outmap);
3048 audiocontext->wvpk_block_index += block_samples;
3054 static GstFlowReturn
3055 gst_matroska_demux_add_prores_header (GstElement * element,
3056 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3058 GstBuffer *newbuf = gst_buffer_new_allocate (NULL, 8, NULL);
3062 if (!gst_buffer_map (newbuf, &map, GST_MAP_WRITE)) {
3063 GST_ERROR ("Failed to map newly allocated buffer");
3064 return GST_FLOW_ERROR;
3067 frame_size = gst_buffer_get_size (*buf);
3069 GST_WRITE_UINT32_BE (map.data, frame_size);
3075 gst_buffer_unmap (newbuf, &map);
3076 *buf = gst_buffer_append (newbuf, *buf);
3081 /* @text must be null-terminated */
3083 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
3088 g_return_val_if_fail (text != NULL, FALSE);
3090 /* yes, this might all lead to false positives ... */
3091 tag = (gchar *) text;
3092 while ((tag = strchr (tag, '<'))) {
3094 if (*tag != '\0' && *(tag + 1) == '>') {
3095 /* some common convenience ones */
3096 /* maybe any character will do here ? */
3109 if (strstr (text, "<span"))
3115 static GstFlowReturn
3116 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
3117 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3119 GstMatroskaTrackSubtitleContext *sub_stream;
3120 const gchar *encoding;
3125 gboolean needs_unmap = TRUE;
3127 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3129 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
3132 /* The subtitle buffer we push out should not include a NUL terminator as
3133 * part of the data. */
3134 if (map.data[map.size - 1] == '\0') {
3135 gst_buffer_set_size (*buf, map.size - 1);
3136 gst_buffer_unmap (*buf, &map);
3137 gst_buffer_map (*buf, &map, GST_MAP_READ);
3140 if (!sub_stream->invalid_utf8) {
3141 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
3144 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
3145 " is not valid UTF-8, this is broken according to the matroska"
3146 " specification", stream->num);
3147 sub_stream->invalid_utf8 = TRUE;
3150 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3151 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3152 if (encoding == NULL || *encoding == '\0') {
3153 /* if local encoding is UTF-8 and no encoding specified
3154 * via the environment variable, assume ISO-8859-15 */
3155 if (g_get_charset (&encoding)) {
3156 encoding = "ISO-8859-15";
3161 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3162 (char *) "*", NULL, NULL, &err);
3165 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3166 encoding, err->message);
3170 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3171 encoding = "ISO-8859-15";
3173 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3174 encoding, (char *) "*", NULL, NULL, NULL);
3177 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3178 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3181 utf8 = g_strdup ("invalid subtitle");
3183 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3184 gst_buffer_unmap (*buf, &map);
3185 gst_buffer_copy_into (newbuf, *buf,
3186 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3188 gst_buffer_unref (*buf);
3191 gst_buffer_map (*buf, &map, GST_MAP_READ);
3195 if (sub_stream->check_markup) {
3196 /* caps claim markup text, so we need to escape text,
3197 * except if text is already markup and then needs no further escaping */
3198 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3199 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3201 if (!sub_stream->seen_markup_tag) {
3202 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3204 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3205 gst_buffer_unmap (*buf, &map);
3206 gst_buffer_copy_into (newbuf, *buf,
3207 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3208 GST_BUFFER_COPY_META, 0, -1);
3209 gst_buffer_unref (*buf);
3212 needs_unmap = FALSE;
3217 gst_buffer_unmap (*buf, &map);
3222 static GstFlowReturn
3223 gst_matroska_demux_check_aac (GstElement * element,
3224 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3229 gst_buffer_extract (*buf, 0, data, 2);
3230 size = gst_buffer_get_size (*buf);
3232 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3235 /* tss, ADTS data, remove codec_data
3236 * still assume it is at least parsed */
3237 stream->caps = gst_caps_make_writable (stream->caps);
3238 s = gst_caps_get_structure (stream->caps, 0);
3240 gst_structure_remove_field (s, "codec_data");
3241 gst_pad_set_caps (stream->pad, stream->caps);
3242 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3243 "new caps: %" GST_PTR_FORMAT, stream->caps);
3246 /* disable subsequent checking */
3247 stream->postprocess_frame = NULL;
3253 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3254 GstBuffer * buffer, gsize alignment)
3258 gst_buffer_map (buffer, &map, GST_MAP_READ);
3260 if (map.size < sizeof (guintptr)) {
3261 gst_buffer_unmap (buffer, &map);
3265 if (((guintptr) map.data) & (alignment - 1)) {
3266 GstBuffer *new_buffer;
3267 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3269 new_buffer = gst_buffer_new_allocate (NULL,
3270 gst_buffer_get_size (buffer), ¶ms);
3272 /* Copy data "by hand", so ensure alignment is kept: */
3273 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3275 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3276 GST_DEBUG_OBJECT (demux,
3277 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3280 gst_buffer_unmap (buffer, &map);
3281 gst_buffer_unref (buffer);
3286 gst_buffer_unmap (buffer, &map);
3290 static GstFlowReturn
3291 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3292 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3293 gboolean is_simpleblock)
3295 GstMatroskaTrackContext *stream = NULL;
3296 GstFlowReturn ret = GST_FLOW_OK;
3297 gboolean readblock = FALSE;
3299 guint64 block_duration = -1;
3300 gint64 block_discardpadding = 0;
3301 GstBuffer *buf = NULL;
3303 gint stream_num = -1, n, laces = 0;
3305 gint *lace_size = NULL;
3308 gint64 referenceblock = 0;
3310 GstClockTime buffer_timestamp;
3312 offset = gst_ebml_read_get_offset (ebml);
3314 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3315 if (!is_simpleblock) {
3316 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3320 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3324 /* one block inside the group. Note, block parsing is one
3325 * of the harder things, so this code is a bit complicated.
3326 * See http://www.matroska.org/ for documentation. */
3327 case GST_MATROSKA_ID_SIMPLEBLOCK:
3328 case GST_MATROSKA_ID_BLOCK:
3334 gst_buffer_unmap (buf, &map);
3335 gst_buffer_unref (buf);
3338 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3341 gst_buffer_map (buf, &map, GST_MAP_READ);
3345 /* first byte(s): blocknum */
3346 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3351 /* fetch stream from num */
3352 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3354 if (G_UNLIKELY (size < 3)) {
3355 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3356 /* non-fatal, try next block(group) */
3359 } else if (G_UNLIKELY (stream_num < 0 ||
3360 stream_num >= demux->common.num_streams)) {
3361 /* let's not give up on a stray invalid track number */
3362 GST_WARNING_OBJECT (demux,
3363 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3364 "; ignoring block", stream_num, num);
3368 stream = g_ptr_array_index (demux->common.src, stream_num);
3370 /* time (relative to cluster time) */
3371 time = ((gint16) GST_READ_UINT16_BE (data));
3374 flags = GST_READ_UINT8 (data);
3378 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3381 switch ((flags & 0x06) >> 1) {
3382 case 0x0: /* no lacing */
3384 lace_size = g_new (gint, 1);
3385 lace_size[0] = size;
3388 case 0x1: /* xiph lacing */
3389 case 0x2: /* fixed-size lacing */
3390 case 0x3: /* EBML lacing */
3392 goto invalid_lacing;
3393 laces = GST_READ_UINT8 (data) + 1;
3396 lace_size = g_new0 (gint, laces);
3398 switch ((flags & 0x06) >> 1) {
3399 case 0x1: /* xiph lacing */ {
3400 guint temp, total = 0;
3402 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3405 goto invalid_lacing;
3406 temp = GST_READ_UINT8 (data);
3407 lace_size[n] += temp;
3413 total += lace_size[n];
3415 lace_size[n] = size - total;
3419 case 0x2: /* fixed-size lacing */
3420 for (n = 0; n < laces; n++)
3421 lace_size[n] = size / laces;
3424 case 0x3: /* EBML lacing */ {
3427 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3431 total = lace_size[0] = num;
3432 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3436 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3440 lace_size[n] = lace_size[n - 1] + snum;
3441 total += lace_size[n];
3444 lace_size[n] = size - total;
3451 if (ret != GST_FLOW_OK)
3458 case GST_MATROSKA_ID_BLOCKDURATION:{
3459 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3460 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3465 case GST_MATROSKA_ID_DISCARDPADDING:{
3466 ret = gst_ebml_read_sint (ebml, &id, &block_discardpadding);
3467 GST_DEBUG_OBJECT (demux, "DiscardPadding: %" GST_STIME_FORMAT,
3468 GST_STIME_ARGS (block_discardpadding));
3472 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3473 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3474 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3479 case GST_MATROSKA_ID_CODECSTATE:{
3481 guint64 data_len = 0;
3484 gst_ebml_read_binary (ebml, &id, &data,
3485 &data_len)) != GST_FLOW_OK)
3488 if (G_UNLIKELY (stream == NULL)) {
3489 GST_WARNING_OBJECT (demux,
3490 "Unexpected CodecState subelement - ignoring");
3494 g_free (stream->codec_state);
3495 stream->codec_state = data;
3496 stream->codec_state_size = data_len;
3498 /* Decode if necessary */
3499 if (stream->encodings && stream->encodings->len > 0
3500 && stream->codec_state && stream->codec_state_size > 0) {
3501 if (!gst_matroska_decode_data (stream->encodings,
3502 &stream->codec_state, &stream->codec_state_size,
3503 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3504 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3508 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3509 stream->codec_state_size);
3514 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3518 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3519 case GST_MATROSKA_ID_BLOCKADDITIONS:
3520 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3521 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3522 case GST_MATROSKA_ID_SLICES:
3523 GST_DEBUG_OBJECT (demux,
3524 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3525 ret = gst_ebml_read_skip (ebml);
3533 /* reading a number or so could have failed */
3534 if (ret != GST_FLOW_OK)
3537 if (ret == GST_FLOW_OK && readblock) {
3538 gboolean invisible_frame = FALSE;
3539 gboolean delta_unit = FALSE;
3540 guint64 duration = 0;
3541 gint64 lace_time = 0;
3543 stream = g_ptr_array_index (demux->common.src, stream_num);
3545 if (cluster_time != GST_CLOCK_TIME_NONE) {
3546 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3547 * Drop unless the lace contains timestamp 0? */
3548 if (time < 0 && (-time) > cluster_time) {
3551 if (stream->timecodescale == 1.0)
3552 lace_time = (cluster_time + time) * demux->common.time_scale;
3555 gst_util_guint64_to_gdouble ((cluster_time + time) *
3556 demux->common.time_scale) * stream->timecodescale;
3559 lace_time = GST_CLOCK_TIME_NONE;
3562 /* need to refresh segment info ASAP */
3563 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3564 GstSegment *segment = &demux->common.segment;
3566 GstEvent *segment_event;
3568 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3569 demux->stream_start_time = lace_time;
3570 GST_DEBUG_OBJECT (demux,
3571 "Setting stream start time to %" GST_TIME_FORMAT,
3572 GST_TIME_ARGS (lace_time));
3574 clace_time = MAX (lace_time, demux->stream_start_time);
3575 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3576 demux->common.segment.position != 0) {
3577 GST_DEBUG_OBJECT (demux,
3578 "using stored seek position %" GST_TIME_FORMAT,
3579 GST_TIME_ARGS (demux->common.segment.position));
3580 clace_time = demux->common.segment.position;
3581 segment->position = GST_CLOCK_TIME_NONE;
3583 segment->start = clace_time;
3584 segment->stop = GST_CLOCK_TIME_NONE;
3585 segment->time = segment->start - demux->stream_start_time;
3586 segment->position = segment->start - demux->stream_start_time;
3587 GST_DEBUG_OBJECT (demux,
3588 "generated segment starting at %" GST_TIME_FORMAT ": %"
3589 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3590 /* now convey our segment notion downstream */
3591 segment_event = gst_event_new_segment (segment);
3592 if (demux->segment_seqnum)
3593 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3594 gst_matroska_demux_send_event (demux, segment_event);
3595 demux->need_segment = FALSE;
3596 demux->segment_seqnum = 0;
3599 /* send pending codec data headers for all streams,
3600 * before we perform sync across all streams */
3601 gst_matroska_demux_push_codec_data_all (demux);
3603 if (block_duration != -1) {
3604 if (stream->timecodescale == 1.0)
3605 duration = gst_util_uint64_scale (block_duration,
3606 demux->common.time_scale, 1);
3609 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3610 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3611 1)) * stream->timecodescale);
3612 } else if (stream->default_duration) {
3613 duration = stream->default_duration * laces;
3615 /* else duration is diff between timecode of this and next block */
3617 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3618 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3619 a ReferenceBlock implies that this is not a keyframe. In either
3620 case, it only makes sense for video streams. */
3621 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3623 invisible_frame = ((flags & 0x08)) &&
3624 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3625 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3628 /* If we're doing a keyframe-only trickmode, only push keyframes on video
3632 segment.flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) {
3633 GST_LOG_OBJECT (demux, "Skipping non-keyframe on stream %d",
3640 for (n = 0; n < laces; n++) {
3643 if (G_UNLIKELY (lace_size[n] > size)) {
3644 GST_WARNING_OBJECT (demux, "Invalid lace size");
3648 /* QoS for video track with an index. the assumption is that
3649 index entries point to keyframes, but if that is not true we
3650 will instad skip until the next keyframe. */
3651 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3652 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3653 stream->index_table && demux->common.segment.rate > 0.0) {
3654 GstMatroskaTrackVideoContext *videocontext =
3655 (GstMatroskaTrackVideoContext *) stream;
3656 GstClockTime earliest_time;
3657 GstClockTime earliest_stream_time;
3659 GST_OBJECT_LOCK (demux);
3660 earliest_time = videocontext->earliest_time;
3661 GST_OBJECT_UNLOCK (demux);
3662 earliest_stream_time =
3663 gst_segment_position_from_running_time (&demux->common.segment,
3664 GST_FORMAT_TIME, earliest_time);
3666 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3667 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3668 lace_time <= earliest_stream_time) {
3669 /* find index entry (keyframe) <= earliest_stream_time */
3670 GstMatroskaIndex *entry =
3671 gst_util_array_binary_search (stream->index_table->data,
3672 stream->index_table->len, sizeof (GstMatroskaIndex),
3673 (GCompareDataFunc) gst_matroska_index_seek_find,
3674 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3676 /* if that entry (keyframe) is after the current the current
3677 buffer, we can skip pushing (and thus decoding) all
3678 buffers until that keyframe. */
3679 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3680 entry->time > lace_time) {
3681 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3682 stream->set_discont = TRUE;
3688 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3689 gst_buffer_get_size (buf) - size, lace_size[n]);
3690 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3693 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3695 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3697 if (invisible_frame)
3698 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3700 if (stream->encodings != NULL && stream->encodings->len > 0)
3701 sub = gst_matroska_decode_buffer (stream, sub);
3704 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3708 if (!stream->dts_only) {
3709 GST_BUFFER_PTS (sub) = lace_time;
3711 GST_BUFFER_DTS (sub) = lace_time;
3712 if (stream->intra_only)
3713 GST_BUFFER_PTS (sub) = lace_time;
3716 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
3718 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3719 GstClockTime last_stop_end;
3721 /* Check if this stream is after segment stop */
3722 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3723 lace_time >= demux->common.segment.stop) {
3724 GST_DEBUG_OBJECT (demux,
3725 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3726 GST_TIME_ARGS (demux->common.segment.stop));
3727 gst_buffer_unref (sub);
3730 if (offset >= stream->to_offset
3731 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3732 && lace_time > demux->to_time)) {
3733 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3735 gst_buffer_unref (sub);
3739 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3740 * that landed us with timestamps not quite intended */
3741 GST_OBJECT_LOCK (demux);
3742 if (demux->max_gap_time &&
3743 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3744 demux->common.segment.rate > 0.0) {
3745 GstClockTimeDiff diff;
3747 /* only send segments with increasing start times,
3748 * otherwise if these go back and forth downstream (sinks) increase
3749 * accumulated time and running_time */
3750 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3751 if (diff > 0 && diff > demux->max_gap_time
3752 && lace_time > demux->common.segment.start
3753 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3754 || lace_time < demux->common.segment.stop)) {
3756 GST_DEBUG_OBJECT (demux,
3757 "Gap of %" G_GINT64_FORMAT " ns detected in"
3758 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3759 "Sending updated SEGMENT events", diff,
3760 stream->index, GST_TIME_ARGS (stream->pos),
3761 GST_TIME_ARGS (lace_time));
3763 event = gst_event_new_gap (demux->last_stop_end, diff);
3764 GST_OBJECT_UNLOCK (demux);
3765 gst_pad_push_event (stream->pad, event);
3766 GST_OBJECT_LOCK (demux);
3770 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3771 || demux->common.segment.position < lace_time) {
3772 demux->common.segment.position = lace_time;
3774 GST_OBJECT_UNLOCK (demux);
3776 last_stop_end = lace_time;
3778 GST_BUFFER_DURATION (sub) = duration / laces;
3779 last_stop_end += GST_BUFFER_DURATION (sub);
3782 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3783 demux->last_stop_end < last_stop_end)
3784 demux->last_stop_end = last_stop_end;
3786 GST_OBJECT_LOCK (demux);
3787 if (demux->common.segment.duration == -1 ||
3788 demux->stream_start_time + demux->common.segment.duration <
3790 demux->common.segment.duration =
3791 last_stop_end - demux->stream_start_time;
3792 GST_OBJECT_UNLOCK (demux);
3793 if (!demux->invalid_duration) {
3794 gst_element_post_message (GST_ELEMENT_CAST (demux),
3795 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3796 demux->invalid_duration = TRUE;
3799 GST_OBJECT_UNLOCK (demux);
3803 stream->pos = lace_time;
3805 gst_matroska_demux_sync_streams (demux);
3807 if (stream->set_discont) {
3808 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3809 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3810 stream->set_discont = FALSE;
3812 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3815 /* reverse playback book-keeping */
3816 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3817 stream->from_time = lace_time;
3818 if (stream->from_offset == -1)
3819 stream->from_offset = offset;
3821 GST_DEBUG_OBJECT (demux,
3822 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3823 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3824 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3825 GST_TIME_ARGS (buffer_timestamp),
3826 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3829 if (demux->common.element_index) {
3830 if (stream->index_writer_id == -1)
3831 gst_index_get_writer_id (demux->common.element_index,
3832 GST_OBJECT (stream->pad), &stream->index_writer_id);
3834 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3835 G_GUINT64_FORMAT " for writer id %d",
3836 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
3837 stream->index_writer_id);
3838 gst_index_add_association (demux->common.element_index,
3839 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3840 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3841 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
3846 /* Postprocess the buffers depending on the codec used */
3847 if (stream->postprocess_frame) {
3848 GST_LOG_OBJECT (demux, "running post process");
3849 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3852 /* At this point, we have a sub-buffer pointing at data within a larger
3853 buffer. This data might not be aligned with anything. If the data is
3854 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3855 for 32 bit samples, etc), or bad things will happen downstream as
3856 elements typically assume minimal alignment.
3857 Therefore, create an aligned copy if necessary. */
3858 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3860 if (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
3861 guint64 start_clip = 0, end_clip = 0;
3863 /* Codec delay is part of the timestamps */
3864 if (GST_BUFFER_PTS_IS_VALID (sub) && stream->codec_delay) {
3865 if (GST_BUFFER_PTS (sub) > stream->codec_delay) {
3866 GST_BUFFER_PTS (sub) -= stream->codec_delay;
3868 GST_BUFFER_PTS (sub) = 0;
3870 gst_util_uint64_scale_round (stream->codec_delay, 48000,
3873 if (GST_BUFFER_DURATION_IS_VALID (sub)) {
3874 if (GST_BUFFER_DURATION (sub) > stream->codec_delay)
3875 GST_BUFFER_DURATION (sub) -= stream->codec_delay;
3877 GST_BUFFER_DURATION (sub) = 0;
3882 if (block_discardpadding) {
3884 gst_util_uint64_scale_round (block_discardpadding, 48000,
3888 if (start_clip || end_clip) {
3889 gst_buffer_add_audio_clipping_meta (sub, GST_FORMAT_DEFAULT,
3890 start_clip, end_clip);
3894 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3895 stream->pos = GST_BUFFER_PTS (sub);
3896 if (GST_BUFFER_DURATION_IS_VALID (sub))
3897 stream->pos += GST_BUFFER_DURATION (sub);
3898 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
3899 stream->pos = GST_BUFFER_DTS (sub);
3900 if (GST_BUFFER_DURATION_IS_VALID (sub))
3901 stream->pos += GST_BUFFER_DURATION (sub);
3904 ret = gst_pad_push (stream->pad, sub);
3906 if (demux->common.segment.rate < 0) {
3907 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3908 /* In reverse playback we can get a GST_FLOW_EOS when
3909 * we are at the end of the segment, so we just need to jump
3910 * back to the previous section. */
3911 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3916 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
3920 size -= lace_size[n];
3921 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3922 lace_time += duration / laces;
3924 lace_time = GST_CLOCK_TIME_NONE;
3930 gst_buffer_unmap (buf, &map);
3931 gst_buffer_unref (buf);
3943 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
3949 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3950 /* non-fatal, try next block(group) */
3956 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3957 /* non-fatal, try next block(group) */
3963 /* return FALSE if block(group) should be skipped (due to a seek) */
3964 static inline gboolean
3965 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3967 if (G_UNLIKELY (demux->seek_block)) {
3968 if (!(--demux->seek_block)) {
3971 GST_LOG_OBJECT (demux, "should skip block due to seek");
3979 static GstFlowReturn
3980 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3984 guint64 seek_pos = (guint64) - 1;
3985 guint32 seek_id = 0;
3988 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3990 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3991 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3995 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3996 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4000 case GST_MATROSKA_ID_SEEKID:
4004 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4007 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
4012 case GST_MATROSKA_ID_SEEKPOSITION:
4016 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4019 if (t > G_MAXINT64) {
4020 GST_WARNING_OBJECT (demux,
4021 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
4025 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
4031 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
4037 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
4040 if (!seek_id || seek_pos == (guint64) - 1) {
4041 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
4042 G_GUINT64_FORMAT ")", seek_id, seek_pos);
4047 case GST_MATROSKA_ID_SEEKHEAD:
4050 case GST_MATROSKA_ID_CUES:
4051 case GST_MATROSKA_ID_TAGS:
4052 case GST_MATROSKA_ID_TRACKS:
4053 case GST_MATROSKA_ID_SEGMENTINFO:
4054 case GST_MATROSKA_ID_ATTACHMENTS:
4055 case GST_MATROSKA_ID_CHAPTERS:
4057 guint64 before_pos, length;
4061 length = gst_matroska_read_common_get_length (&demux->common);
4062 before_pos = demux->common.offset;
4064 if (length == (guint64) - 1) {
4065 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
4069 /* check for validity */
4070 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
4071 GST_WARNING_OBJECT (demux,
4072 "SeekHead reference lies outside file!" " (%"
4073 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
4074 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
4079 /* only pick up index location when streaming */
4080 if (demux->streaming) {
4081 if (seek_id == GST_MATROSKA_ID_CUES) {
4082 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
4083 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
4084 demux->index_offset);
4090 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
4093 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4094 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
4098 if (id != seek_id) {
4099 GST_WARNING_OBJECT (demux,
4100 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
4101 seek_id, id, seek_pos + demux->common.ebml_segment_start);
4104 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4109 demux->common.offset = before_pos;
4113 case GST_MATROSKA_ID_CLUSTER:
4115 guint64 pos = seek_pos + demux->common.ebml_segment_start;
4117 GST_LOG_OBJECT (demux, "Cluster position");
4118 if (G_UNLIKELY (!demux->clusters))
4119 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
4120 g_array_append_val (demux->clusters, pos);
4125 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
4128 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4133 static GstFlowReturn
4134 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4136 GstFlowReturn ret = GST_FLOW_OK;
4139 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4141 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4142 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4146 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4147 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4151 case GST_MATROSKA_ID_SEEKENTRY:
4153 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
4154 /* Ignore EOS and errors here */
4155 if (ret != GST_FLOW_OK) {
4156 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4163 ret = gst_matroska_read_common_parse_skip (&demux->common,
4164 ebml, "SeekHead", id);
4169 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4171 /* Sort clusters by position for easier searching */
4172 if (demux->clusters)
4173 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4178 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
4180 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4182 static inline GstFlowReturn
4183 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4185 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4186 /* only a few blocks are expected/allowed to be large,
4187 * and will be recursed into, whereas others will be read and must fit */
4188 if (demux->streaming) {
4189 /* fatal in streaming case, as we can't step over easily */
4190 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4191 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4192 "file might be corrupt.", bytes));
4193 return GST_FLOW_ERROR;
4195 /* indicate higher level to quietly give up */
4196 GST_DEBUG_OBJECT (demux,
4197 "too large block of size %" G_GUINT64_FORMAT, bytes);
4198 return GST_FLOW_ERROR;
4205 /* returns TRUE if we truely are in error state, and should give up */
4206 static inline GstFlowReturn
4207 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4209 if (!demux->streaming && demux->next_cluster_offset > 0) {
4210 /* just repositioning to where next cluster should be and try from there */
4211 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4212 G_GUINT64_FORMAT, demux->next_cluster_offset);
4213 demux->common.offset = demux->next_cluster_offset;
4214 demux->next_cluster_offset = 0;
4220 /* sigh, one last attempt above and beyond call of duty ...;
4221 * search for cluster mark following current pos */
4222 pos = demux->common.offset;
4223 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4224 if ((ret = gst_matroska_demux_search_cluster (demux, &pos, TRUE)) !=
4226 /* did not work, give up */
4229 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4230 /* try that position */
4231 demux->common.offset = pos;
4237 static inline GstFlowReturn
4238 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4240 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4241 demux->common.offset += flush;
4242 if (demux->streaming) {
4245 /* hard to skip large blocks when streaming */
4246 ret = gst_matroska_demux_check_read_size (demux, flush);
4247 if (ret != GST_FLOW_OK)
4249 if (flush <= gst_adapter_available (demux->common.adapter))
4250 gst_adapter_flush (demux->common.adapter, flush);
4252 return GST_FLOW_EOS;
4257 /* initializes @ebml with @bytes from input stream at current offset.
4258 * Returns EOS if insufficient available,
4259 * ERROR if too much was attempted to read. */
4260 static inline GstFlowReturn
4261 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4264 GstBuffer *buffer = NULL;
4265 GstFlowReturn ret = GST_FLOW_OK;
4267 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4269 ret = gst_matroska_demux_check_read_size (demux, bytes);
4270 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4271 if (!demux->streaming) {
4272 /* in pull mode, we can skip */
4273 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4274 ret = GST_FLOW_OVERFLOW;
4276 /* otherwise fatal */
4277 ret = GST_FLOW_ERROR;
4281 if (demux->streaming) {
4282 if (gst_adapter_available (demux->common.adapter) >= bytes)
4283 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4287 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4288 demux->common.offset, bytes, &buffer, NULL);
4289 if (G_LIKELY (buffer)) {
4290 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4291 demux->common.offset);
4292 demux->common.offset += bytes;
4299 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4302 gboolean seekable = FALSE;
4303 gint64 start = -1, stop = -1;
4305 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4306 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4307 GST_DEBUG_OBJECT (demux, "seeking query failed");
4311 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4313 /* try harder to query upstream size if we didn't get it the first time */
4314 if (seekable && stop == -1) {
4315 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4316 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4320 /* if upstream doesn't know the size, it's likely that it's not seekable in
4321 * practice even if it technically may be seekable */
4322 if (seekable && (start != 0 || stop <= start)) {
4323 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4328 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4329 G_GUINT64_FORMAT ")", seekable, start, stop);
4330 demux->seekable = seekable;
4332 gst_query_unref (query);
4335 static GstFlowReturn
4336 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4342 GstFlowReturn ret = GST_FLOW_OK;
4344 GST_WARNING_OBJECT (demux,
4345 "Found Cluster element before Tracks, searching Tracks");
4348 before_pos = demux->common.offset;
4350 /* Search Tracks element */
4352 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4353 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4354 if (ret != GST_FLOW_OK)
4357 if (id != GST_MATROSKA_ID_TRACKS) {
4358 /* we may be skipping large cluster here, so forego size check etc */
4359 /* ... but we can't skip undefined size; force error */
4360 if (length == G_MAXUINT64) {
4361 ret = gst_matroska_demux_check_read_size (demux, length);
4364 demux->common.offset += needed;
4365 demux->common.offset += length;
4370 /* will lead to track parsing ... */
4371 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4376 demux->common.offset = before_pos;
4381 #define GST_READ_CHECK(stmt) \
4383 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4384 if (ret == GST_FLOW_OVERFLOW) { \
4385 ret = GST_FLOW_OK; \
4391 static GstFlowReturn
4392 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4393 guint64 length, guint needed)
4395 GstEbmlRead ebml = { 0, };
4396 GstFlowReturn ret = GST_FLOW_OK;
4399 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4400 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4402 /* if we plan to read and parse this element, we need prefix (id + length)
4403 * and the contents */
4404 /* mind about overflow wrap-around when dealing with undefined size */
4406 if (G_LIKELY (length != G_MAXUINT64))
4409 switch (demux->common.state) {
4410 case GST_MATROSKA_READ_STATE_START:
4412 case GST_EBML_ID_HEADER:
4413 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4414 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4415 if (ret != GST_FLOW_OK)
4417 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4418 gst_matroska_demux_check_seekability (demux);
4421 goto invalid_header;
4425 case GST_MATROSKA_READ_STATE_SEGMENT:
4427 case GST_MATROSKA_ID_SEGMENT:
4428 /* eat segment prefix */
4429 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4430 GST_DEBUG_OBJECT (demux,
4431 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4432 G_GUINT64_FORMAT, demux->common.offset, length);
4433 /* seeks are from the beginning of the segment,
4434 * after the segment ID/length */
4435 demux->common.ebml_segment_start = demux->common.offset;
4437 length = G_MAXUINT64;
4438 demux->common.ebml_segment_length = length;
4439 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4442 GST_WARNING_OBJECT (demux,
4443 "Expected a Segment ID (0x%x), but received 0x%x!",
4444 GST_MATROSKA_ID_SEGMENT, id);
4445 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4449 case GST_MATROSKA_READ_STATE_SCANNING:
4450 if (id != GST_MATROSKA_ID_CLUSTER &&
4451 id != GST_MATROSKA_ID_CLUSTERTIMECODE) {
4452 if (demux->common.start_resync_offset != -1) {
4453 /* we need to skip byte per byte if we are scanning for a new cluster
4454 * after invalid data is found
4460 if (demux->common.start_resync_offset != -1) {
4461 GST_LOG_OBJECT (demux, "Resync done, new cluster found!");
4462 demux->common.start_resync_offset = -1;
4463 demux->common.state = demux->common.state_to_restore;
4467 case GST_MATROSKA_READ_STATE_HEADER:
4468 case GST_MATROSKA_READ_STATE_DATA:
4469 case GST_MATROSKA_READ_STATE_SEEK:
4471 case GST_MATROSKA_ID_SEGMENTINFO:
4472 if (!demux->common.segmentinfo_parsed) {
4473 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4474 ret = gst_matroska_read_common_parse_info (&demux->common,
4475 GST_ELEMENT_CAST (demux), &ebml);
4476 if (ret == GST_FLOW_OK)
4477 gst_matroska_demux_send_tags (demux);
4479 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4482 case GST_MATROSKA_ID_TRACKS:
4483 if (!demux->tracks_parsed) {
4484 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4485 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4487 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4490 case GST_MATROSKA_ID_CLUSTER:
4491 if (G_UNLIKELY (!demux->tracks_parsed)) {
4492 if (demux->streaming) {
4493 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4494 goto not_streamable;
4496 ret = gst_matroska_demux_find_tracks (demux);
4497 if (!demux->tracks_parsed)
4501 if (G_UNLIKELY (demux->common.state
4502 == GST_MATROSKA_READ_STATE_HEADER)) {
4503 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4504 demux->first_cluster_offset = demux->common.offset;
4505 if (!demux->streaming &&
4506 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.duration)) {
4507 GstMatroskaIndex *last = NULL;
4509 GST_DEBUG_OBJECT (demux,
4510 "estimating duration using last cluster");
4511 if ((last = gst_matroska_demux_search_pos (demux,
4512 GST_CLOCK_TIME_NONE)) != NULL) {
4513 demux->last_cluster_offset =
4514 last->pos + demux->common.ebml_segment_start;
4515 demux->stream_last_time = last->time;
4516 demux->common.segment.duration =
4517 demux->stream_last_time - demux->stream_start_time;
4518 /* above estimate should not be taken all too strongly */
4519 demux->invalid_duration = TRUE;
4520 GST_DEBUG_OBJECT (demux,
4521 "estimated duration as %" GST_TIME_FORMAT,
4522 GST_TIME_ARGS (demux->common.segment.duration));
4525 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4526 gst_element_no_more_pads (GST_ELEMENT (demux));
4527 /* send initial segment - we wait till we know the first
4528 incoming timestamp, so we can properly set the start of
4530 demux->need_segment = TRUE;
4532 demux->cluster_time = GST_CLOCK_TIME_NONE;
4533 demux->cluster_offset = demux->common.offset;
4534 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4535 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4536 " not found in Cluster, trying next Cluster's first block instead",
4538 demux->seek_block = 0;
4540 demux->seek_first = FALSE;
4541 /* record next cluster for recovery */
4542 if (read != G_MAXUINT64)
4543 demux->next_cluster_offset = demux->cluster_offset + read;
4544 /* eat cluster prefix */
4545 gst_matroska_demux_flush (demux, needed);
4547 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4551 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4552 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4554 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4555 demux->cluster_time = num;
4556 /* track last cluster */
4557 if (demux->cluster_offset > demux->last_cluster_offset) {
4558 demux->last_cluster_offset = demux->cluster_offset;
4559 demux->stream_last_time =
4560 demux->cluster_time * demux->common.time_scale;
4563 if (demux->common.element_index) {
4564 if (demux->common.element_index_writer_id == -1)
4565 gst_index_get_writer_id (demux->common.element_index,
4566 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4567 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4568 G_GUINT64_FORMAT " for writer id %d",
4569 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4570 demux->common.element_index_writer_id);
4571 gst_index_add_association (demux->common.element_index,
4572 demux->common.element_index_writer_id,
4573 GST_ASSOCIATION_FLAG_KEY_UNIT,
4574 GST_FORMAT_TIME, demux->cluster_time,
4575 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4580 case GST_MATROSKA_ID_BLOCKGROUP:
4581 if (!gst_matroska_demux_seek_block (demux))
4583 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4584 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4585 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4586 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4587 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4589 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4591 case GST_MATROSKA_ID_SIMPLEBLOCK:
4592 if (!gst_matroska_demux_seek_block (demux))
4594 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4595 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4596 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4597 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4598 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4600 case GST_MATROSKA_ID_ATTACHMENTS:
4601 if (!demux->common.attachments_parsed) {
4602 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4603 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4604 GST_ELEMENT_CAST (demux), &ebml);
4605 if (ret == GST_FLOW_OK)
4606 gst_matroska_demux_send_tags (demux);
4608 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4611 case GST_MATROSKA_ID_TAGS:
4612 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4613 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4614 GST_ELEMENT_CAST (demux), &ebml);
4615 if (ret == GST_FLOW_OK)
4616 gst_matroska_demux_send_tags (demux);
4618 case GST_MATROSKA_ID_CHAPTERS:
4619 if (!demux->common.chapters_parsed) {
4620 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4622 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4624 if (demux->common.toc) {
4625 gst_matroska_demux_send_event (demux,
4626 gst_event_new_toc (demux->common.toc, FALSE));
4629 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4631 case GST_MATROSKA_ID_SEEKHEAD:
4632 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4633 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4635 case GST_MATROSKA_ID_CUES:
4636 if (demux->common.index_parsed) {
4637 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4640 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4641 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4642 /* only push based; delayed index building */
4643 if (ret == GST_FLOW_OK
4644 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4647 GST_OBJECT_LOCK (demux);
4648 event = demux->seek_event;
4649 demux->seek_event = NULL;
4650 GST_OBJECT_UNLOCK (demux);
4653 /* unlikely to fail, since we managed to seek to this point */
4654 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
4655 gst_event_unref (event);
4658 gst_event_unref (event);
4659 /* resume data handling, main thread clear to seek again */
4660 GST_OBJECT_LOCK (demux);
4661 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4662 GST_OBJECT_UNLOCK (demux);
4665 case GST_MATROSKA_ID_POSITION:
4666 case GST_MATROSKA_ID_PREVSIZE:
4667 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4668 case GST_MATROSKA_ID_SILENTTRACKS:
4669 GST_DEBUG_OBJECT (demux,
4670 "Skipping Cluster subelement 0x%x - ignoring", id);
4674 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4675 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4681 if (ret == GST_FLOW_PARSE)
4685 gst_ebml_read_clear (&ebml);
4691 /* simply exit, maybe not enough data yet */
4692 /* no ebml to clear if read error */
4697 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4698 ("Failed to parse Element 0x%x", id));
4699 ret = GST_FLOW_ERROR;
4704 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4705 ("File layout does not permit streaming"));
4706 ret = GST_FLOW_ERROR;
4711 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4712 ("No Tracks element found"));
4713 ret = GST_FLOW_ERROR;
4718 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4719 ret = GST_FLOW_ERROR;
4724 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4725 ret = GST_FLOW_ERROR;
4731 gst_matroska_demux_loop (GstPad * pad)
4733 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4739 /* If we have to close a segment, send a new segment to do this now */
4740 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4741 if (G_UNLIKELY (demux->new_segment)) {
4742 gst_matroska_demux_send_event (demux, demux->new_segment);
4743 demux->new_segment = NULL;
4747 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4748 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4749 if (ret == GST_FLOW_EOS) {
4751 } else if (ret == GST_FLOW_FLUSHING) {
4753 } else if (ret != GST_FLOW_OK) {
4754 ret = gst_matroska_demux_check_parse_error (demux);
4756 /* Only handle EOS as no error if we're outside the segment already */
4757 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4758 && demux->common.offset >=
4759 demux->common.ebml_segment_start +
4760 demux->common.ebml_segment_length))
4762 else if (ret != GST_FLOW_OK)
4768 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4769 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4772 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4773 if (ret == GST_FLOW_EOS)
4775 if (ret != GST_FLOW_OK)
4778 /* check if we're at the end of a configured segment */
4779 if (G_LIKELY (demux->common.src->len)) {
4782 g_assert (demux->common.num_streams == demux->common.src->len);
4783 for (i = 0; i < demux->common.src->len; i++) {
4784 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4786 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4787 GST_TIME_ARGS (context->pos));
4788 if (context->eos == FALSE)
4792 GST_INFO_OBJECT (demux, "All streams are EOS");
4798 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4799 demux->common.offset >= demux->cached_length)) {
4800 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4801 if (demux->common.offset == demux->cached_length) {
4802 GST_LOG_OBJECT (demux, "Reached end of stream");
4813 if (demux->common.segment.rate < 0.0) {
4814 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4815 if (ret == GST_FLOW_OK)
4822 const gchar *reason = gst_flow_get_name (ret);
4823 gboolean push_eos = FALSE;
4825 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4826 gst_pad_pause_task (demux->common.sinkpad);
4828 if (ret == GST_FLOW_EOS) {
4829 /* perform EOS logic */
4831 /* If we were in the headers, make sure we send no-more-pads.
4832 This will ensure decodebin does not get stuck thinking
4833 the chain is not complete yet, and waiting indefinitely. */
4834 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4835 if (demux->common.src->len == 0) {
4836 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4837 ("No pads created"));
4839 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4840 ("Failed to finish reading headers"));
4842 gst_element_no_more_pads (GST_ELEMENT (demux));
4845 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4850 /* for segment playback we need to post when (in stream time)
4851 * we stopped, this is either stop (when set) or the duration. */
4852 if ((stop = demux->common.segment.stop) == -1)
4853 stop = demux->last_stop_end;
4855 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4856 msg = gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4858 if (demux->segment_seqnum)
4859 gst_message_set_seqnum (msg, demux->segment_seqnum);
4860 gst_element_post_message (GST_ELEMENT (demux), msg);
4862 event = gst_event_new_segment_done (GST_FORMAT_TIME, stop);
4863 if (demux->segment_seqnum)
4864 gst_event_set_seqnum (event, demux->segment_seqnum);
4865 gst_matroska_demux_send_event (demux, event);
4869 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4870 /* for fatal errors we post an error message */
4871 GST_ELEMENT_FLOW_ERROR (demux, ret);
4877 /* send EOS, and prevent hanging if no streams yet */
4878 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4879 event = gst_event_new_eos ();
4880 if (demux->segment_seqnum)
4881 gst_event_set_seqnum (event, demux->segment_seqnum);
4882 if (!gst_matroska_demux_send_event (demux, event) &&
4883 (ret == GST_FLOW_EOS)) {
4884 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4885 (NULL), ("got eos but no streams (yet)"));
4893 * Create and push a flushing seek event upstream
4896 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4897 guint32 seqnum, GstSeekFlags flags)
4902 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4905 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4906 flags | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
4907 GST_SEEK_TYPE_SET, offset, GST_SEEK_TYPE_NONE, -1);
4908 gst_event_set_seqnum (event, seqnum);
4910 res = gst_pad_push_event (demux->common.sinkpad, event);
4912 /* segment event will update offset */
4916 static GstFlowReturn
4917 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4919 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4921 GstFlowReturn ret = GST_FLOW_OK;
4926 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4927 GST_DEBUG_OBJECT (demux, "got DISCONT");
4928 gst_adapter_clear (demux->common.adapter);
4929 GST_OBJECT_LOCK (demux);
4930 gst_matroska_read_common_reset_streams (&demux->common,
4931 GST_CLOCK_TIME_NONE, FALSE);
4932 GST_OBJECT_UNLOCK (demux);
4935 gst_adapter_push (demux->common.adapter, buffer);
4939 available = gst_adapter_available (demux->common.adapter);
4941 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4942 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4943 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4944 if (demux->common.ebml_segment_length != G_MAXUINT64
4945 && demux->common.offset >=
4946 demux->common.ebml_segment_start + demux->common.ebml_segment_length) {
4949 gint64 bytes_scanned;
4950 if (demux->common.start_resync_offset == -1) {
4951 demux->common.start_resync_offset = demux->common.offset;
4952 demux->common.state_to_restore = demux->common.state;
4954 bytes_scanned = demux->common.offset - demux->common.start_resync_offset;
4955 if (bytes_scanned <= INVALID_DATA_THRESHOLD) {
4956 GST_WARNING_OBJECT (demux,
4957 "parse error, looking for next cluster, actual offset %"
4958 G_GUINT64_FORMAT ", start resync offset %" G_GUINT64_FORMAT,
4959 demux->common.offset, demux->common.start_resync_offset);
4960 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
4963 GST_WARNING_OBJECT (demux,
4964 "unrecoverable parse error, next cluster not found and threshold "
4965 "exceeded, bytes scanned %" G_GINT64_FORMAT, bytes_scanned);
4971 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4972 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4973 demux->common.offset, id, length, needed, available);
4975 if (needed > available)
4978 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4979 if (ret == GST_FLOW_EOS) {
4980 /* need more data */
4982 } else if (ret != GST_FLOW_OK) {
4989 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4992 gboolean res = TRUE;
4993 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4995 GST_DEBUG_OBJECT (demux,
4996 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4998 switch (GST_EVENT_TYPE (event)) {
4999 case GST_EVENT_SEGMENT:
5001 const GstSegment *segment;
5003 /* some debug output */
5004 gst_event_parse_segment (event, &segment);
5005 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
5006 GST_DEBUG_OBJECT (demux,
5007 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
5010 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
5011 GST_DEBUG_OBJECT (demux, "still starting");
5015 /* we only expect a BYTE segment, e.g. following a seek */
5016 if (segment->format != GST_FORMAT_BYTES) {
5017 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
5021 GST_DEBUG_OBJECT (demux, "clearing segment state");
5022 GST_OBJECT_LOCK (demux);
5023 /* clear current segment leftover */
5024 gst_adapter_clear (demux->common.adapter);
5025 /* and some streaming setup */
5026 demux->common.offset = segment->start;
5027 /* accumulate base based on current position */
5028 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
5029 demux->common.segment.base +=
5030 (MAX (demux->common.segment.position, demux->stream_start_time)
5031 - demux->stream_start_time) / fabs (demux->common.segment.rate);
5032 /* do not know where we are;
5033 * need to come across a cluster and generate segment */
5034 demux->common.segment.position = GST_CLOCK_TIME_NONE;
5035 demux->cluster_time = GST_CLOCK_TIME_NONE;
5036 demux->cluster_offset = 0;
5037 demux->need_segment = TRUE;
5038 demux->segment_seqnum = gst_event_get_seqnum (event);
5039 /* but keep some of the upstream segment */
5040 demux->common.segment.rate = segment->rate;
5041 demux->common.segment.flags = segment->flags;
5042 /* also check if need to keep some of the requested seek position */
5043 if (demux->seek_offset == segment->start) {
5044 GST_DEBUG_OBJECT (demux, "position matches requested seek");
5045 demux->common.segment.position = demux->requested_seek_time;
5047 GST_DEBUG_OBJECT (demux, "unexpected segment position");
5049 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
5050 demux->seek_offset = -1;
5051 GST_OBJECT_UNLOCK (demux);
5053 /* chain will send initial segment after pads have been added,
5054 * or otherwise come up with one */
5055 GST_DEBUG_OBJECT (demux, "eating event");
5056 gst_event_unref (event);
5062 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA
5063 && demux->common.state != GST_MATROSKA_READ_STATE_SCANNING) {
5064 gst_event_unref (event);
5065 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5066 (NULL), ("got eos and didn't receive a complete header object"));
5067 } else if (demux->common.num_streams == 0) {
5068 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5069 (NULL), ("got eos but no streams (yet)"));
5071 gst_matroska_demux_send_event (demux, event);
5075 case GST_EVENT_FLUSH_STOP:
5079 gst_adapter_clear (demux->common.adapter);
5080 GST_OBJECT_LOCK (demux);
5081 gst_matroska_read_common_reset_streams (&demux->common,
5082 GST_CLOCK_TIME_NONE, TRUE);
5083 gst_flow_combiner_reset (demux->flowcombiner);
5084 dur = demux->common.segment.duration;
5085 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
5086 demux->common.segment.duration = dur;
5087 demux->cluster_time = GST_CLOCK_TIME_NONE;
5088 demux->cluster_offset = 0;
5089 GST_OBJECT_UNLOCK (demux);
5093 res = gst_pad_event_default (pad, parent, event);
5101 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
5103 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5105 gboolean pull_mode = FALSE;
5107 query = gst_query_new_scheduling ();
5109 if (gst_pad_peer_query (sinkpad, query))
5110 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
5111 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
5113 gst_query_unref (query);
5116 GST_DEBUG ("going to pull mode");
5117 demux->streaming = FALSE;
5118 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
5120 GST_DEBUG ("going to push (streaming) mode");
5121 demux->streaming = TRUE;
5122 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
5127 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
5128 GstPadMode mode, gboolean active)
5131 case GST_PAD_MODE_PULL:
5133 /* if we have a scheduler we can start the task */
5134 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
5137 gst_pad_stop_task (sinkpad);
5140 case GST_PAD_MODE_PUSH:
5148 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
5149 videocontext, const gchar * codec_id, guint8 * data, guint size,
5150 gchar ** codec_name, guint32 * riff_fourcc)
5152 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
5153 GstCaps *caps = NULL;
5155 g_assert (videocontext != NULL);
5156 g_assert (codec_name != NULL);
5161 /* TODO: check if we have all codec types from matroska-ids.h
5162 * check if we have to do more special things with codec_private
5165 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
5166 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
5169 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
5170 gst_riff_strf_vids *vids = NULL;
5173 GstBuffer *buf = NULL;
5175 vids = (gst_riff_strf_vids *) data;
5177 /* assure size is big enough */
5179 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
5182 if (size < sizeof (gst_riff_strf_vids)) {
5183 vids = g_new (gst_riff_strf_vids, 1);
5184 memcpy (vids, data, size);
5187 context->dts_only = TRUE; /* VFW files only store DTS */
5189 /* little-endian -> byte-order */
5190 vids->size = GUINT32_FROM_LE (vids->size);
5191 vids->width = GUINT32_FROM_LE (vids->width);
5192 vids->height = GUINT32_FROM_LE (vids->height);
5193 vids->planes = GUINT16_FROM_LE (vids->planes);
5194 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
5195 vids->compression = GUINT32_FROM_LE (vids->compression);
5196 vids->image_size = GUINT32_FROM_LE (vids->image_size);
5197 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
5198 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
5199 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
5200 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
5202 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
5203 gsize offset = sizeof (gst_riff_strf_vids);
5206 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
5207 size - offset), size - offset);
5211 *riff_fourcc = vids->compression;
5213 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
5214 buf, NULL, codec_name);
5217 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
5218 GST_FOURCC_ARGS (vids->compression));
5220 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
5221 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
5222 "video/x-compressed-yuv");
5223 context->intra_only =
5224 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
5228 gst_buffer_unref (buf);
5230 if (vids != (gst_riff_strf_vids *) data)
5233 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
5235 GstVideoFormat format;
5237 gst_video_info_init (&info);
5238 switch (videocontext->fourcc) {
5239 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5240 format = GST_VIDEO_FORMAT_I420;
5242 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5243 format = GST_VIDEO_FORMAT_YUY2;
5245 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5246 format = GST_VIDEO_FORMAT_YV12;
5248 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5249 format = GST_VIDEO_FORMAT_UYVY;
5251 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5252 format = GST_VIDEO_FORMAT_AYUV;
5254 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
5255 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
5256 format = GST_VIDEO_FORMAT_GRAY8;
5258 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
5259 format = GST_VIDEO_FORMAT_RGB;
5261 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
5262 format = GST_VIDEO_FORMAT_BGR;
5265 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5266 GST_FOURCC_ARGS (videocontext->fourcc));
5270 context->intra_only = TRUE;
5272 gst_video_info_set_format (&info, format, videocontext->pixel_width,
5273 videocontext->pixel_height);
5274 caps = gst_video_info_to_caps (&info);
5275 *codec_name = gst_pb_utils_get_codec_description (caps);
5276 context->alignment = 32;
5277 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5278 caps = gst_caps_new_simple ("video/x-divx",
5279 "divxversion", G_TYPE_INT, 4, NULL);
5280 *codec_name = g_strdup ("MPEG-4 simple profile");
5281 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5282 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5283 caps = gst_caps_new_simple ("video/mpeg",
5284 "mpegversion", G_TYPE_INT, 4,
5285 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5289 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5290 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5291 gst_buffer_unref (priv);
5293 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
5295 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5296 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5298 *codec_name = g_strdup ("MPEG-4 advanced profile");
5299 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5301 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5302 "divxversion", G_TYPE_INT, 3, NULL),
5303 gst_structure_new ("video/x-msmpeg",
5304 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5306 caps = gst_caps_new_simple ("video/x-msmpeg",
5307 "msmpegversion", G_TYPE_INT, 43, NULL);
5308 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5309 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5310 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5313 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5318 caps = gst_caps_new_simple ("video/mpeg",
5319 "systemstream", G_TYPE_BOOLEAN, FALSE,
5320 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5321 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5322 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5323 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5324 caps = gst_caps_new_empty_simple ("image/jpeg");
5325 *codec_name = g_strdup ("Motion-JPEG");
5326 context->intra_only = TRUE;
5327 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5328 caps = gst_caps_new_empty_simple ("video/x-h264");
5332 /* First byte is the version, second is the profile indication, and third
5333 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5334 * level indication. */
5335 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5338 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5339 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5340 gst_buffer_unref (priv);
5342 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5343 "alignment", G_TYPE_STRING, "au", NULL);
5345 GST_WARNING ("No codec data found, assuming output is byte-stream");
5346 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5349 *codec_name = g_strdup ("H264");
5350 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
5351 caps = gst_caps_new_empty_simple ("video/x-h265");
5355 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
5358 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5359 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5360 gst_buffer_unref (priv);
5362 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
5363 "alignment", G_TYPE_STRING, "au", NULL);
5365 GST_WARNING ("No codec data found, assuming output is byte-stream");
5366 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5369 *codec_name = g_strdup ("HEVC");
5370 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5371 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5372 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5373 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5374 gint rmversion = -1;
5376 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5378 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5380 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5382 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5385 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5386 "rmversion", G_TYPE_INT, rmversion, NULL);
5387 GST_DEBUG ("data:%p, size:0x%x", data, size);
5388 /* We need to extract the extradata ! */
5389 if (data && (size >= 0x22)) {
5394 subformat = GST_READ_UINT32_BE (data + 0x1a);
5395 rformat = GST_READ_UINT32_BE (data + 0x1e);
5398 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5400 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5401 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5402 gst_buffer_unref (priv);
5405 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5406 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5407 caps = gst_caps_new_empty_simple ("video/x-theora");
5408 context->stream_headers =
5409 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5410 context->codec_priv_size);
5411 /* FIXME: mark stream as broken and skip if there are no stream headers */
5412 context->send_stream_headers = TRUE;
5413 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5414 caps = gst_caps_new_empty_simple ("video/x-dirac");
5415 *codec_name = g_strdup_printf ("Dirac");
5416 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5417 caps = gst_caps_new_empty_simple ("video/x-vp8");
5418 *codec_name = g_strdup_printf ("On2 VP8");
5419 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5420 caps = gst_caps_new_empty_simple ("video/x-vp9");
5421 *codec_name = g_strdup_printf ("On2 VP9");
5422 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
5424 const gchar *variant, *variant_descr = "";
5426 /* Expect a fourcc in the codec private data */
5427 if (!data || size < 4) {
5428 GST_WARNING ("No or too small PRORESS fourcc (%d bytes)", size);
5432 fourcc = GST_STR_FOURCC (data);
5434 case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
5435 variant_descr = " 4:2:2 LT";
5438 case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
5440 variant_descr = " 4:2:2 HQ";
5442 case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
5444 variant_descr = " 4:4:4:4";
5446 case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
5448 variant_descr = " 4:2:2 Proxy";
5450 case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
5452 variant = "standard";
5453 variant_descr = " 4:2:2 SD";
5457 GST_LOG ("Prores video, codec fourcc %" GST_FOURCC_FORMAT,
5458 GST_FOURCC_ARGS (fourcc));
5460 caps = gst_caps_new_simple ("video/x-prores",
5461 "format", G_TYPE_STRING, variant, NULL);
5462 *codec_name = g_strdup_printf ("Apple ProRes%s", variant_descr);
5463 context->postprocess_frame = gst_matroska_demux_add_prores_header;
5465 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5471 GstStructure *structure;
5473 for (i = 0; i < gst_caps_get_size (caps); i++) {
5474 structure = gst_caps_get_structure (caps, i);
5476 /* FIXME: use the real unit here! */
5477 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5478 videocontext->pixel_width,
5479 videocontext->pixel_height,
5480 videocontext->display_width, videocontext->display_height);
5482 /* pixel width and height are the w and h of the video in pixels */
5483 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5484 gint w = videocontext->pixel_width;
5485 gint h = videocontext->pixel_height;
5487 gst_structure_set (structure,
5488 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5491 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5494 if (videocontext->display_width <= 0)
5495 videocontext->display_width = videocontext->pixel_width;
5496 if (videocontext->display_height <= 0)
5497 videocontext->display_height = videocontext->pixel_height;
5499 /* calculate the pixel aspect ratio using the display and pixel w/h */
5500 n = videocontext->display_width * videocontext->pixel_height;
5501 d = videocontext->display_height * videocontext->pixel_width;
5502 GST_DEBUG ("setting PAR to %d/%d", n, d);
5503 gst_structure_set (structure, "pixel-aspect-ratio",
5505 videocontext->display_width * videocontext->pixel_height,
5506 videocontext->display_height * videocontext->pixel_width, NULL);
5509 if (videocontext->default_fps > 0.0) {
5512 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5514 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5516 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5518 } else if (context->default_duration > 0) {
5521 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5523 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5524 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5526 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5527 fps_n, fps_d, NULL);
5529 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5533 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5534 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5537 if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
5538 if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
5539 videocontext->pixel_width, videocontext->pixel_height,
5540 videocontext->display_width * videocontext->pixel_height,
5541 videocontext->display_height * videocontext->pixel_width)) {
5542 videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
5544 gst_caps_set_simple (caps,
5545 "multiview-mode", G_TYPE_STRING,
5546 gst_video_multiview_mode_to_caps_string
5547 (videocontext->multiview_mode), "multiview-flags",
5548 GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
5549 GST_FLAG_SET_MASK_EXACT, NULL);
5552 caps = gst_caps_simplify (caps);
5559 * Some AAC specific code... *sigh*
5560 * FIXME: maybe we should use '15' and code the sample rate explicitly
5561 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5565 aac_rate_idx (gint rate)
5569 else if (75132 <= rate)
5571 else if (55426 <= rate)
5573 else if (46009 <= rate)
5575 else if (37566 <= rate)
5577 else if (27713 <= rate)
5579 else if (23004 <= rate)
5581 else if (18783 <= rate)
5583 else if (13856 <= rate)
5585 else if (11502 <= rate)
5587 else if (9391 <= rate)
5594 aac_profile_idx (const gchar * codec_id)
5598 if (strlen (codec_id) <= 12)
5600 else if (!strncmp (&codec_id[12], "MAIN", 4))
5602 else if (!strncmp (&codec_id[12], "LC", 2))
5604 else if (!strncmp (&codec_id[12], "SSR", 3))
5613 round_up_pow2 (guint n)
5624 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5627 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5628 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5629 gchar ** codec_name, guint16 * riff_audio_fmt)
5631 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5632 GstCaps *caps = NULL;
5634 g_assert (audiocontext != NULL);
5635 g_assert (codec_name != NULL);
5638 *riff_audio_fmt = 0;
5640 /* TODO: check if we have all codec types from matroska-ids.h
5641 * check if we have to do more special things with codec_private
5642 * check if we need bitdepth in different places too
5643 * implement channel position magic
5645 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5646 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5647 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5648 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5651 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5652 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5653 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5656 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5658 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5663 caps = gst_caps_new_simple ("audio/mpeg",
5664 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5665 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5666 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5667 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5670 GstAudioFormat format;
5672 sign = (audiocontext->bitdepth != 8);
5673 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5674 endianness = G_BIG_ENDIAN;
5676 endianness = G_LITTLE_ENDIAN;
5678 format = gst_audio_format_build_integer (sign, endianness,
5679 audiocontext->bitdepth, audiocontext->bitdepth);
5681 /* FIXME: Channel mask and reordering */
5682 caps = gst_caps_new_simple ("audio/x-raw",
5683 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5684 "layout", G_TYPE_STRING, "interleaved",
5685 "channel-mask", GST_TYPE_BITMASK,
5686 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5688 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5689 audiocontext->bitdepth);
5690 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5691 context->alignment = round_up_pow2 (context->alignment);
5692 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5693 const gchar *format;
5694 if (audiocontext->bitdepth == 32)
5698 /* FIXME: Channel mask and reordering */
5699 caps = gst_caps_new_simple ("audio/x-raw",
5700 "format", G_TYPE_STRING, format,
5701 "layout", G_TYPE_STRING, "interleaved",
5702 "channel-mask", GST_TYPE_BITMASK,
5703 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5704 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5705 audiocontext->bitdepth);
5706 context->alignment = audiocontext->bitdepth / 8;
5707 context->alignment = round_up_pow2 (context->alignment);
5708 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5709 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5710 caps = gst_caps_new_simple ("audio/x-ac3",
5711 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5712 *codec_name = g_strdup ("AC-3 audio");
5713 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5714 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5715 caps = gst_caps_new_simple ("audio/x-eac3",
5716 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5717 *codec_name = g_strdup ("E-AC-3 audio");
5718 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5719 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5720 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5721 *codec_name = g_strdup ("Dolby TrueHD");
5722 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5723 caps = gst_caps_new_empty_simple ("audio/x-dts");
5724 *codec_name = g_strdup ("DTS audio");
5725 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5726 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5727 context->stream_headers =
5728 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5729 context->codec_priv_size);
5730 /* FIXME: mark stream as broken and skip if there are no stream headers */
5731 context->send_stream_headers = TRUE;
5732 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5733 caps = gst_caps_new_empty_simple ("audio/x-flac");
5734 context->stream_headers =
5735 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5736 context->codec_priv_size);
5737 /* FIXME: mark stream as broken and skip if there are no stream headers */
5738 context->send_stream_headers = TRUE;
5739 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5740 caps = gst_caps_new_empty_simple ("audio/x-speex");
5741 context->stream_headers =
5742 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5743 context->codec_priv_size);
5744 /* FIXME: mark stream as broken and skip if there are no stream headers */
5745 context->send_stream_headers = TRUE;
5746 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5749 if (context->codec_priv_size >= 19) {
5750 if (audiocontext->samplerate)
5751 GST_WRITE_UINT32_LE ((guint8 *) context->codec_priv + 12,
5752 audiocontext->samplerate);
5753 if (context->codec_delay) {
5755 gst_util_uint64_scale_round (context->codec_delay, 48000,
5757 GST_WRITE_UINT16_LE ((guint8 *) context->codec_priv + 10, delay);
5761 gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5762 context->codec_priv_size), context->codec_priv_size);
5763 caps = gst_codec_utils_opus_create_caps_from_header (tmp, NULL);
5764 gst_buffer_unref (tmp);
5765 *codec_name = g_strdup ("Opus");
5766 } else if (context->codec_priv_size == 0) {
5767 GST_WARNING ("No Opus codec data found, trying to create one");
5768 if (audiocontext->channels <= 2) {
5769 guint8 streams, coupled, channels;
5773 audiocontext->samplerate == 0 ? 48000 : audiocontext->samplerate;
5774 channels = audiocontext->channels == 0 ? 2 : audiocontext->channels;
5775 if (channels == 1) {
5784 gst_codec_utils_opus_create_caps (samplerate, channels, 0, streams,
5787 *codec_name = g_strdup ("Opus");
5789 GST_WARNING ("Failed to create Opus caps from audio context");
5792 GST_WARNING ("No Opus codec data, and not enough info to create one");
5795 GST_WARNING ("Invalid Opus codec data size (got %" G_GSIZE_FORMAT
5796 ", expected 19)", context->codec_priv_size);
5798 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5799 gst_riff_strf_auds auds;
5801 if (data && size >= 18) {
5802 GstBuffer *codec_data = NULL;
5804 /* little-endian -> byte-order */
5805 auds.format = GST_READ_UINT16_LE (data);
5806 auds.channels = GST_READ_UINT16_LE (data + 2);
5807 auds.rate = GST_READ_UINT32_LE (data + 4);
5808 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5809 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5810 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5812 /* 18 is the waveformatex size */
5814 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5815 data + 18, size - 18, 0, size - 18, NULL, NULL);
5819 *riff_audio_fmt = auds.format;
5821 /* FIXME: Handle reorder map */
5822 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5823 codec_data, codec_name, NULL);
5825 gst_buffer_unref (codec_data);
5828 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5831 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5833 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5834 GstBuffer *priv = NULL;
5836 gint rate_idx, profile;
5837 guint8 *data = NULL;
5839 /* unspecified AAC profile with opaque private codec data */
5840 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5841 if (context->codec_priv_size >= 2) {
5842 guint obj_type, freq_index, explicit_freq_bytes = 0;
5844 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5846 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5847 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5848 if (freq_index == 15)
5849 explicit_freq_bytes = 3;
5850 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5851 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5852 context->codec_priv_size), context->codec_priv_size);
5853 /* assume SBR if samplerate <= 24kHz */
5854 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5855 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5856 audiocontext->samplerate *= 2;
5859 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5860 /* this is pretty broken;
5861 * maybe we need to make up some default private,
5862 * or maybe ADTS data got dumped in.
5863 * Let's set up some private data now, and check actual data later */
5864 /* just try this and see what happens ... */
5865 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5866 context->postprocess_frame = gst_matroska_demux_check_aac;
5870 /* make up decoder-specific data if it is not supplied */
5874 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5875 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5877 rate_idx = aac_rate_idx (audiocontext->samplerate);
5878 profile = aac_profile_idx (codec_id);
5880 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5881 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5883 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5884 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5886 gst_buffer_unmap (priv, &map);
5887 gst_buffer_set_size (priv, 2);
5888 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5889 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5892 if (g_strrstr (codec_id, "SBR")) {
5893 /* HE-AAC (aka SBR AAC) */
5894 audiocontext->samplerate *= 2;
5895 rate_idx = aac_rate_idx (audiocontext->samplerate);
5896 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5897 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5898 data[4] = (1 << 7) | (rate_idx << 3);
5899 gst_buffer_unmap (priv, &map);
5901 gst_buffer_unmap (priv, &map);
5902 gst_buffer_set_size (priv, 2);
5905 gst_buffer_unmap (priv, &map);
5906 gst_buffer_unref (priv);
5908 GST_ERROR ("Unknown AAC profile and no codec private data");
5913 caps = gst_caps_new_simple ("audio/mpeg",
5914 "mpegversion", G_TYPE_INT, mpegversion,
5915 "framed", G_TYPE_BOOLEAN, TRUE,
5916 "stream-format", G_TYPE_STRING, "raw", NULL);
5917 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5918 if (context->codec_priv && context->codec_priv_size > 0)
5919 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5920 context->codec_priv, context->codec_priv_size);
5921 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5922 gst_buffer_unref (priv);
5924 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5925 caps = gst_caps_new_simple ("audio/x-tta",
5926 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5927 *codec_name = g_strdup ("TTA audio");
5928 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5929 caps = gst_caps_new_simple ("audio/x-wavpack",
5930 "width", G_TYPE_INT, audiocontext->bitdepth,
5931 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5932 *codec_name = g_strdup ("Wavpack audio");
5933 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5934 audiocontext->wvpk_block_index = 0;
5935 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5936 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5937 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5938 gint raversion = -1;
5940 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5942 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5947 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5948 "raversion", G_TYPE_INT, raversion, NULL);
5949 /* Extract extra information from caps, mapping varies based on codec */
5950 if (data && (size >= 0x50)) {
5957 guint extra_data_size;
5959 GST_ERROR ("real audio raversion:%d", raversion);
5960 if (raversion == 8) {
5962 flavor = GST_READ_UINT16_BE (data + 22);
5963 packet_size = GST_READ_UINT32_BE (data + 24);
5964 height = GST_READ_UINT16_BE (data + 40);
5965 leaf_size = GST_READ_UINT16_BE (data + 44);
5966 sample_width = GST_READ_UINT16_BE (data + 58);
5967 extra_data_size = GST_READ_UINT32_BE (data + 74);
5970 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5971 flavor, packet_size, height, leaf_size, sample_width,
5973 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5974 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5975 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5977 if ((size - 78) >= extra_data_size) {
5978 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5980 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5981 gst_buffer_unref (priv);
5986 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5987 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5988 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5989 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5990 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5991 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5992 *codec_name = g_strdup ("Real Audio Lossless");
5993 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5994 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5995 *codec_name = g_strdup ("Sony ATRAC3");
5997 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6002 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
6005 for (i = 0; i < gst_caps_get_size (caps); i++) {
6006 gst_structure_set (gst_caps_get_structure (caps, i),
6007 "channels", G_TYPE_INT, audiocontext->channels,
6008 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
6012 caps = gst_caps_simplify (caps);
6019 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
6020 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
6022 GstCaps *caps = NULL;
6023 GstMatroskaTrackContext *context =
6024 (GstMatroskaTrackContext *) subtitlecontext;
6026 /* for backwards compatibility */
6027 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
6028 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
6029 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
6030 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
6031 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
6032 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
6033 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
6034 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
6036 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
6037 * Check if we have to do something with codec_private */
6038 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
6039 /* well, plain text simply does not have a lot of markup ... */
6040 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
6041 "pango-markup", NULL);
6042 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6043 subtitlecontext->check_markup = TRUE;
6044 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
6045 caps = gst_caps_new_empty_simple ("application/x-ssa");
6046 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6047 subtitlecontext->check_markup = FALSE;
6048 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
6049 caps = gst_caps_new_empty_simple ("application/x-ass");
6050 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6051 subtitlecontext->check_markup = FALSE;
6052 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
6053 caps = gst_caps_new_empty_simple ("application/x-usf");
6054 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6055 subtitlecontext->check_markup = FALSE;
6056 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
6057 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
6058 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
6059 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
6060 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
6061 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
6062 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
6063 context->stream_headers =
6064 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6065 context->codec_priv_size);
6066 /* FIXME: mark stream as broken and skip if there are no stream headers */
6067 context->send_stream_headers = TRUE;
6069 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
6070 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
6073 if (data != NULL && size > 0) {
6076 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
6077 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
6078 gst_buffer_unref (buf);
6086 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
6088 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6090 GST_OBJECT_LOCK (demux);
6091 if (demux->common.element_index)
6092 gst_object_unref (demux->common.element_index);
6093 demux->common.element_index = index ? gst_object_ref (index) : NULL;
6094 GST_OBJECT_UNLOCK (demux);
6095 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
6096 demux->common.element_index);
6100 gst_matroska_demux_get_index (GstElement * element)
6102 GstIndex *result = NULL;
6103 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6105 GST_OBJECT_LOCK (demux);
6106 if (demux->common.element_index)
6107 result = gst_object_ref (demux->common.element_index);
6108 GST_OBJECT_UNLOCK (demux);
6110 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
6116 static GstStateChangeReturn
6117 gst_matroska_demux_change_state (GstElement * element,
6118 GstStateChange transition)
6120 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6121 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
6123 /* handle upwards state changes here */
6124 switch (transition) {
6129 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
6131 /* handle downwards state changes */
6132 switch (transition) {
6133 case GST_STATE_CHANGE_PAUSED_TO_READY:
6134 gst_matroska_demux_reset (GST_ELEMENT (demux));
6144 gst_matroska_demux_set_property (GObject * object,
6145 guint prop_id, const GValue * value, GParamSpec * pspec)
6147 GstMatroskaDemux *demux;
6149 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6150 demux = GST_MATROSKA_DEMUX (object);
6153 case PROP_MAX_GAP_TIME:
6154 GST_OBJECT_LOCK (demux);
6155 demux->max_gap_time = g_value_get_uint64 (value);
6156 GST_OBJECT_UNLOCK (demux);
6159 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6165 gst_matroska_demux_get_property (GObject * object,
6166 guint prop_id, GValue * value, GParamSpec * pspec)
6168 GstMatroskaDemux *demux;
6170 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6171 demux = GST_MATROSKA_DEMUX (object);
6174 case PROP_MAX_GAP_TIME:
6175 GST_OBJECT_LOCK (demux);
6176 g_value_set_uint64 (value, demux->max_gap_time);
6177 GST_OBJECT_UNLOCK (demux);
6180 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6186 gst_matroska_demux_plugin_init (GstPlugin * plugin)
6190 /* parser helper separate debug */
6191 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
6192 0, "EBML stream helper class");
6194 /* create an elementfactory for the matroska_demux element */
6195 if (!gst_element_register (plugin, "matroskademux",
6196 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))