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;
1708 newpos = MAX (0, newpos - chunk);
1710 gst_buffer_unmap (buf, &map);
1711 gst_buffer_unref (buf);
1714 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1715 if (ret != GST_FLOW_OK)
1717 GST_DEBUG_OBJECT (demux,
1718 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1719 gst_buffer_get_size (buf), newpos);
1720 gst_buffer_map (buf, &map, GST_MAP_READ);
1723 if (oldpos == newpos && oldlength == map.size) {
1724 GST_ERROR_OBJECT (demux, "Stuck at same position");
1725 ret = GST_FLOW_ERROR;
1729 oldlength = map.size;
1732 gst_byte_reader_init (&reader, data, size);
1735 gint found = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1736 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1738 cluster_pos = found;
1741 /* need last occurrence when searching backwards */
1743 cluster_pos = gst_byte_reader_get_pos (&reader) + found;
1744 gst_byte_reader_skip (&reader, found + 4);
1750 if (cluster_pos >= 0) {
1751 newpos += cluster_pos;
1752 GST_DEBUG_OBJECT (demux,
1753 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1754 /* extra checks whether we really sync'ed to a cluster:
1755 * - either it is the first and only cluster
1756 * - either there is a cluster after this one
1757 * - either cluster length is undefined
1759 /* ok if first cluster (there may not a subsequent one) */
1760 if (newpos == demux->first_cluster_offset) {
1761 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1764 demux->common.offset = newpos;
1765 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1766 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1767 if (ret != GST_FLOW_OK) {
1768 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1771 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1772 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1774 /* ok if undefined length or first cluster */
1775 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1776 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1780 demux->common.offset += length + needed;
1781 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1782 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1783 if (ret != GST_FLOW_OK)
1785 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1786 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1787 if (id == GST_MATROSKA_ID_CLUSTER)
1793 /* partial cluster id may have been in tail of buffer */
1795 forward ? MAX (gst_byte_reader_get_remaining (&reader), 4) - 3 : 3;
1800 gst_buffer_unmap (buf, &map);
1801 gst_buffer_unref (buf);
1806 demux->common.offset = orig_offset;
1811 /* bisect and scan through file for cluster starting before @time,
1812 * returns fake index entry with corresponding info on cluster */
1813 static GstMatroskaIndex *
1814 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1816 GstMatroskaIndex *entry = NULL;
1817 GstMatroskaReadState current_state;
1818 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1820 gint64 opos, newpos, current_offset;
1821 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1822 gint64 apos, maxpos;
1823 guint64 cluster_size = 0;
1829 /* estimate new position, resync using cluster ebml id,
1830 * and bisect further or scan forward to appropriate cluster */
1832 /* store some current state */
1833 current_state = demux->common.state;
1834 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1836 current_cluster_offset = demux->cluster_offset;
1837 current_cluster_time = demux->cluster_time;
1838 current_offset = demux->common.offset;
1840 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1842 /* estimate using start and last known cluster */
1843 GST_OBJECT_LOCK (demux);
1844 apos = demux->first_cluster_offset;
1845 atime = demux->stream_start_time;
1846 opos = demux->last_cluster_offset;
1847 otime = demux->stream_last_time;
1848 GST_OBJECT_UNLOCK (demux);
1851 time = MAX (time, atime);
1852 otime = MAX (otime, atime);
1853 opos = MAX (opos, apos);
1855 maxpos = gst_matroska_read_common_get_length (&demux->common);
1860 * apos always refer to a cluster before target time;
1861 * opos may or may not be after target time, but if it is once so,
1862 * then also in next iteration
1866 GST_LOG_OBJECT (demux,
1867 "apos: %" G_GUINT64_FORMAT ", atime: %" GST_TIME_FORMAT ", %"
1868 GST_TIME_FORMAT " in stream time, "
1869 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1870 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1871 GST_TIME_FORMAT, apos, GST_TIME_ARGS (atime),
1872 GST_TIME_ARGS (atime - demux->stream_start_time), opos,
1873 GST_TIME_ARGS (otime), GST_TIME_ARGS (otime - demux->stream_start_time),
1874 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1876 g_assert (atime <= otime);
1877 g_assert (apos <= opos);
1878 if (time == GST_CLOCK_TIME_NONE) {
1879 GST_DEBUG_OBJECT (demux, "searching last cluster");
1882 GST_DEBUG_OBJECT (demux, "unknown file size; bailing out");
1885 } else if (otime <= atime) {
1889 gst_util_uint64_scale (opos - apos, time - atime, otime - atime);
1890 if (maxpos != -1 && newpos > maxpos)
1894 GST_DEBUG_OBJECT (demux,
1895 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1896 GST_TIME_ARGS (time), newpos);
1898 /* search backwards */
1899 if (newpos > apos) {
1900 ret = gst_matroska_demux_search_cluster (demux, &newpos, FALSE);
1901 if (ret != GST_FLOW_OK)
1905 /* then start scanning and parsing for cluster time,
1906 * re-estimate if possible, otherwise next cluster and so on */
1907 /* note that each re-estimate is entered with a change in apos or opos,
1908 * avoiding infinite loop */
1909 demux->common.offset = newpos;
1910 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1912 prev_cluster_time = GST_CLOCK_TIME_NONE;
1914 /* peek and parse some elements */
1915 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1916 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1917 if (ret != GST_FLOW_OK)
1919 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1920 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1922 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1923 if (ret != GST_FLOW_OK)
1926 if (id == GST_MATROSKA_ID_CLUSTER) {
1927 cluster_time = GST_CLOCK_TIME_NONE;
1928 if (length == G_MAXUINT64)
1931 cluster_size = length + needed;
1933 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1934 cluster_time == GST_CLOCK_TIME_NONE) {
1935 cluster_time = demux->cluster_time * demux->common.time_scale;
1936 cluster_offset = demux->cluster_offset;
1937 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1938 " with time %" GST_TIME_FORMAT, cluster_offset,
1939 GST_TIME_ARGS (cluster_time));
1940 if (time == GST_CLOCK_TIME_NONE) {
1941 GST_DEBUG_OBJECT (demux, "found last cluster");
1942 prev_cluster_time = cluster_time;
1943 prev_cluster_offset = cluster_offset;
1946 if (cluster_time > time) {
1947 GST_DEBUG_OBJECT (demux, "overshot target");
1948 /* cluster overshoots */
1949 if (cluster_offset == demux->first_cluster_offset) {
1950 /* but no prev one */
1951 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1952 prev_cluster_time = cluster_time;
1953 prev_cluster_offset = cluster_offset;
1956 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1957 /* prev cluster did not overshoot, so prev cluster is target */
1960 /* re-estimate using this new position info */
1961 opos = cluster_offset;
1962 otime = cluster_time;
1966 /* cluster undershoots */
1967 GST_DEBUG_OBJECT (demux, "undershot target");
1968 /* ok if close enough */
1969 if (GST_CLOCK_DIFF (cluster_time, time) < 5 * GST_SECOND) {
1970 GST_DEBUG_OBJECT (demux, "target close enough");
1971 prev_cluster_time = cluster_time;
1972 prev_cluster_offset = cluster_offset;
1976 /* we are in between atime and otime => can bisect if worthwhile */
1977 if (prev_cluster_time != GST_CLOCK_TIME_NONE &&
1978 cluster_time > prev_cluster_time &&
1979 (GST_CLOCK_DIFF (prev_cluster_time, cluster_time) * 10 <
1980 GST_CLOCK_DIFF (cluster_time, time))) {
1981 /* we moved at least one cluster forward,
1982 * and it looks like target is still far away,
1983 * let's estimate again */
1984 GST_DEBUG_OBJECT (demux, "bisecting with new apos");
1985 apos = cluster_offset;
1986 atime = cluster_time;
1990 /* cluster undershoots, goto next one */
1991 prev_cluster_time = cluster_time;
1992 prev_cluster_offset = cluster_offset;
1993 /* skip cluster if length is defined,
1994 * otherwise will be skippingly parsed into */
1996 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1997 demux->common.offset = cluster_offset + cluster_size;
1998 demux->cluster_time = GST_CLOCK_TIME_NONE;
2000 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
2007 if (ret == GST_FLOW_EOS) {
2008 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
2014 entry = g_new0 (GstMatroskaIndex, 1);
2015 entry->time = prev_cluster_time;
2016 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
2017 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
2018 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
2022 /* restore some state */
2023 demux->cluster_offset = current_cluster_offset;
2024 demux->cluster_time = current_cluster_time;
2025 demux->common.offset = current_offset;
2026 demux->common.state = current_state;
2032 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
2033 GstPad * pad, GstEvent * event)
2035 GstMatroskaIndex *entry = NULL;
2036 GstMatroskaIndex scan_entry;
2038 GstSeekType cur_type, stop_type;
2040 gboolean flush, keyunit, before, after, snap_next;
2043 GstMatroskaTrackContext *track = NULL;
2044 GstSegment seeksegment = { 0, };
2045 gboolean update = TRUE;
2046 gboolean pad_locked = FALSE;
2048 GstSearchMode snap_dir;
2050 g_return_val_if_fail (event != NULL, FALSE);
2053 track = gst_pad_get_element_private (pad);
2055 GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
2057 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2059 seqnum = gst_event_get_seqnum (event);
2061 /* we can only seek on time */
2062 if (format != GST_FORMAT_TIME) {
2063 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2067 /* copy segment, we need this because we still need the old
2068 * segment when we close the current segment. */
2069 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
2071 /* pull mode without index means that the actual duration is not known,
2072 * we might be playing a file that's still being recorded
2073 * so, invalidate our current duration, which is only a moving target,
2074 * and should not be used to clamp anything */
2075 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
2076 seeksegment.duration = GST_CLOCK_TIME_NONE;
2079 GST_DEBUG_OBJECT (demux, "configuring seek");
2080 /* Subtract stream_start_time so we always seek on a segment
2082 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2083 seeksegment.start -= demux->stream_start_time;
2084 seeksegment.position -= demux->stream_start_time;
2085 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2086 seeksegment.stop -= demux->stream_start_time;
2088 seeksegment.stop = seeksegment.duration;
2091 gst_segment_do_seek (&seeksegment, rate, format, flags,
2092 cur_type, cur, stop_type, stop, &update);
2094 /* Restore the clip timestamp offset */
2095 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2096 seeksegment.position += demux->stream_start_time;
2097 seeksegment.start += demux->stream_start_time;
2098 if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2099 seeksegment.stop = seeksegment.duration;
2100 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2101 seeksegment.stop += demux->stream_start_time;
2104 /* restore segment duration (if any effect),
2105 * would be determined again when parsing, but anyway ... */
2106 seeksegment.duration = demux->common.segment.duration;
2108 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2109 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2110 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
2111 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
2113 /* always do full update if flushing,
2114 * otherwise problems might arise downstream with missing keyframes etc */
2115 update = update || flush;
2117 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2119 /* check sanity before we start flushing and all that */
2120 snap_next = after && !before;
2121 if (seeksegment.rate < 0)
2122 snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
2124 snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
2126 GST_OBJECT_LOCK (demux);
2127 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2128 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2129 seeksegment.position, &demux->seek_index, &demux->seek_entry,
2130 snap_dir)) == NULL) {
2131 /* pull mode without index can scan later on */
2132 if (demux->streaming) {
2133 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2134 GST_OBJECT_UNLOCK (demux);
2136 } else if (rate < 0.0) {
2137 /* FIXME: We should build an index during playback or when scanning
2138 * that can be used here. The reverse playback code requires seek_index
2139 * and seek_entry to be set!
2141 GST_DEBUG_OBJECT (demux,
2142 "No matching seek entry in index, needed for reverse playback");
2143 GST_OBJECT_UNLOCK (demux);
2147 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2148 GST_OBJECT_UNLOCK (demux);
2151 /* only have to update some segment,
2152 * but also still have to honour flush and so on */
2153 GST_DEBUG_OBJECT (demux, "... no update");
2154 /* bad goto, bad ... */
2158 if (demux->streaming)
2163 GstEvent *flush_event = gst_event_new_flush_start ();
2164 gst_event_set_seqnum (flush_event, seqnum);
2165 GST_DEBUG_OBJECT (demux, "Starting flush");
2166 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2167 gst_matroska_demux_send_event (demux, flush_event);
2169 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2170 gst_pad_pause_task (demux->common.sinkpad);
2174 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2179 /* now grab the stream lock so that streaming cannot continue, for
2180 * non flushing seeks when the element is in PAUSED this could block
2182 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2183 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2186 /* pull mode without index can do some scanning */
2187 if (!demux->streaming && !entry) {
2188 GstEvent *flush_event;
2190 /* need to stop flushing upstream as we need it next */
2192 flush_event = gst_event_new_flush_stop (TRUE);
2193 gst_event_set_seqnum (flush_event, seqnum);
2194 gst_pad_push_event (demux->common.sinkpad, flush_event);
2196 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2197 /* keep local copy */
2199 scan_entry = *entry;
2201 entry = &scan_entry;
2203 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2205 flush_event = gst_event_new_flush_stop (TRUE);
2206 gst_event_set_seqnum (flush_event, seqnum);
2207 gst_matroska_demux_send_event (demux, flush_event);
2214 if (keyunit && seeksegment.rate > 0) {
2215 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2216 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2217 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2218 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2219 seeksegment.position = seeksegment.start;
2220 seeksegment.time = seeksegment.start - demux->stream_start_time;
2221 } else if (keyunit) {
2222 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment stop from %"
2223 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2224 GST_TIME_ARGS (seeksegment.stop), GST_TIME_ARGS (entry->time));
2225 seeksegment.stop = MAX (entry->time, demux->stream_start_time);
2226 seeksegment.position = seeksegment.stop;
2229 if (demux->streaming) {
2230 GST_OBJECT_LOCK (demux);
2231 /* track real position we should start at */
2232 GST_DEBUG_OBJECT (demux, "storing segment start");
2233 demux->requested_seek_time = seeksegment.position;
2234 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2235 GST_OBJECT_UNLOCK (demux);
2236 /* need to seek to cluster start to pick up cluster time */
2237 /* upstream takes care of flushing and all that
2238 * ... and newsegment event handling takes care of the rest */
2239 return perform_seek_to_offset (demux, rate,
2240 entry->pos + demux->common.ebml_segment_start, seqnum, flags);
2245 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2246 gst_event_set_seqnum (flush_event, seqnum);
2247 GST_DEBUG_OBJECT (demux, "Stopping flush");
2248 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2249 gst_matroska_demux_send_event (demux, flush_event);
2252 GST_OBJECT_LOCK (demux);
2253 /* now update the real segment info */
2254 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2255 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2256 GST_OBJECT_UNLOCK (demux);
2258 /* update some (segment) state */
2259 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2262 /* notify start of new segment */
2263 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2266 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2267 GST_FORMAT_TIME, demux->common.segment.start);
2268 gst_message_set_seqnum (msg, seqnum);
2269 gst_element_post_message (GST_ELEMENT (demux), msg);
2272 GST_OBJECT_LOCK (demux);
2273 if (demux->new_segment)
2274 gst_event_unref (demux->new_segment);
2276 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2277 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2278 gst_event_set_seqnum (demux->new_segment, seqnum);
2279 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2280 demux->to_time = demux->common.segment.position;
2282 demux->to_time = GST_CLOCK_TIME_NONE;
2283 demux->segment_seqnum = seqnum;
2284 GST_OBJECT_UNLOCK (demux);
2286 /* restart our task since it might have been stopped when we did the
2288 gst_pad_start_task (demux->common.sinkpad,
2289 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2291 /* streaming can continue now */
2293 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2301 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2303 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2309 * Handle whether we can perform the seek event or if we have to let the chain
2310 * function handle seeks to build the seek indexes first.
2313 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2317 GstSeekType cur_type, stop_type;
2322 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2327 /* we can only seek on time */
2328 if (format != GST_FORMAT_TIME) {
2329 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2333 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2334 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2338 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2339 GST_DEBUG_OBJECT (demux,
2340 "Non-flushing seek not supported in streaming mode");
2344 if (flags & GST_SEEK_FLAG_SEGMENT) {
2345 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2349 /* check for having parsed index already */
2350 if (!demux->common.index_parsed) {
2351 gboolean building_index;
2354 if (!demux->index_offset) {
2355 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2359 GST_OBJECT_LOCK (demux);
2360 /* handle the seek event in the chain function */
2361 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2362 /* no more seek can be issued until state reset to _DATA */
2364 /* copy the event */
2365 if (demux->seek_event)
2366 gst_event_unref (demux->seek_event);
2367 demux->seek_event = gst_event_ref (event);
2369 /* set the building_index flag so that only one thread can setup the
2370 * structures for index seeking. */
2371 building_index = demux->building_index;
2372 if (!building_index) {
2373 demux->building_index = TRUE;
2374 offset = demux->index_offset;
2376 GST_OBJECT_UNLOCK (demux);
2378 if (!building_index) {
2379 /* seek to the first subindex or legacy index */
2380 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2381 return perform_seek_to_offset (demux, rate, offset,
2382 gst_event_get_seqnum (event), GST_SEEK_FLAG_NONE);
2385 /* well, we are handling it already */
2389 /* delegate to tweaked regular seek */
2390 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2394 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2397 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2398 gboolean res = TRUE;
2400 switch (GST_EVENT_TYPE (event)) {
2401 case GST_EVENT_SEEK:
2402 /* no seeking until we are (safely) ready */
2403 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2404 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2405 gst_event_unref (event);
2410 guint32 seqnum = gst_event_get_seqnum (event);
2411 if (seqnum == demux->segment_seqnum) {
2412 GST_LOG_OBJECT (pad,
2413 "Drop duplicated SEEK event seqnum %" G_GUINT32_FORMAT, seqnum);
2414 gst_event_unref (event);
2419 if (!demux->streaming)
2420 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2422 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2423 gst_event_unref (event);
2428 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2429 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2430 GstMatroskaTrackVideoContext *videocontext =
2431 (GstMatroskaTrackVideoContext *) context;
2433 GstClockTimeDiff diff;
2434 GstClockTime timestamp;
2436 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2438 GST_OBJECT_LOCK (demux);
2439 videocontext->earliest_time = timestamp + diff;
2440 GST_OBJECT_UNLOCK (demux);
2443 gst_event_unref (event);
2447 case GST_EVENT_TOC_SELECT:
2450 GstTocEntry *entry = NULL;
2451 GstEvent *seek_event;
2454 if (!demux->common.toc) {
2455 GST_DEBUG_OBJECT (demux, "no TOC to select");
2458 gst_event_parse_toc_select (event, &uid);
2460 GST_OBJECT_LOCK (demux);
2461 entry = gst_toc_find_entry (demux->common.toc, uid);
2462 if (entry == NULL) {
2463 GST_OBJECT_UNLOCK (demux);
2464 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2467 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2468 GST_OBJECT_UNLOCK (demux);
2469 seek_event = gst_event_new_seek (1.0,
2471 GST_SEEK_FLAG_FLUSH,
2472 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2473 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2474 gst_event_unref (seek_event);
2478 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2482 gst_event_unref (event);
2486 /* events we don't need to handle */
2487 case GST_EVENT_NAVIGATION:
2488 gst_event_unref (event);
2492 case GST_EVENT_LATENCY:
2494 res = gst_pad_push_event (demux->common.sinkpad, event);
2501 static GstFlowReturn
2502 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2504 GstFlowReturn ret = GST_FLOW_EOS;
2505 gboolean done = TRUE;
2508 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2509 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2512 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2514 if (!demux->seek_entry) {
2515 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2519 for (i = 0; i < demux->common.src->len; i++) {
2520 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2522 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2523 ", stream %d at %" GST_TIME_FORMAT,
2524 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2525 GST_TIME_ARGS (stream->from_time));
2526 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2527 if (stream->from_time > demux->common.segment.start) {
2528 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2532 /* nothing pushed for this stream;
2533 * likely seek entry did not start at keyframe, so all was skipped.
2534 * So we need an earlier entry */
2540 GstMatroskaIndex *entry;
2542 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2543 --demux->seek_entry);
2544 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2554 static GstFlowReturn
2555 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2557 GstFlowReturn ret = GST_FLOW_OK;
2560 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2562 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2563 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2567 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2568 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2572 /* one track within the "all-tracks" header */
2573 case GST_MATROSKA_ID_TRACKENTRY:
2574 ret = gst_matroska_demux_add_stream (demux, ebml);
2578 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2583 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2585 demux->tracks_parsed = TRUE;
2591 * Read signed/unsigned "EBML" numbers.
2592 * Return: number of bytes processed.
2596 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2598 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2606 while (read <= 8 && !(total & len_mask)) {
2613 if ((total &= (len_mask - 1)) == len_mask - 1)
2618 if (data[n] == 0xff)
2620 total = (total << 8) | data[n];
2624 if (read == num_ffs && total != 0)
2633 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2638 /* read as unsigned number first */
2639 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2643 if (unum == G_MAXUINT64)
2646 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2652 * Mostly used for subtitles. We add void filler data for each
2653 * lagging stream to make sure we don't deadlock.
2657 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2659 GstClockTime gap_threshold;
2662 GST_OBJECT_LOCK (demux);
2664 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2665 GST_TIME_ARGS (demux->common.segment.position));
2667 g_assert (demux->common.num_streams == demux->common.src->len);
2668 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2669 GstMatroskaTrackContext *context;
2671 context = g_ptr_array_index (demux->common.src, stream_nr);
2673 GST_LOG_OBJECT (demux,
2674 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2675 GST_TIME_ARGS (context->pos));
2677 /* Only send gap events on non-subtitle streams if lagging way behind.
2678 * The 0.5 second threshold for subtitle streams is also quite random. */
2679 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
2680 gap_threshold = GST_SECOND / 2;
2682 gap_threshold = 3 * GST_SECOND;
2684 /* Lag need only be considered if we have advanced into requested segment */
2685 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2686 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2687 demux->common.segment.position > demux->common.segment.start &&
2688 context->pos + gap_threshold < demux->common.segment.position) {
2691 guint64 start = context->pos;
2692 guint64 stop = demux->common.segment.position - gap_threshold;
2694 GST_DEBUG_OBJECT (demux,
2695 "Synchronizing stream %d with other by advancing time from %"
2696 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2697 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2699 context->pos = stop;
2701 event = gst_event_new_gap (start, stop - start);
2702 GST_OBJECT_UNLOCK (demux);
2703 gst_pad_push_event (context->pad, event);
2704 GST_OBJECT_LOCK (demux);
2708 GST_OBJECT_UNLOCK (demux);
2711 static GstFlowReturn
2712 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2713 GstMatroskaTrackContext * stream)
2715 GstFlowReturn ret = GST_FLOW_OK;
2718 num = gst_buffer_list_length (stream->stream_headers);
2719 for (i = 0; i < num; ++i) {
2722 buf = gst_buffer_list_get (stream->stream_headers, i);
2723 buf = gst_buffer_copy (buf);
2725 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2727 if (stream->set_discont) {
2728 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2729 stream->set_discont = FALSE;
2731 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2734 /* push out all headers in one go and use last flow return */
2735 ret = gst_pad_push (stream->pad, buf);
2738 /* don't need these any longer */
2739 gst_buffer_list_unref (stream->stream_headers);
2740 stream->stream_headers = NULL;
2743 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2749 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2750 GstMatroskaTrackContext * stream)
2754 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2756 if (!stream->codec_priv)
2759 /* ideally, VobSub private data should be parsed and stored more convenient
2760 * elsewhere, but for now, only interested in a small part */
2762 /* make sure we have terminating 0 */
2763 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2765 /* just locate and parse palette part */
2766 start = strstr (buf, "palette:");
2771 guint8 r, g, b, y, u, v;
2774 while (g_ascii_isspace (*start))
2776 for (i = 0; i < 16; i++) {
2777 if (sscanf (start, "%06x", &col) != 1)
2780 while ((*start == ',') || g_ascii_isspace (*start))
2782 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2783 r = (col >> 16) & 0xff;
2784 g = (col >> 8) & 0xff;
2786 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2788 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2789 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2790 clut[i] = (y << 16) | (u << 8) | v;
2793 /* got them all without problems; build and send event */
2797 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2798 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2799 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2800 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2801 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2802 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2803 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2804 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2805 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2806 G_TYPE_INT, clut[15], NULL);
2808 gst_pad_push_event (stream->pad,
2809 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2816 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2820 g_assert (demux->common.num_streams == demux->common.src->len);
2821 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2822 GstMatroskaTrackContext *stream;
2824 stream = g_ptr_array_index (demux->common.src, stream_nr);
2826 if (stream->send_stream_headers) {
2827 if (stream->stream_headers != NULL) {
2828 gst_matroska_demux_push_stream_headers (demux, stream);
2830 /* FIXME: perhaps we can just disable and skip this stream then */
2831 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2832 ("Failed to extract stream headers from codec private data"));
2834 stream->send_stream_headers = FALSE;
2837 if (stream->send_dvd_event) {
2838 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2839 /* FIXME: should we send this event again after (flushing) seek ? */
2840 stream->send_dvd_event = FALSE;
2846 static GstFlowReturn
2847 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2848 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2851 guint seq_header_len;
2852 guint32 header, tmp;
2854 if (stream->codec_state) {
2855 seq_header = stream->codec_state;
2856 seq_header_len = stream->codec_state_size;
2857 } else if (stream->codec_priv) {
2858 seq_header = stream->codec_priv;
2859 seq_header_len = stream->codec_priv_size;
2864 /* Sequence header only needed for keyframes */
2865 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2868 if (gst_buffer_get_size (*buf) < 4)
2871 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2872 header = GUINT32_FROM_BE (tmp);
2874 /* Sequence start code, if not found prepend */
2875 if (header != 0x000001b3) {
2878 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2880 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2883 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2884 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2885 gst_buffer_get_size (*buf));
2887 gst_buffer_unref (*buf);
2894 static GstFlowReturn
2895 gst_matroska_demux_add_wvpk_header (GstElement * element,
2896 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2898 GstMatroskaTrackAudioContext *audiocontext =
2899 (GstMatroskaTrackAudioContext *) stream;
2900 GstBuffer *newbuf = NULL;
2901 GstMapInfo map, outmap;
2902 guint8 *buf_data, *data;
2910 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2913 wvh.total_samples = -1;
2914 wvh.block_index = audiocontext->wvpk_block_index;
2916 if (audiocontext->channels <= 2) {
2917 guint32 block_samples, tmp;
2918 gsize size = gst_buffer_get_size (*buf);
2920 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2921 block_samples = GUINT32_FROM_LE (tmp);
2922 /* we need to reconstruct the header of the wavpack block */
2924 /* -20 because ck_size is the size of the wavpack block -8
2925 * and lace_size is the size of the wavpack block + 12
2926 * (the three guint32 of the header that already are in the buffer) */
2927 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2929 /* block_samples, flags and crc are already in the buffer */
2930 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2932 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2938 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2939 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2940 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2941 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2942 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2943 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2944 gst_buffer_unmap (newbuf, &outmap);
2946 /* Append data from buf: */
2947 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2948 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2950 gst_buffer_unref (*buf);
2952 audiocontext->wvpk_block_index += block_samples;
2954 guint8 *outdata = NULL;
2956 gsize buf_size, size, out_size = 0;
2957 guint32 block_samples, flags, crc, blocksize;
2959 gst_buffer_map (*buf, &map, GST_MAP_READ);
2960 buf_data = map.data;
2961 buf_size = map.size;
2964 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2965 gst_buffer_unmap (*buf, &map);
2966 return GST_FLOW_ERROR;
2972 block_samples = GST_READ_UINT32_LE (data);
2977 flags = GST_READ_UINT32_LE (data);
2980 crc = GST_READ_UINT32_LE (data);
2983 blocksize = GST_READ_UINT32_LE (data);
2987 if (blocksize == 0 || size < blocksize)
2990 g_assert ((newbuf == NULL) == (outdata == NULL));
2992 if (newbuf == NULL) {
2993 out_size = sizeof (Wavpack4Header) + blocksize;
2994 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2996 gst_buffer_copy_into (newbuf, *buf,
2997 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
3000 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3001 outdata = outmap.data;
3003 gst_buffer_unmap (newbuf, &outmap);
3004 out_size += sizeof (Wavpack4Header) + blocksize;
3005 gst_buffer_set_size (newbuf, out_size);
3006 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3007 outdata = outmap.data;
3010 outdata[outpos] = 'w';
3011 outdata[outpos + 1] = 'v';
3012 outdata[outpos + 2] = 'p';
3013 outdata[outpos + 3] = 'k';
3016 GST_WRITE_UINT32_LE (outdata + outpos,
3017 blocksize + sizeof (Wavpack4Header) - 8);
3018 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
3019 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
3020 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
3021 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
3022 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
3023 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
3024 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
3025 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
3028 memmove (outdata + outpos, data, blocksize);
3029 outpos += blocksize;
3033 gst_buffer_unmap (*buf, &map);
3034 gst_buffer_unref (*buf);
3037 gst_buffer_unmap (newbuf, &outmap);
3040 audiocontext->wvpk_block_index += block_samples;
3046 static GstFlowReturn
3047 gst_matroska_demux_add_prores_header (GstElement * element,
3048 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3050 GstBuffer *newbuf = gst_buffer_new_allocate (NULL, 8, NULL);
3054 if (!gst_buffer_map (newbuf, &map, GST_MAP_WRITE)) {
3055 GST_ERROR ("Failed to map newly allocated buffer");
3056 return GST_FLOW_ERROR;
3059 frame_size = gst_buffer_get_size (*buf);
3061 GST_WRITE_UINT32_BE (map.data, frame_size);
3067 gst_buffer_unmap (newbuf, &map);
3068 *buf = gst_buffer_append (newbuf, *buf);
3073 /* @text must be null-terminated */
3075 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
3080 g_return_val_if_fail (text != NULL, FALSE);
3082 /* yes, this might all lead to false positives ... */
3083 tag = (gchar *) text;
3084 while ((tag = strchr (tag, '<'))) {
3086 if (*tag != '\0' && *(tag + 1) == '>') {
3087 /* some common convenience ones */
3088 /* maybe any character will do here ? */
3101 if (strstr (text, "<span"))
3107 static GstFlowReturn
3108 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
3109 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3111 GstMatroskaTrackSubtitleContext *sub_stream;
3112 const gchar *encoding;
3117 gboolean needs_unmap = TRUE;
3119 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3121 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
3124 /* The subtitle buffer we push out should not include a NUL terminator as
3125 * part of the data. */
3126 if (map.data[map.size - 1] == '\0') {
3127 gst_buffer_set_size (*buf, map.size - 1);
3128 gst_buffer_unmap (*buf, &map);
3129 gst_buffer_map (*buf, &map, GST_MAP_READ);
3132 if (!sub_stream->invalid_utf8) {
3133 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
3136 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
3137 " is not valid UTF-8, this is broken according to the matroska"
3138 " specification", stream->num);
3139 sub_stream->invalid_utf8 = TRUE;
3142 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3143 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3144 if (encoding == NULL || *encoding == '\0') {
3145 /* if local encoding is UTF-8 and no encoding specified
3146 * via the environment variable, assume ISO-8859-15 */
3147 if (g_get_charset (&encoding)) {
3148 encoding = "ISO-8859-15";
3153 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3154 (char *) "*", NULL, NULL, &err);
3157 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3158 encoding, err->message);
3162 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3163 encoding = "ISO-8859-15";
3165 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3166 encoding, (char *) "*", NULL, NULL, NULL);
3169 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3170 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3173 utf8 = g_strdup ("invalid subtitle");
3175 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3176 gst_buffer_unmap (*buf, &map);
3177 gst_buffer_copy_into (newbuf, *buf,
3178 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3180 gst_buffer_unref (*buf);
3183 gst_buffer_map (*buf, &map, GST_MAP_READ);
3187 if (sub_stream->check_markup) {
3188 /* caps claim markup text, so we need to escape text,
3189 * except if text is already markup and then needs no further escaping */
3190 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3191 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3193 if (!sub_stream->seen_markup_tag) {
3194 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3196 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3197 gst_buffer_unmap (*buf, &map);
3198 gst_buffer_copy_into (newbuf, *buf,
3199 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3200 GST_BUFFER_COPY_META, 0, -1);
3201 gst_buffer_unref (*buf);
3204 needs_unmap = FALSE;
3209 gst_buffer_unmap (*buf, &map);
3214 static GstFlowReturn
3215 gst_matroska_demux_check_aac (GstElement * element,
3216 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3221 gst_buffer_extract (*buf, 0, data, 2);
3222 size = gst_buffer_get_size (*buf);
3224 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3227 /* tss, ADTS data, remove codec_data
3228 * still assume it is at least parsed */
3229 stream->caps = gst_caps_make_writable (stream->caps);
3230 s = gst_caps_get_structure (stream->caps, 0);
3232 gst_structure_remove_field (s, "codec_data");
3233 gst_pad_set_caps (stream->pad, stream->caps);
3234 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3235 "new caps: %" GST_PTR_FORMAT, stream->caps);
3238 /* disable subsequent checking */
3239 stream->postprocess_frame = NULL;
3245 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3246 GstBuffer * buffer, gsize alignment)
3250 gst_buffer_map (buffer, &map, GST_MAP_READ);
3252 if (map.size < sizeof (guintptr)) {
3253 gst_buffer_unmap (buffer, &map);
3257 if (((guintptr) map.data) & (alignment - 1)) {
3258 GstBuffer *new_buffer;
3259 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3261 new_buffer = gst_buffer_new_allocate (NULL,
3262 gst_buffer_get_size (buffer), ¶ms);
3264 /* Copy data "by hand", so ensure alignment is kept: */
3265 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3267 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3268 GST_DEBUG_OBJECT (demux,
3269 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3272 gst_buffer_unmap (buffer, &map);
3273 gst_buffer_unref (buffer);
3278 gst_buffer_unmap (buffer, &map);
3282 static GstFlowReturn
3283 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3284 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3285 gboolean is_simpleblock)
3287 GstMatroskaTrackContext *stream = NULL;
3288 GstFlowReturn ret = GST_FLOW_OK;
3289 gboolean readblock = FALSE;
3291 guint64 block_duration = -1;
3292 gint64 block_discardpadding = 0;
3293 GstBuffer *buf = NULL;
3295 gint stream_num = -1, n, laces = 0;
3297 gint *lace_size = NULL;
3300 gint64 referenceblock = 0;
3302 GstClockTime buffer_timestamp;
3304 offset = gst_ebml_read_get_offset (ebml);
3306 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3307 if (!is_simpleblock) {
3308 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3312 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3316 /* one block inside the group. Note, block parsing is one
3317 * of the harder things, so this code is a bit complicated.
3318 * See http://www.matroska.org/ for documentation. */
3319 case GST_MATROSKA_ID_SIMPLEBLOCK:
3320 case GST_MATROSKA_ID_BLOCK:
3326 gst_buffer_unmap (buf, &map);
3327 gst_buffer_unref (buf);
3330 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3333 gst_buffer_map (buf, &map, GST_MAP_READ);
3337 /* first byte(s): blocknum */
3338 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3343 /* fetch stream from num */
3344 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3346 if (G_UNLIKELY (size < 3)) {
3347 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3348 /* non-fatal, try next block(group) */
3351 } else if (G_UNLIKELY (stream_num < 0 ||
3352 stream_num >= demux->common.num_streams)) {
3353 /* let's not give up on a stray invalid track number */
3354 GST_WARNING_OBJECT (demux,
3355 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3356 "; ignoring block", stream_num, num);
3360 stream = g_ptr_array_index (demux->common.src, stream_num);
3362 /* time (relative to cluster time) */
3363 time = ((gint16) GST_READ_UINT16_BE (data));
3366 flags = GST_READ_UINT8 (data);
3370 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3373 switch ((flags & 0x06) >> 1) {
3374 case 0x0: /* no lacing */
3376 lace_size = g_new (gint, 1);
3377 lace_size[0] = size;
3380 case 0x1: /* xiph lacing */
3381 case 0x2: /* fixed-size lacing */
3382 case 0x3: /* EBML lacing */
3384 goto invalid_lacing;
3385 laces = GST_READ_UINT8 (data) + 1;
3388 lace_size = g_new0 (gint, laces);
3390 switch ((flags & 0x06) >> 1) {
3391 case 0x1: /* xiph lacing */ {
3392 guint temp, total = 0;
3394 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3397 goto invalid_lacing;
3398 temp = GST_READ_UINT8 (data);
3399 lace_size[n] += temp;
3405 total += lace_size[n];
3407 lace_size[n] = size - total;
3411 case 0x2: /* fixed-size lacing */
3412 for (n = 0; n < laces; n++)
3413 lace_size[n] = size / laces;
3416 case 0x3: /* EBML lacing */ {
3419 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3423 total = lace_size[0] = num;
3424 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3428 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3432 lace_size[n] = lace_size[n - 1] + snum;
3433 total += lace_size[n];
3436 lace_size[n] = size - total;
3443 if (ret != GST_FLOW_OK)
3450 case GST_MATROSKA_ID_BLOCKDURATION:{
3451 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3452 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3457 case GST_MATROSKA_ID_DISCARDPADDING:{
3458 ret = gst_ebml_read_sint (ebml, &id, &block_discardpadding);
3459 GST_DEBUG_OBJECT (demux, "DiscardPadding: %" GST_STIME_FORMAT,
3460 GST_STIME_ARGS (block_discardpadding));
3464 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3465 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3466 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3471 case GST_MATROSKA_ID_CODECSTATE:{
3473 guint64 data_len = 0;
3476 gst_ebml_read_binary (ebml, &id, &data,
3477 &data_len)) != GST_FLOW_OK)
3480 if (G_UNLIKELY (stream == NULL)) {
3481 GST_WARNING_OBJECT (demux,
3482 "Unexpected CodecState subelement - ignoring");
3486 g_free (stream->codec_state);
3487 stream->codec_state = data;
3488 stream->codec_state_size = data_len;
3490 /* Decode if necessary */
3491 if (stream->encodings && stream->encodings->len > 0
3492 && stream->codec_state && stream->codec_state_size > 0) {
3493 if (!gst_matroska_decode_data (stream->encodings,
3494 &stream->codec_state, &stream->codec_state_size,
3495 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3496 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3500 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3501 stream->codec_state_size);
3506 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3510 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3511 case GST_MATROSKA_ID_BLOCKADDITIONS:
3512 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3513 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3514 case GST_MATROSKA_ID_SLICES:
3515 GST_DEBUG_OBJECT (demux,
3516 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3517 ret = gst_ebml_read_skip (ebml);
3525 /* reading a number or so could have failed */
3526 if (ret != GST_FLOW_OK)
3529 if (ret == GST_FLOW_OK && readblock) {
3530 gboolean invisible_frame = FALSE;
3531 gboolean delta_unit = FALSE;
3532 guint64 duration = 0;
3533 gint64 lace_time = 0;
3535 stream = g_ptr_array_index (demux->common.src, stream_num);
3537 if (cluster_time != GST_CLOCK_TIME_NONE) {
3538 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3539 * Drop unless the lace contains timestamp 0? */
3540 if (time < 0 && (-time) > cluster_time) {
3543 if (stream->timecodescale == 1.0)
3544 lace_time = (cluster_time + time) * demux->common.time_scale;
3547 gst_util_guint64_to_gdouble ((cluster_time + time) *
3548 demux->common.time_scale) * stream->timecodescale;
3551 lace_time = GST_CLOCK_TIME_NONE;
3554 /* need to refresh segment info ASAP */
3555 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3556 GstSegment *segment = &demux->common.segment;
3558 GstEvent *segment_event;
3560 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3561 demux->stream_start_time = lace_time;
3562 GST_DEBUG_OBJECT (demux,
3563 "Setting stream start time to %" GST_TIME_FORMAT,
3564 GST_TIME_ARGS (lace_time));
3566 clace_time = MAX (lace_time, demux->stream_start_time);
3567 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3568 demux->common.segment.position != 0) {
3569 GST_DEBUG_OBJECT (demux,
3570 "using stored seek position %" GST_TIME_FORMAT,
3571 GST_TIME_ARGS (demux->common.segment.position));
3572 clace_time = demux->common.segment.position;
3573 segment->position = GST_CLOCK_TIME_NONE;
3575 segment->start = clace_time;
3576 segment->stop = GST_CLOCK_TIME_NONE;
3577 segment->time = segment->start - demux->stream_start_time;
3578 segment->position = segment->start - demux->stream_start_time;
3579 GST_DEBUG_OBJECT (demux,
3580 "generated segment starting at %" GST_TIME_FORMAT ": %"
3581 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3582 /* now convey our segment notion downstream */
3583 segment_event = gst_event_new_segment (segment);
3584 if (demux->segment_seqnum)
3585 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3586 gst_matroska_demux_send_event (demux, segment_event);
3587 demux->need_segment = FALSE;
3588 demux->segment_seqnum = 0;
3591 /* send pending codec data headers for all streams,
3592 * before we perform sync across all streams */
3593 gst_matroska_demux_push_codec_data_all (demux);
3595 if (block_duration != -1) {
3596 if (stream->timecodescale == 1.0)
3597 duration = gst_util_uint64_scale (block_duration,
3598 demux->common.time_scale, 1);
3601 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3602 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3603 1)) * stream->timecodescale);
3604 } else if (stream->default_duration) {
3605 duration = stream->default_duration * laces;
3607 /* else duration is diff between timecode of this and next block */
3609 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3610 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3611 a ReferenceBlock implies that this is not a keyframe. In either
3612 case, it only makes sense for video streams. */
3613 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3615 invisible_frame = ((flags & 0x08)) &&
3616 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3617 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3620 /* If we're doing a keyframe-only trickmode, only push keyframes on video
3624 segment.flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) {
3625 GST_LOG_OBJECT (demux, "Skipping non-keyframe on stream %d",
3632 for (n = 0; n < laces; n++) {
3635 if (G_UNLIKELY (lace_size[n] > size)) {
3636 GST_WARNING_OBJECT (demux, "Invalid lace size");
3640 /* QoS for video track with an index. the assumption is that
3641 index entries point to keyframes, but if that is not true we
3642 will instad skip until the next keyframe. */
3643 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3644 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3645 stream->index_table && demux->common.segment.rate > 0.0) {
3646 GstMatroskaTrackVideoContext *videocontext =
3647 (GstMatroskaTrackVideoContext *) stream;
3648 GstClockTime earliest_time;
3649 GstClockTime earliest_stream_time;
3651 GST_OBJECT_LOCK (demux);
3652 earliest_time = videocontext->earliest_time;
3653 GST_OBJECT_UNLOCK (demux);
3654 earliest_stream_time =
3655 gst_segment_position_from_running_time (&demux->common.segment,
3656 GST_FORMAT_TIME, earliest_time);
3658 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3659 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3660 lace_time <= earliest_stream_time) {
3661 /* find index entry (keyframe) <= earliest_stream_time */
3662 GstMatroskaIndex *entry =
3663 gst_util_array_binary_search (stream->index_table->data,
3664 stream->index_table->len, sizeof (GstMatroskaIndex),
3665 (GCompareDataFunc) gst_matroska_index_seek_find,
3666 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3668 /* if that entry (keyframe) is after the current the current
3669 buffer, we can skip pushing (and thus decoding) all
3670 buffers until that keyframe. */
3671 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3672 entry->time > lace_time) {
3673 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3674 stream->set_discont = TRUE;
3680 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3681 gst_buffer_get_size (buf) - size, lace_size[n]);
3682 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3685 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3687 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3689 if (invisible_frame)
3690 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3692 if (stream->encodings != NULL && stream->encodings->len > 0)
3693 sub = gst_matroska_decode_buffer (stream, sub);
3696 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3700 if (!stream->dts_only) {
3701 GST_BUFFER_PTS (sub) = lace_time;
3703 GST_BUFFER_DTS (sub) = lace_time;
3704 if (stream->intra_only)
3705 GST_BUFFER_PTS (sub) = lace_time;
3708 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
3710 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3711 GstClockTime last_stop_end;
3713 /* Check if this stream is after segment stop */
3714 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3715 lace_time >= demux->common.segment.stop) {
3716 GST_DEBUG_OBJECT (demux,
3717 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3718 GST_TIME_ARGS (demux->common.segment.stop));
3719 gst_buffer_unref (sub);
3722 if (offset >= stream->to_offset
3723 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3724 && lace_time > demux->to_time)) {
3725 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3727 gst_buffer_unref (sub);
3731 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3732 * that landed us with timestamps not quite intended */
3733 GST_OBJECT_LOCK (demux);
3734 if (demux->max_gap_time &&
3735 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3736 demux->common.segment.rate > 0.0) {
3737 GstClockTimeDiff diff;
3739 /* only send segments with increasing start times,
3740 * otherwise if these go back and forth downstream (sinks) increase
3741 * accumulated time and running_time */
3742 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3743 if (diff > 0 && diff > demux->max_gap_time
3744 && lace_time > demux->common.segment.start
3745 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3746 || lace_time < demux->common.segment.stop)) {
3748 GST_DEBUG_OBJECT (demux,
3749 "Gap of %" G_GINT64_FORMAT " ns detected in"
3750 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3751 "Sending updated SEGMENT events", diff,
3752 stream->index, GST_TIME_ARGS (stream->pos),
3753 GST_TIME_ARGS (lace_time));
3755 event = gst_event_new_gap (demux->last_stop_end, diff);
3756 GST_OBJECT_UNLOCK (demux);
3757 gst_pad_push_event (stream->pad, event);
3758 GST_OBJECT_LOCK (demux);
3762 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3763 || demux->common.segment.position < lace_time) {
3764 demux->common.segment.position = lace_time;
3766 GST_OBJECT_UNLOCK (demux);
3768 last_stop_end = lace_time;
3770 GST_BUFFER_DURATION (sub) = duration / laces;
3771 last_stop_end += GST_BUFFER_DURATION (sub);
3774 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3775 demux->last_stop_end < last_stop_end)
3776 demux->last_stop_end = last_stop_end;
3778 GST_OBJECT_LOCK (demux);
3779 if (demux->common.segment.duration == -1 ||
3780 demux->stream_start_time + demux->common.segment.duration <
3782 demux->common.segment.duration =
3783 last_stop_end - demux->stream_start_time;
3784 GST_OBJECT_UNLOCK (demux);
3785 if (!demux->invalid_duration) {
3786 gst_element_post_message (GST_ELEMENT_CAST (demux),
3787 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3788 demux->invalid_duration = TRUE;
3791 GST_OBJECT_UNLOCK (demux);
3795 stream->pos = lace_time;
3797 gst_matroska_demux_sync_streams (demux);
3799 if (stream->set_discont) {
3800 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3801 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3802 stream->set_discont = FALSE;
3804 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3807 /* reverse playback book-keeping */
3808 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3809 stream->from_time = lace_time;
3810 if (stream->from_offset == -1)
3811 stream->from_offset = offset;
3813 GST_DEBUG_OBJECT (demux,
3814 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3815 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3816 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3817 GST_TIME_ARGS (buffer_timestamp),
3818 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3821 if (demux->common.element_index) {
3822 if (stream->index_writer_id == -1)
3823 gst_index_get_writer_id (demux->common.element_index,
3824 GST_OBJECT (stream->pad), &stream->index_writer_id);
3826 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3827 G_GUINT64_FORMAT " for writer id %d",
3828 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
3829 stream->index_writer_id);
3830 gst_index_add_association (demux->common.element_index,
3831 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3832 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3833 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
3838 /* Postprocess the buffers depending on the codec used */
3839 if (stream->postprocess_frame) {
3840 GST_LOG_OBJECT (demux, "running post process");
3841 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3844 /* At this point, we have a sub-buffer pointing at data within a larger
3845 buffer. This data might not be aligned with anything. If the data is
3846 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3847 for 32 bit samples, etc), or bad things will happen downstream as
3848 elements typically assume minimal alignment.
3849 Therefore, create an aligned copy if necessary. */
3850 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3852 if (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
3853 guint64 start_clip = 0, end_clip = 0;
3855 /* Codec delay is part of the timestamps */
3856 if (GST_BUFFER_PTS_IS_VALID (sub) && stream->codec_delay) {
3857 if (GST_BUFFER_PTS (sub) > stream->codec_delay) {
3858 GST_BUFFER_PTS (sub) -= stream->codec_delay;
3860 GST_BUFFER_PTS (sub) = 0;
3862 gst_util_uint64_scale_round (stream->codec_delay, 48000,
3865 if (GST_BUFFER_DURATION_IS_VALID (sub)) {
3866 if (GST_BUFFER_DURATION (sub) > stream->codec_delay)
3867 GST_BUFFER_DURATION (sub) -= stream->codec_delay;
3869 GST_BUFFER_DURATION (sub) = 0;
3874 if (block_discardpadding) {
3876 gst_util_uint64_scale_round (block_discardpadding, 48000,
3880 if (start_clip || end_clip) {
3881 gst_buffer_add_audio_clipping_meta (sub, GST_FORMAT_DEFAULT,
3882 start_clip, end_clip);
3886 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3887 stream->pos = GST_BUFFER_PTS (sub);
3888 if (GST_BUFFER_DURATION_IS_VALID (sub))
3889 stream->pos += GST_BUFFER_DURATION (sub);
3890 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
3891 stream->pos = GST_BUFFER_DTS (sub);
3892 if (GST_BUFFER_DURATION_IS_VALID (sub))
3893 stream->pos += GST_BUFFER_DURATION (sub);
3896 ret = gst_pad_push (stream->pad, sub);
3898 if (demux->common.segment.rate < 0) {
3899 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3900 /* In reverse playback we can get a GST_FLOW_EOS when
3901 * we are at the end of the segment, so we just need to jump
3902 * back to the previous section. */
3903 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3908 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
3912 size -= lace_size[n];
3913 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3914 lace_time += duration / laces;
3916 lace_time = GST_CLOCK_TIME_NONE;
3922 gst_buffer_unmap (buf, &map);
3923 gst_buffer_unref (buf);
3935 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
3941 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3942 /* non-fatal, try next block(group) */
3948 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3949 /* non-fatal, try next block(group) */
3955 /* return FALSE if block(group) should be skipped (due to a seek) */
3956 static inline gboolean
3957 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3959 if (G_UNLIKELY (demux->seek_block)) {
3960 if (!(--demux->seek_block)) {
3963 GST_LOG_OBJECT (demux, "should skip block due to seek");
3971 static GstFlowReturn
3972 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3976 guint64 seek_pos = (guint64) - 1;
3977 guint32 seek_id = 0;
3980 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3982 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3983 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3987 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3988 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3992 case GST_MATROSKA_ID_SEEKID:
3996 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3999 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
4004 case GST_MATROSKA_ID_SEEKPOSITION:
4008 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4011 if (t > G_MAXINT64) {
4012 GST_WARNING_OBJECT (demux,
4013 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
4017 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
4023 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
4029 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
4032 if (!seek_id || seek_pos == (guint64) - 1) {
4033 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
4034 G_GUINT64_FORMAT ")", seek_id, seek_pos);
4039 case GST_MATROSKA_ID_SEEKHEAD:
4042 case GST_MATROSKA_ID_CUES:
4043 case GST_MATROSKA_ID_TAGS:
4044 case GST_MATROSKA_ID_TRACKS:
4045 case GST_MATROSKA_ID_SEGMENTINFO:
4046 case GST_MATROSKA_ID_ATTACHMENTS:
4047 case GST_MATROSKA_ID_CHAPTERS:
4049 guint64 before_pos, length;
4053 length = gst_matroska_read_common_get_length (&demux->common);
4054 before_pos = demux->common.offset;
4056 if (length == (guint64) - 1) {
4057 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
4061 /* check for validity */
4062 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
4063 GST_WARNING_OBJECT (demux,
4064 "SeekHead reference lies outside file!" " (%"
4065 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
4066 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
4071 /* only pick up index location when streaming */
4072 if (demux->streaming) {
4073 if (seek_id == GST_MATROSKA_ID_CUES) {
4074 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
4075 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
4076 demux->index_offset);
4082 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
4085 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4086 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
4090 if (id != seek_id) {
4091 GST_WARNING_OBJECT (demux,
4092 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
4093 seek_id, id, seek_pos + demux->common.ebml_segment_start);
4096 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4101 demux->common.offset = before_pos;
4105 case GST_MATROSKA_ID_CLUSTER:
4107 guint64 pos = seek_pos + demux->common.ebml_segment_start;
4109 GST_LOG_OBJECT (demux, "Cluster position");
4110 if (G_UNLIKELY (!demux->clusters))
4111 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
4112 g_array_append_val (demux->clusters, pos);
4117 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
4120 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4125 static GstFlowReturn
4126 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4128 GstFlowReturn ret = GST_FLOW_OK;
4131 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4133 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4134 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4138 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4139 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4143 case GST_MATROSKA_ID_SEEKENTRY:
4145 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
4146 /* Ignore EOS and errors here */
4147 if (ret != GST_FLOW_OK) {
4148 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4155 ret = gst_matroska_read_common_parse_skip (&demux->common,
4156 ebml, "SeekHead", id);
4161 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4163 /* Sort clusters by position for easier searching */
4164 if (demux->clusters)
4165 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4170 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
4172 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4174 static inline GstFlowReturn
4175 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4177 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4178 /* only a few blocks are expected/allowed to be large,
4179 * and will be recursed into, whereas others will be read and must fit */
4180 if (demux->streaming) {
4181 /* fatal in streaming case, as we can't step over easily */
4182 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4183 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4184 "file might be corrupt.", bytes));
4185 return GST_FLOW_ERROR;
4187 /* indicate higher level to quietly give up */
4188 GST_DEBUG_OBJECT (demux,
4189 "too large block of size %" G_GUINT64_FORMAT, bytes);
4190 return GST_FLOW_ERROR;
4197 /* returns TRUE if we truely are in error state, and should give up */
4198 static inline GstFlowReturn
4199 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4201 if (!demux->streaming && demux->next_cluster_offset > 0) {
4202 /* just repositioning to where next cluster should be and try from there */
4203 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4204 G_GUINT64_FORMAT, demux->next_cluster_offset);
4205 demux->common.offset = demux->next_cluster_offset;
4206 demux->next_cluster_offset = 0;
4212 /* sigh, one last attempt above and beyond call of duty ...;
4213 * search for cluster mark following current pos */
4214 pos = demux->common.offset;
4215 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4216 if ((ret = gst_matroska_demux_search_cluster (demux, &pos, TRUE)) !=
4218 /* did not work, give up */
4221 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4222 /* try that position */
4223 demux->common.offset = pos;
4229 static inline GstFlowReturn
4230 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4232 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4233 demux->common.offset += flush;
4234 if (demux->streaming) {
4237 /* hard to skip large blocks when streaming */
4238 ret = gst_matroska_demux_check_read_size (demux, flush);
4239 if (ret != GST_FLOW_OK)
4241 if (flush <= gst_adapter_available (demux->common.adapter))
4242 gst_adapter_flush (demux->common.adapter, flush);
4244 return GST_FLOW_EOS;
4249 /* initializes @ebml with @bytes from input stream at current offset.
4250 * Returns EOS if insufficient available,
4251 * ERROR if too much was attempted to read. */
4252 static inline GstFlowReturn
4253 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4256 GstBuffer *buffer = NULL;
4257 GstFlowReturn ret = GST_FLOW_OK;
4259 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4261 ret = gst_matroska_demux_check_read_size (demux, bytes);
4262 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4263 if (!demux->streaming) {
4264 /* in pull mode, we can skip */
4265 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4266 ret = GST_FLOW_OVERFLOW;
4268 /* otherwise fatal */
4269 ret = GST_FLOW_ERROR;
4273 if (demux->streaming) {
4274 if (gst_adapter_available (demux->common.adapter) >= bytes)
4275 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4279 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4280 demux->common.offset, bytes, &buffer, NULL);
4281 if (G_LIKELY (buffer)) {
4282 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4283 demux->common.offset);
4284 demux->common.offset += bytes;
4291 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4294 gboolean seekable = FALSE;
4295 gint64 start = -1, stop = -1;
4297 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4298 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4299 GST_DEBUG_OBJECT (demux, "seeking query failed");
4303 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4305 /* try harder to query upstream size if we didn't get it the first time */
4306 if (seekable && stop == -1) {
4307 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4308 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4312 /* if upstream doesn't know the size, it's likely that it's not seekable in
4313 * practice even if it technically may be seekable */
4314 if (seekable && (start != 0 || stop <= start)) {
4315 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4320 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4321 G_GUINT64_FORMAT ")", seekable, start, stop);
4322 demux->seekable = seekable;
4324 gst_query_unref (query);
4327 static GstFlowReturn
4328 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4334 GstFlowReturn ret = GST_FLOW_OK;
4336 GST_WARNING_OBJECT (demux,
4337 "Found Cluster element before Tracks, searching Tracks");
4340 before_pos = demux->common.offset;
4342 /* Search Tracks element */
4344 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4345 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4346 if (ret != GST_FLOW_OK)
4349 if (id != GST_MATROSKA_ID_TRACKS) {
4350 /* we may be skipping large cluster here, so forego size check etc */
4351 /* ... but we can't skip undefined size; force error */
4352 if (length == G_MAXUINT64) {
4353 ret = gst_matroska_demux_check_read_size (demux, length);
4356 demux->common.offset += needed;
4357 demux->common.offset += length;
4362 /* will lead to track parsing ... */
4363 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4368 demux->common.offset = before_pos;
4373 #define GST_READ_CHECK(stmt) \
4375 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4376 if (ret == GST_FLOW_OVERFLOW) { \
4377 ret = GST_FLOW_OK; \
4383 static GstFlowReturn
4384 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4385 guint64 length, guint needed)
4387 GstEbmlRead ebml = { 0, };
4388 GstFlowReturn ret = GST_FLOW_OK;
4391 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4392 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4394 /* if we plan to read and parse this element, we need prefix (id + length)
4395 * and the contents */
4396 /* mind about overflow wrap-around when dealing with undefined size */
4398 if (G_LIKELY (length != G_MAXUINT64))
4401 switch (demux->common.state) {
4402 case GST_MATROSKA_READ_STATE_START:
4404 case GST_EBML_ID_HEADER:
4405 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4406 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4407 if (ret != GST_FLOW_OK)
4409 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4410 gst_matroska_demux_check_seekability (demux);
4413 goto invalid_header;
4417 case GST_MATROSKA_READ_STATE_SEGMENT:
4419 case GST_MATROSKA_ID_SEGMENT:
4420 /* eat segment prefix */
4421 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4422 GST_DEBUG_OBJECT (demux,
4423 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4424 G_GUINT64_FORMAT, demux->common.offset, length);
4425 /* seeks are from the beginning of the segment,
4426 * after the segment ID/length */
4427 demux->common.ebml_segment_start = demux->common.offset;
4429 length = G_MAXUINT64;
4430 demux->common.ebml_segment_length = length;
4431 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4434 GST_WARNING_OBJECT (demux,
4435 "Expected a Segment ID (0x%x), but received 0x%x!",
4436 GST_MATROSKA_ID_SEGMENT, id);
4437 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4441 case GST_MATROSKA_READ_STATE_SCANNING:
4442 if (id != GST_MATROSKA_ID_CLUSTER &&
4443 id != GST_MATROSKA_ID_CLUSTERTIMECODE) {
4444 if (demux->common.start_resync_offset != -1) {
4445 /* we need to skip byte per byte if we are scanning for a new cluster
4446 * after invalid data is found
4452 if (demux->common.start_resync_offset != -1) {
4453 GST_LOG_OBJECT (demux, "Resync done, new cluster found!");
4454 demux->common.start_resync_offset = -1;
4455 demux->common.state = demux->common.state_to_restore;
4459 case GST_MATROSKA_READ_STATE_HEADER:
4460 case GST_MATROSKA_READ_STATE_DATA:
4461 case GST_MATROSKA_READ_STATE_SEEK:
4463 case GST_MATROSKA_ID_SEGMENTINFO:
4464 if (!demux->common.segmentinfo_parsed) {
4465 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4466 ret = gst_matroska_read_common_parse_info (&demux->common,
4467 GST_ELEMENT_CAST (demux), &ebml);
4468 if (ret == GST_FLOW_OK)
4469 gst_matroska_demux_send_tags (demux);
4471 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4474 case GST_MATROSKA_ID_TRACKS:
4475 if (!demux->tracks_parsed) {
4476 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4477 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4479 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4482 case GST_MATROSKA_ID_CLUSTER:
4483 if (G_UNLIKELY (!demux->tracks_parsed)) {
4484 if (demux->streaming) {
4485 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4486 goto not_streamable;
4488 ret = gst_matroska_demux_find_tracks (demux);
4489 if (!demux->tracks_parsed)
4493 if (G_UNLIKELY (demux->common.state
4494 == GST_MATROSKA_READ_STATE_HEADER)) {
4495 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4496 demux->first_cluster_offset = demux->common.offset;
4497 if (!demux->streaming &&
4498 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.duration)) {
4499 GstMatroskaIndex *last = NULL;
4501 GST_DEBUG_OBJECT (demux,
4502 "estimating duration using last cluster");
4503 if ((last = gst_matroska_demux_search_pos (demux,
4504 GST_CLOCK_TIME_NONE)) != NULL) {
4505 demux->last_cluster_offset =
4506 last->pos + demux->common.ebml_segment_start;
4507 demux->stream_last_time = last->time;
4508 demux->common.segment.duration =
4509 demux->stream_last_time - demux->stream_start_time;
4510 /* above estimate should not be taken all too strongly */
4511 demux->invalid_duration = TRUE;
4512 GST_DEBUG_OBJECT (demux,
4513 "estimated duration as %" GST_TIME_FORMAT,
4514 GST_TIME_ARGS (demux->common.segment.duration));
4517 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4518 gst_element_no_more_pads (GST_ELEMENT (demux));
4519 /* send initial segment - we wait till we know the first
4520 incoming timestamp, so we can properly set the start of
4522 demux->need_segment = TRUE;
4524 demux->cluster_time = GST_CLOCK_TIME_NONE;
4525 demux->cluster_offset = demux->common.offset;
4526 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4527 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4528 " not found in Cluster, trying next Cluster's first block instead",
4530 demux->seek_block = 0;
4532 demux->seek_first = FALSE;
4533 /* record next cluster for recovery */
4534 if (read != G_MAXUINT64)
4535 demux->next_cluster_offset = demux->cluster_offset + read;
4536 /* eat cluster prefix */
4537 gst_matroska_demux_flush (demux, needed);
4539 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4543 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4544 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4546 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4547 demux->cluster_time = num;
4548 /* track last cluster */
4549 if (demux->cluster_offset > demux->last_cluster_offset) {
4550 demux->last_cluster_offset = demux->cluster_offset;
4551 demux->stream_last_time =
4552 demux->cluster_time * demux->common.time_scale;
4555 if (demux->common.element_index) {
4556 if (demux->common.element_index_writer_id == -1)
4557 gst_index_get_writer_id (demux->common.element_index,
4558 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4559 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4560 G_GUINT64_FORMAT " for writer id %d",
4561 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4562 demux->common.element_index_writer_id);
4563 gst_index_add_association (demux->common.element_index,
4564 demux->common.element_index_writer_id,
4565 GST_ASSOCIATION_FLAG_KEY_UNIT,
4566 GST_FORMAT_TIME, demux->cluster_time,
4567 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4572 case GST_MATROSKA_ID_BLOCKGROUP:
4573 if (!gst_matroska_demux_seek_block (demux))
4575 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4576 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4577 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4578 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4579 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4581 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4583 case GST_MATROSKA_ID_SIMPLEBLOCK:
4584 if (!gst_matroska_demux_seek_block (demux))
4586 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4587 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4588 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4589 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4590 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4592 case GST_MATROSKA_ID_ATTACHMENTS:
4593 if (!demux->common.attachments_parsed) {
4594 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4595 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4596 GST_ELEMENT_CAST (demux), &ebml);
4597 if (ret == GST_FLOW_OK)
4598 gst_matroska_demux_send_tags (demux);
4600 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4603 case GST_MATROSKA_ID_TAGS:
4604 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4605 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4606 GST_ELEMENT_CAST (demux), &ebml);
4607 if (ret == GST_FLOW_OK)
4608 gst_matroska_demux_send_tags (demux);
4610 case GST_MATROSKA_ID_CHAPTERS:
4611 if (!demux->common.chapters_parsed) {
4612 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4614 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4616 if (demux->common.toc) {
4617 gst_matroska_demux_send_event (demux,
4618 gst_event_new_toc (demux->common.toc, FALSE));
4621 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4623 case GST_MATROSKA_ID_SEEKHEAD:
4624 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4625 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4627 case GST_MATROSKA_ID_CUES:
4628 if (demux->common.index_parsed) {
4629 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4632 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4633 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4634 /* only push based; delayed index building */
4635 if (ret == GST_FLOW_OK
4636 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4639 GST_OBJECT_LOCK (demux);
4640 event = demux->seek_event;
4641 demux->seek_event = NULL;
4642 GST_OBJECT_UNLOCK (demux);
4645 /* unlikely to fail, since we managed to seek to this point */
4646 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
4647 gst_event_unref (event);
4650 gst_event_unref (event);
4651 /* resume data handling, main thread clear to seek again */
4652 GST_OBJECT_LOCK (demux);
4653 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4654 GST_OBJECT_UNLOCK (demux);
4657 case GST_MATROSKA_ID_POSITION:
4658 case GST_MATROSKA_ID_PREVSIZE:
4659 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4660 case GST_MATROSKA_ID_SILENTTRACKS:
4661 GST_DEBUG_OBJECT (demux,
4662 "Skipping Cluster subelement 0x%x - ignoring", id);
4666 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4667 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4673 if (ret == GST_FLOW_PARSE)
4677 gst_ebml_read_clear (&ebml);
4683 /* simply exit, maybe not enough data yet */
4684 /* no ebml to clear if read error */
4689 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4690 ("Failed to parse Element 0x%x", id));
4691 ret = GST_FLOW_ERROR;
4696 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4697 ("File layout does not permit streaming"));
4698 ret = GST_FLOW_ERROR;
4703 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4704 ("No Tracks element found"));
4705 ret = GST_FLOW_ERROR;
4710 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4711 ret = GST_FLOW_ERROR;
4716 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4717 ret = GST_FLOW_ERROR;
4723 gst_matroska_demux_loop (GstPad * pad)
4725 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4731 /* If we have to close a segment, send a new segment to do this now */
4732 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4733 if (G_UNLIKELY (demux->new_segment)) {
4734 gst_matroska_demux_send_event (demux, demux->new_segment);
4735 demux->new_segment = NULL;
4739 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4740 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4741 if (ret == GST_FLOW_EOS) {
4743 } else if (ret == GST_FLOW_FLUSHING) {
4745 } else if (ret != GST_FLOW_OK) {
4746 ret = gst_matroska_demux_check_parse_error (demux);
4748 /* Only handle EOS as no error if we're outside the segment already */
4749 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4750 && demux->common.offset >=
4751 demux->common.ebml_segment_start +
4752 demux->common.ebml_segment_length))
4754 else if (ret != GST_FLOW_OK)
4760 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4761 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4764 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4765 if (ret == GST_FLOW_EOS)
4767 if (ret != GST_FLOW_OK)
4770 /* check if we're at the end of a configured segment */
4771 if (G_LIKELY (demux->common.src->len)) {
4774 g_assert (demux->common.num_streams == demux->common.src->len);
4775 for (i = 0; i < demux->common.src->len; i++) {
4776 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4778 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4779 GST_TIME_ARGS (context->pos));
4780 if (context->eos == FALSE)
4784 GST_INFO_OBJECT (demux, "All streams are EOS");
4790 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4791 demux->common.offset >= demux->cached_length)) {
4792 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4793 if (demux->common.offset == demux->cached_length) {
4794 GST_LOG_OBJECT (demux, "Reached end of stream");
4805 if (demux->common.segment.rate < 0.0) {
4806 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4807 if (ret == GST_FLOW_OK)
4814 const gchar *reason = gst_flow_get_name (ret);
4815 gboolean push_eos = FALSE;
4817 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4818 gst_pad_pause_task (demux->common.sinkpad);
4820 if (ret == GST_FLOW_EOS) {
4821 /* perform EOS logic */
4823 /* If we were in the headers, make sure we send no-more-pads.
4824 This will ensure decodebin does not get stuck thinking
4825 the chain is not complete yet, and waiting indefinitely. */
4826 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4827 if (demux->common.src->len == 0) {
4828 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4829 ("No pads created"));
4831 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4832 ("Failed to finish reading headers"));
4834 gst_element_no_more_pads (GST_ELEMENT (demux));
4837 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4842 /* for segment playback we need to post when (in stream time)
4843 * we stopped, this is either stop (when set) or the duration. */
4844 if ((stop = demux->common.segment.stop) == -1)
4845 stop = demux->last_stop_end;
4847 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4848 msg = gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4850 if (demux->segment_seqnum)
4851 gst_message_set_seqnum (msg, demux->segment_seqnum);
4852 gst_element_post_message (GST_ELEMENT (demux), msg);
4854 event = gst_event_new_segment_done (GST_FORMAT_TIME, stop);
4855 if (demux->segment_seqnum)
4856 gst_event_set_seqnum (event, demux->segment_seqnum);
4857 gst_matroska_demux_send_event (demux, event);
4861 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4862 /* for fatal errors we post an error message */
4863 GST_ELEMENT_FLOW_ERROR (demux, ret);
4869 /* send EOS, and prevent hanging if no streams yet */
4870 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4871 event = gst_event_new_eos ();
4872 if (demux->segment_seqnum)
4873 gst_event_set_seqnum (event, demux->segment_seqnum);
4874 if (!gst_matroska_demux_send_event (demux, event) &&
4875 (ret == GST_FLOW_EOS)) {
4876 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4877 (NULL), ("got eos but no streams (yet)"));
4885 * Create and push a flushing seek event upstream
4888 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4889 guint32 seqnum, GstSeekFlags flags)
4894 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4897 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4898 flags | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
4899 GST_SEEK_TYPE_SET, offset, GST_SEEK_TYPE_NONE, -1);
4900 gst_event_set_seqnum (event, seqnum);
4902 res = gst_pad_push_event (demux->common.sinkpad, event);
4904 /* segment event will update offset */
4908 static GstFlowReturn
4909 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4911 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4913 GstFlowReturn ret = GST_FLOW_OK;
4918 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4919 GST_DEBUG_OBJECT (demux, "got DISCONT");
4920 gst_adapter_clear (demux->common.adapter);
4921 GST_OBJECT_LOCK (demux);
4922 gst_matroska_read_common_reset_streams (&demux->common,
4923 GST_CLOCK_TIME_NONE, FALSE);
4924 GST_OBJECT_UNLOCK (demux);
4927 gst_adapter_push (demux->common.adapter, buffer);
4931 available = gst_adapter_available (demux->common.adapter);
4933 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4934 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4935 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4936 if (demux->common.ebml_segment_length != G_MAXUINT64
4937 && demux->common.offset >=
4938 demux->common.ebml_segment_start + demux->common.ebml_segment_length) {
4941 gint64 bytes_scanned;
4942 if (demux->common.start_resync_offset == -1) {
4943 demux->common.start_resync_offset = demux->common.offset;
4944 demux->common.state_to_restore = demux->common.state;
4946 bytes_scanned = demux->common.offset - demux->common.start_resync_offset;
4947 if (bytes_scanned <= INVALID_DATA_THRESHOLD) {
4948 GST_WARNING_OBJECT (demux,
4949 "parse error, looking for next cluster, actual offset %"
4950 G_GUINT64_FORMAT ", start resync offset %" G_GUINT64_FORMAT,
4951 demux->common.offset, demux->common.start_resync_offset);
4952 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
4955 GST_WARNING_OBJECT (demux,
4956 "unrecoverable parse error, next cluster not found and threshold "
4957 "exceeded, bytes scanned %" G_GINT64_FORMAT, bytes_scanned);
4963 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4964 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4965 demux->common.offset, id, length, needed, available);
4967 if (needed > available)
4970 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4971 if (ret == GST_FLOW_EOS) {
4972 /* need more data */
4974 } else if (ret != GST_FLOW_OK) {
4981 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4984 gboolean res = TRUE;
4985 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4987 GST_DEBUG_OBJECT (demux,
4988 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4990 switch (GST_EVENT_TYPE (event)) {
4991 case GST_EVENT_SEGMENT:
4993 const GstSegment *segment;
4995 /* some debug output */
4996 gst_event_parse_segment (event, &segment);
4997 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4998 GST_DEBUG_OBJECT (demux,
4999 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
5002 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
5003 GST_DEBUG_OBJECT (demux, "still starting");
5007 /* we only expect a BYTE segment, e.g. following a seek */
5008 if (segment->format != GST_FORMAT_BYTES) {
5009 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
5013 GST_DEBUG_OBJECT (demux, "clearing segment state");
5014 GST_OBJECT_LOCK (demux);
5015 /* clear current segment leftover */
5016 gst_adapter_clear (demux->common.adapter);
5017 /* and some streaming setup */
5018 demux->common.offset = segment->start;
5019 /* accumulate base based on current position */
5020 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
5021 demux->common.segment.base +=
5022 (MAX (demux->common.segment.position, demux->stream_start_time)
5023 - demux->stream_start_time) / fabs (demux->common.segment.rate);
5024 /* do not know where we are;
5025 * need to come across a cluster and generate segment */
5026 demux->common.segment.position = GST_CLOCK_TIME_NONE;
5027 demux->cluster_time = GST_CLOCK_TIME_NONE;
5028 demux->cluster_offset = 0;
5029 demux->need_segment = TRUE;
5030 demux->segment_seqnum = gst_event_get_seqnum (event);
5031 /* but keep some of the upstream segment */
5032 demux->common.segment.rate = segment->rate;
5033 demux->common.segment.flags = segment->flags;
5034 /* also check if need to keep some of the requested seek position */
5035 if (demux->seek_offset == segment->start) {
5036 GST_DEBUG_OBJECT (demux, "position matches requested seek");
5037 demux->common.segment.position = demux->requested_seek_time;
5039 GST_DEBUG_OBJECT (demux, "unexpected segment position");
5041 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
5042 demux->seek_offset = -1;
5043 GST_OBJECT_UNLOCK (demux);
5045 /* chain will send initial segment after pads have been added,
5046 * or otherwise come up with one */
5047 GST_DEBUG_OBJECT (demux, "eating event");
5048 gst_event_unref (event);
5054 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA
5055 && demux->common.state != GST_MATROSKA_READ_STATE_SCANNING) {
5056 gst_event_unref (event);
5057 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5058 (NULL), ("got eos and didn't receive a complete header object"));
5059 } else if (demux->common.num_streams == 0) {
5060 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5061 (NULL), ("got eos but no streams (yet)"));
5063 gst_matroska_demux_send_event (demux, event);
5067 case GST_EVENT_FLUSH_STOP:
5071 gst_adapter_clear (demux->common.adapter);
5072 GST_OBJECT_LOCK (demux);
5073 gst_matroska_read_common_reset_streams (&demux->common,
5074 GST_CLOCK_TIME_NONE, TRUE);
5075 gst_flow_combiner_reset (demux->flowcombiner);
5076 dur = demux->common.segment.duration;
5077 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
5078 demux->common.segment.duration = dur;
5079 demux->cluster_time = GST_CLOCK_TIME_NONE;
5080 demux->cluster_offset = 0;
5081 GST_OBJECT_UNLOCK (demux);
5085 res = gst_pad_event_default (pad, parent, event);
5093 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
5095 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5097 gboolean pull_mode = FALSE;
5099 query = gst_query_new_scheduling ();
5101 if (gst_pad_peer_query (sinkpad, query))
5102 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
5103 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
5105 gst_query_unref (query);
5108 GST_DEBUG ("going to pull mode");
5109 demux->streaming = FALSE;
5110 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
5112 GST_DEBUG ("going to push (streaming) mode");
5113 demux->streaming = TRUE;
5114 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
5119 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
5120 GstPadMode mode, gboolean active)
5123 case GST_PAD_MODE_PULL:
5125 /* if we have a scheduler we can start the task */
5126 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
5129 gst_pad_stop_task (sinkpad);
5132 case GST_PAD_MODE_PUSH:
5140 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
5141 videocontext, const gchar * codec_id, guint8 * data, guint size,
5142 gchar ** codec_name, guint32 * riff_fourcc)
5144 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
5145 GstCaps *caps = NULL;
5147 g_assert (videocontext != NULL);
5148 g_assert (codec_name != NULL);
5153 /* TODO: check if we have all codec types from matroska-ids.h
5154 * check if we have to do more special things with codec_private
5157 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
5158 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
5161 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
5162 gst_riff_strf_vids *vids = NULL;
5165 GstBuffer *buf = NULL;
5167 vids = (gst_riff_strf_vids *) data;
5169 /* assure size is big enough */
5171 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
5174 if (size < sizeof (gst_riff_strf_vids)) {
5175 vids = g_new (gst_riff_strf_vids, 1);
5176 memcpy (vids, data, size);
5179 context->dts_only = TRUE; /* VFW files only store DTS */
5181 /* little-endian -> byte-order */
5182 vids->size = GUINT32_FROM_LE (vids->size);
5183 vids->width = GUINT32_FROM_LE (vids->width);
5184 vids->height = GUINT32_FROM_LE (vids->height);
5185 vids->planes = GUINT16_FROM_LE (vids->planes);
5186 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
5187 vids->compression = GUINT32_FROM_LE (vids->compression);
5188 vids->image_size = GUINT32_FROM_LE (vids->image_size);
5189 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
5190 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
5191 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
5192 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
5194 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
5195 gsize offset = sizeof (gst_riff_strf_vids);
5198 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
5199 size - offset), size - offset);
5203 *riff_fourcc = vids->compression;
5205 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
5206 buf, NULL, codec_name);
5209 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
5210 GST_FOURCC_ARGS (vids->compression));
5212 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
5213 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
5214 "video/x-compressed-yuv");
5215 context->intra_only =
5216 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
5220 gst_buffer_unref (buf);
5222 if (vids != (gst_riff_strf_vids *) data)
5225 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
5227 GstVideoFormat format;
5229 gst_video_info_init (&info);
5230 switch (videocontext->fourcc) {
5231 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5232 format = GST_VIDEO_FORMAT_I420;
5234 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5235 format = GST_VIDEO_FORMAT_YUY2;
5237 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5238 format = GST_VIDEO_FORMAT_YV12;
5240 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5241 format = GST_VIDEO_FORMAT_UYVY;
5243 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5244 format = GST_VIDEO_FORMAT_AYUV;
5246 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
5247 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
5248 format = GST_VIDEO_FORMAT_GRAY8;
5250 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
5251 format = GST_VIDEO_FORMAT_RGB;
5253 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
5254 format = GST_VIDEO_FORMAT_BGR;
5257 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5258 GST_FOURCC_ARGS (videocontext->fourcc));
5262 context->intra_only = TRUE;
5264 gst_video_info_set_format (&info, format, videocontext->pixel_width,
5265 videocontext->pixel_height);
5266 caps = gst_video_info_to_caps (&info);
5267 *codec_name = gst_pb_utils_get_codec_description (caps);
5268 context->alignment = 32;
5269 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5270 caps = gst_caps_new_simple ("video/x-divx",
5271 "divxversion", G_TYPE_INT, 4, NULL);
5272 *codec_name = g_strdup ("MPEG-4 simple profile");
5273 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5274 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5275 caps = gst_caps_new_simple ("video/mpeg",
5276 "mpegversion", G_TYPE_INT, 4,
5277 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5281 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5282 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5283 gst_buffer_unref (priv);
5285 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
5287 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5288 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5290 *codec_name = g_strdup ("MPEG-4 advanced profile");
5291 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5293 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5294 "divxversion", G_TYPE_INT, 3, NULL),
5295 gst_structure_new ("video/x-msmpeg",
5296 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5298 caps = gst_caps_new_simple ("video/x-msmpeg",
5299 "msmpegversion", G_TYPE_INT, 43, NULL);
5300 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5301 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5302 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5305 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5310 caps = gst_caps_new_simple ("video/mpeg",
5311 "systemstream", G_TYPE_BOOLEAN, FALSE,
5312 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5313 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5314 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5315 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5316 caps = gst_caps_new_empty_simple ("image/jpeg");
5317 *codec_name = g_strdup ("Motion-JPEG");
5318 context->intra_only = TRUE;
5319 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5320 caps = gst_caps_new_empty_simple ("video/x-h264");
5324 /* First byte is the version, second is the profile indication, and third
5325 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5326 * level indication. */
5327 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5330 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5331 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5332 gst_buffer_unref (priv);
5334 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5335 "alignment", G_TYPE_STRING, "au", NULL);
5337 GST_WARNING ("No codec data found, assuming output is byte-stream");
5338 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5341 *codec_name = g_strdup ("H264");
5342 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
5343 caps = gst_caps_new_empty_simple ("video/x-h265");
5347 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
5350 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5351 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5352 gst_buffer_unref (priv);
5354 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
5355 "alignment", G_TYPE_STRING, "au", NULL);
5357 GST_WARNING ("No codec data found, assuming output is byte-stream");
5358 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5361 *codec_name = g_strdup ("HEVC");
5362 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5363 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5364 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5365 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5366 gint rmversion = -1;
5368 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5370 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5372 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5374 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5377 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5378 "rmversion", G_TYPE_INT, rmversion, NULL);
5379 GST_DEBUG ("data:%p, size:0x%x", data, size);
5380 /* We need to extract the extradata ! */
5381 if (data && (size >= 0x22)) {
5386 subformat = GST_READ_UINT32_BE (data + 0x1a);
5387 rformat = GST_READ_UINT32_BE (data + 0x1e);
5390 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5392 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5393 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5394 gst_buffer_unref (priv);
5397 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5398 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5399 caps = gst_caps_new_empty_simple ("video/x-theora");
5400 context->stream_headers =
5401 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5402 context->codec_priv_size);
5403 /* FIXME: mark stream as broken and skip if there are no stream headers */
5404 context->send_stream_headers = TRUE;
5405 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5406 caps = gst_caps_new_empty_simple ("video/x-dirac");
5407 *codec_name = g_strdup_printf ("Dirac");
5408 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5409 caps = gst_caps_new_empty_simple ("video/x-vp8");
5410 *codec_name = g_strdup_printf ("On2 VP8");
5411 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5412 caps = gst_caps_new_empty_simple ("video/x-vp9");
5413 *codec_name = g_strdup_printf ("On2 VP9");
5414 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
5416 const gchar *variant, *variant_descr = "";
5418 /* Expect a fourcc in the codec private data */
5419 if (!data || size < 4) {
5420 GST_WARNING ("No or too small PRORESS fourcc (%d bytes)", size);
5424 fourcc = GST_STR_FOURCC (data);
5426 case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
5427 variant_descr = " 4:2:2 LT";
5430 case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
5432 variant_descr = " 4:2:2 HQ";
5434 case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
5436 variant_descr = " 4:4:4:4";
5438 case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
5440 variant_descr = " 4:2:2 Proxy";
5442 case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
5444 variant = "standard";
5445 variant_descr = " 4:2:2 SD";
5449 GST_LOG ("Prores video, codec fourcc %" GST_FOURCC_FORMAT,
5450 GST_FOURCC_ARGS (fourcc));
5452 caps = gst_caps_new_simple ("video/x-prores",
5453 "format", G_TYPE_STRING, variant, NULL);
5454 *codec_name = g_strdup_printf ("Apple ProRes%s", variant_descr);
5455 context->postprocess_frame = gst_matroska_demux_add_prores_header;
5457 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5463 GstStructure *structure;
5465 for (i = 0; i < gst_caps_get_size (caps); i++) {
5466 structure = gst_caps_get_structure (caps, i);
5468 /* FIXME: use the real unit here! */
5469 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5470 videocontext->pixel_width,
5471 videocontext->pixel_height,
5472 videocontext->display_width, videocontext->display_height);
5474 /* pixel width and height are the w and h of the video in pixels */
5475 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5476 gint w = videocontext->pixel_width;
5477 gint h = videocontext->pixel_height;
5479 gst_structure_set (structure,
5480 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5483 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5486 if (videocontext->display_width <= 0)
5487 videocontext->display_width = videocontext->pixel_width;
5488 if (videocontext->display_height <= 0)
5489 videocontext->display_height = videocontext->pixel_height;
5491 /* calculate the pixel aspect ratio using the display and pixel w/h */
5492 n = videocontext->display_width * videocontext->pixel_height;
5493 d = videocontext->display_height * videocontext->pixel_width;
5494 GST_DEBUG ("setting PAR to %d/%d", n, d);
5495 gst_structure_set (structure, "pixel-aspect-ratio",
5497 videocontext->display_width * videocontext->pixel_height,
5498 videocontext->display_height * videocontext->pixel_width, NULL);
5501 if (videocontext->default_fps > 0.0) {
5504 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5506 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5508 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5510 } else if (context->default_duration > 0) {
5513 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5515 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5516 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5518 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5519 fps_n, fps_d, NULL);
5521 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5525 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5526 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5529 if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
5530 if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
5531 videocontext->pixel_width, videocontext->pixel_height,
5532 videocontext->display_width * videocontext->pixel_height,
5533 videocontext->display_height * videocontext->pixel_width)) {
5534 videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
5536 gst_caps_set_simple (caps,
5537 "multiview-mode", G_TYPE_STRING,
5538 gst_video_multiview_mode_to_caps_string
5539 (videocontext->multiview_mode), "multiview-flags",
5540 GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
5541 GST_FLAG_SET_MASK_EXACT, NULL);
5544 caps = gst_caps_simplify (caps);
5551 * Some AAC specific code... *sigh*
5552 * FIXME: maybe we should use '15' and code the sample rate explicitly
5553 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5557 aac_rate_idx (gint rate)
5561 else if (75132 <= rate)
5563 else if (55426 <= rate)
5565 else if (46009 <= rate)
5567 else if (37566 <= rate)
5569 else if (27713 <= rate)
5571 else if (23004 <= rate)
5573 else if (18783 <= rate)
5575 else if (13856 <= rate)
5577 else if (11502 <= rate)
5579 else if (9391 <= rate)
5586 aac_profile_idx (const gchar * codec_id)
5590 if (strlen (codec_id) <= 12)
5592 else if (!strncmp (&codec_id[12], "MAIN", 4))
5594 else if (!strncmp (&codec_id[12], "LC", 2))
5596 else if (!strncmp (&codec_id[12], "SSR", 3))
5605 round_up_pow2 (guint n)
5616 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5619 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5620 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5621 gchar ** codec_name, guint16 * riff_audio_fmt)
5623 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5624 GstCaps *caps = NULL;
5626 g_assert (audiocontext != NULL);
5627 g_assert (codec_name != NULL);
5630 *riff_audio_fmt = 0;
5632 /* TODO: check if we have all codec types from matroska-ids.h
5633 * check if we have to do more special things with codec_private
5634 * check if we need bitdepth in different places too
5635 * implement channel position magic
5637 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5638 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5639 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5640 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5643 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5644 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5645 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5648 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5650 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5655 caps = gst_caps_new_simple ("audio/mpeg",
5656 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5657 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5658 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5659 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5662 GstAudioFormat format;
5664 sign = (audiocontext->bitdepth != 8);
5665 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5666 endianness = G_BIG_ENDIAN;
5668 endianness = G_LITTLE_ENDIAN;
5670 format = gst_audio_format_build_integer (sign, endianness,
5671 audiocontext->bitdepth, audiocontext->bitdepth);
5673 /* FIXME: Channel mask and reordering */
5674 caps = gst_caps_new_simple ("audio/x-raw",
5675 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5676 "layout", G_TYPE_STRING, "interleaved",
5677 "channel-mask", GST_TYPE_BITMASK,
5678 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5680 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5681 audiocontext->bitdepth);
5682 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5683 context->alignment = round_up_pow2 (context->alignment);
5684 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5685 const gchar *format;
5686 if (audiocontext->bitdepth == 32)
5690 /* FIXME: Channel mask and reordering */
5691 caps = gst_caps_new_simple ("audio/x-raw",
5692 "format", G_TYPE_STRING, format,
5693 "layout", G_TYPE_STRING, "interleaved",
5694 "channel-mask", GST_TYPE_BITMASK,
5695 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5696 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5697 audiocontext->bitdepth);
5698 context->alignment = audiocontext->bitdepth / 8;
5699 context->alignment = round_up_pow2 (context->alignment);
5700 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5701 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5702 caps = gst_caps_new_simple ("audio/x-ac3",
5703 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5704 *codec_name = g_strdup ("AC-3 audio");
5705 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5706 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5707 caps = gst_caps_new_simple ("audio/x-eac3",
5708 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5709 *codec_name = g_strdup ("E-AC-3 audio");
5710 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5711 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5712 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5713 *codec_name = g_strdup ("Dolby TrueHD");
5714 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5715 caps = gst_caps_new_empty_simple ("audio/x-dts");
5716 *codec_name = g_strdup ("DTS audio");
5717 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5718 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5719 context->stream_headers =
5720 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5721 context->codec_priv_size);
5722 /* FIXME: mark stream as broken and skip if there are no stream headers */
5723 context->send_stream_headers = TRUE;
5724 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5725 caps = gst_caps_new_empty_simple ("audio/x-flac");
5726 context->stream_headers =
5727 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5728 context->codec_priv_size);
5729 /* FIXME: mark stream as broken and skip if there are no stream headers */
5730 context->send_stream_headers = TRUE;
5731 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5732 caps = gst_caps_new_empty_simple ("audio/x-speex");
5733 context->stream_headers =
5734 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5735 context->codec_priv_size);
5736 /* FIXME: mark stream as broken and skip if there are no stream headers */
5737 context->send_stream_headers = TRUE;
5738 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5741 if (context->codec_priv_size >= 19) {
5742 if (audiocontext->samplerate)
5743 GST_WRITE_UINT32_LE ((guint8 *) context->codec_priv + 12,
5744 audiocontext->samplerate);
5745 if (context->codec_delay) {
5747 gst_util_uint64_scale_round (context->codec_delay, 48000,
5749 GST_WRITE_UINT16_LE ((guint8 *) context->codec_priv + 10, delay);
5753 gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5754 context->codec_priv_size), context->codec_priv_size);
5755 caps = gst_codec_utils_opus_create_caps_from_header (tmp, NULL);
5756 gst_buffer_unref (tmp);
5757 *codec_name = g_strdup ("Opus");
5758 } else if (context->codec_priv_size == 0) {
5759 GST_WARNING ("No Opus codec data found, trying to create one");
5760 if (audiocontext->channels <= 2) {
5761 guint8 streams, coupled, channels;
5765 audiocontext->samplerate == 0 ? 48000 : audiocontext->samplerate;
5766 channels = audiocontext->channels == 0 ? 2 : audiocontext->channels;
5767 if (channels == 1) {
5776 gst_codec_utils_opus_create_caps (samplerate, channels, 0, streams,
5779 *codec_name = g_strdup ("Opus");
5781 GST_WARNING ("Failed to create Opus caps from audio context");
5784 GST_WARNING ("No Opus codec data, and not enough info to create one");
5787 GST_WARNING ("Invalid Opus codec data size (got %" G_GSIZE_FORMAT
5788 ", expected 19)", context->codec_priv_size);
5790 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5791 gst_riff_strf_auds auds;
5793 if (data && size >= 18) {
5794 GstBuffer *codec_data = NULL;
5796 /* little-endian -> byte-order */
5797 auds.format = GST_READ_UINT16_LE (data);
5798 auds.channels = GST_READ_UINT16_LE (data + 2);
5799 auds.rate = GST_READ_UINT32_LE (data + 4);
5800 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5801 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5802 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5804 /* 18 is the waveformatex size */
5806 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5807 data + 18, size - 18, 0, size - 18, NULL, NULL);
5811 *riff_audio_fmt = auds.format;
5813 /* FIXME: Handle reorder map */
5814 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5815 codec_data, codec_name, NULL);
5817 gst_buffer_unref (codec_data);
5820 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5823 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5825 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5826 GstBuffer *priv = NULL;
5828 gint rate_idx, profile;
5829 guint8 *data = NULL;
5831 /* unspecified AAC profile with opaque private codec data */
5832 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5833 if (context->codec_priv_size >= 2) {
5834 guint obj_type, freq_index, explicit_freq_bytes = 0;
5836 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5838 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5839 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5840 if (freq_index == 15)
5841 explicit_freq_bytes = 3;
5842 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5843 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5844 context->codec_priv_size), context->codec_priv_size);
5845 /* assume SBR if samplerate <= 24kHz */
5846 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5847 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5848 audiocontext->samplerate *= 2;
5851 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5852 /* this is pretty broken;
5853 * maybe we need to make up some default private,
5854 * or maybe ADTS data got dumped in.
5855 * Let's set up some private data now, and check actual data later */
5856 /* just try this and see what happens ... */
5857 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5858 context->postprocess_frame = gst_matroska_demux_check_aac;
5862 /* make up decoder-specific data if it is not supplied */
5866 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5867 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5869 rate_idx = aac_rate_idx (audiocontext->samplerate);
5870 profile = aac_profile_idx (codec_id);
5872 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5873 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5875 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5876 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5878 gst_buffer_unmap (priv, &map);
5879 gst_buffer_set_size (priv, 2);
5880 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5881 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5884 if (g_strrstr (codec_id, "SBR")) {
5885 /* HE-AAC (aka SBR AAC) */
5886 audiocontext->samplerate *= 2;
5887 rate_idx = aac_rate_idx (audiocontext->samplerate);
5888 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5889 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5890 data[4] = (1 << 7) | (rate_idx << 3);
5891 gst_buffer_unmap (priv, &map);
5893 gst_buffer_unmap (priv, &map);
5894 gst_buffer_set_size (priv, 2);
5897 gst_buffer_unmap (priv, &map);
5898 gst_buffer_unref (priv);
5900 GST_ERROR ("Unknown AAC profile and no codec private data");
5905 caps = gst_caps_new_simple ("audio/mpeg",
5906 "mpegversion", G_TYPE_INT, mpegversion,
5907 "framed", G_TYPE_BOOLEAN, TRUE,
5908 "stream-format", G_TYPE_STRING, "raw", NULL);
5909 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5910 if (context->codec_priv && context->codec_priv_size > 0)
5911 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5912 context->codec_priv, context->codec_priv_size);
5913 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5914 gst_buffer_unref (priv);
5916 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5917 caps = gst_caps_new_simple ("audio/x-tta",
5918 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5919 *codec_name = g_strdup ("TTA audio");
5920 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5921 caps = gst_caps_new_simple ("audio/x-wavpack",
5922 "width", G_TYPE_INT, audiocontext->bitdepth,
5923 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5924 *codec_name = g_strdup ("Wavpack audio");
5925 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5926 audiocontext->wvpk_block_index = 0;
5927 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5928 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5929 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5930 gint raversion = -1;
5932 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5934 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5939 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5940 "raversion", G_TYPE_INT, raversion, NULL);
5941 /* Extract extra information from caps, mapping varies based on codec */
5942 if (data && (size >= 0x50)) {
5949 guint extra_data_size;
5951 GST_ERROR ("real audio raversion:%d", raversion);
5952 if (raversion == 8) {
5954 flavor = GST_READ_UINT16_BE (data + 22);
5955 packet_size = GST_READ_UINT32_BE (data + 24);
5956 height = GST_READ_UINT16_BE (data + 40);
5957 leaf_size = GST_READ_UINT16_BE (data + 44);
5958 sample_width = GST_READ_UINT16_BE (data + 58);
5959 extra_data_size = GST_READ_UINT32_BE (data + 74);
5962 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5963 flavor, packet_size, height, leaf_size, sample_width,
5965 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5966 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5967 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5969 if ((size - 78) >= extra_data_size) {
5970 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5972 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5973 gst_buffer_unref (priv);
5978 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5979 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5980 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5981 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5982 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5983 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5984 *codec_name = g_strdup ("Real Audio Lossless");
5985 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5986 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5987 *codec_name = g_strdup ("Sony ATRAC3");
5989 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5994 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5997 for (i = 0; i < gst_caps_get_size (caps); i++) {
5998 gst_structure_set (gst_caps_get_structure (caps, i),
5999 "channels", G_TYPE_INT, audiocontext->channels,
6000 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
6004 caps = gst_caps_simplify (caps);
6011 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
6012 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
6014 GstCaps *caps = NULL;
6015 GstMatroskaTrackContext *context =
6016 (GstMatroskaTrackContext *) subtitlecontext;
6018 /* for backwards compatibility */
6019 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
6020 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
6021 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
6022 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
6023 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
6024 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
6025 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
6026 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
6028 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
6029 * Check if we have to do something with codec_private */
6030 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
6031 /* well, plain text simply does not have a lot of markup ... */
6032 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
6033 "pango-markup", NULL);
6034 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6035 subtitlecontext->check_markup = TRUE;
6036 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
6037 caps = gst_caps_new_empty_simple ("application/x-ssa");
6038 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6039 subtitlecontext->check_markup = FALSE;
6040 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
6041 caps = gst_caps_new_empty_simple ("application/x-ass");
6042 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6043 subtitlecontext->check_markup = FALSE;
6044 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
6045 caps = gst_caps_new_empty_simple ("application/x-usf");
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_VOBSUB)) {
6049 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
6050 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
6051 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
6052 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
6053 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
6054 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
6055 context->stream_headers =
6056 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6057 context->codec_priv_size);
6058 /* FIXME: mark stream as broken and skip if there are no stream headers */
6059 context->send_stream_headers = TRUE;
6061 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
6062 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
6065 if (data != NULL && size > 0) {
6068 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
6069 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
6070 gst_buffer_unref (buf);
6078 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
6080 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6082 GST_OBJECT_LOCK (demux);
6083 if (demux->common.element_index)
6084 gst_object_unref (demux->common.element_index);
6085 demux->common.element_index = index ? gst_object_ref (index) : NULL;
6086 GST_OBJECT_UNLOCK (demux);
6087 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
6088 demux->common.element_index);
6092 gst_matroska_demux_get_index (GstElement * element)
6094 GstIndex *result = NULL;
6095 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6097 GST_OBJECT_LOCK (demux);
6098 if (demux->common.element_index)
6099 result = gst_object_ref (demux->common.element_index);
6100 GST_OBJECT_UNLOCK (demux);
6102 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
6108 static GstStateChangeReturn
6109 gst_matroska_demux_change_state (GstElement * element,
6110 GstStateChange transition)
6112 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6113 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
6115 /* handle upwards state changes here */
6116 switch (transition) {
6121 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
6123 /* handle downwards state changes */
6124 switch (transition) {
6125 case GST_STATE_CHANGE_PAUSED_TO_READY:
6126 gst_matroska_demux_reset (GST_ELEMENT (demux));
6136 gst_matroska_demux_set_property (GObject * object,
6137 guint prop_id, const GValue * value, GParamSpec * pspec)
6139 GstMatroskaDemux *demux;
6141 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6142 demux = GST_MATROSKA_DEMUX (object);
6145 case PROP_MAX_GAP_TIME:
6146 GST_OBJECT_LOCK (demux);
6147 demux->max_gap_time = g_value_get_uint64 (value);
6148 GST_OBJECT_UNLOCK (demux);
6151 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6157 gst_matroska_demux_get_property (GObject * object,
6158 guint prop_id, GValue * value, GParamSpec * pspec)
6160 GstMatroskaDemux *demux;
6162 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6163 demux = GST_MATROSKA_DEMUX (object);
6166 case PROP_MAX_GAP_TIME:
6167 GST_OBJECT_LOCK (demux);
6168 g_value_set_uint64 (value, demux->max_gap_time);
6169 GST_OBJECT_UNLOCK (demux);
6172 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6178 gst_matroska_demux_plugin_init (GstPlugin * plugin)
6182 /* parser helper separate debug */
6183 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
6184 0, "EBML stream helper class");
6186 /* create an elementfactory for the matroska_demux element */
6187 if (!gst_element_register (plugin, "matroskademux",
6188 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))