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., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, 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 -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/tag/tag.h>
64 #include <gst/pbutils/pbutils.h>
66 #include "matroska-demux.h"
67 #include "matroska-ids.h"
69 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
70 #define GST_CAT_DEFAULT matroskademux_debug
72 #define DEBUG_ELEMENT_START(demux, ebml, element) \
73 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
74 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
76 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
77 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
78 " finished with '%s'", gst_flow_get_name (ret))
88 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
90 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
93 GST_STATIC_CAPS ("video/x-matroska; video/webm")
96 /* TODO: fill in caps! */
98 static GstStaticPadTemplate audio_src_templ =
99 GST_STATIC_PAD_TEMPLATE ("audio_%02d",
102 GST_STATIC_CAPS ("ANY")
105 static GstStaticPadTemplate video_src_templ =
106 GST_STATIC_PAD_TEMPLATE ("video_%02d",
109 GST_STATIC_CAPS ("ANY")
112 static GstStaticPadTemplate subtitle_src_templ =
113 GST_STATIC_PAD_TEMPLATE ("subtitle_%02d",
116 GST_STATIC_CAPS ("text/x-pango-markup; application/x-ssa; "
117 "application/x-ass;application/x-usf; video/x-dvd-subpicture; "
118 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
121 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
122 guint32 id, guint64 length, guint needed);
124 /* element functions */
125 static void gst_matroska_demux_loop (GstPad * pad);
127 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
129 static gboolean gst_matroska_demux_element_query (GstElement * element,
133 static gboolean gst_matroska_demux_sink_activate_pull (GstPad * sinkpad,
135 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad);
137 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
138 GstPad * pad, GstEvent * event);
139 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
141 static const GstQueryType *gst_matroska_demux_get_src_query_types (GstPad *
143 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
146 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
148 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
151 static GstStateChangeReturn
152 gst_matroska_demux_change_state (GstElement * element,
153 GstStateChange transition);
155 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
156 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
159 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
160 * videocontext, const gchar * codec_id, guint8 * data, guint size,
161 gchar ** codec_name, guint32 * riff_fourcc);
162 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
163 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
164 gchar ** codec_name, guint16 * riff_audio_fmt);
166 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
167 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
170 static void gst_matroska_demux_reset (GstElement * element);
171 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
174 /* gobject functions */
175 static void gst_matroska_demux_set_property (GObject * object,
176 guint prop_id, const GValue * value, GParamSpec * pspec);
177 static void gst_matroska_demux_get_property (GObject * object,
178 guint prop_id, GValue * value, GParamSpec * pspec);
180 GType gst_matroska_demux_get_type (void);
181 GST_BOILERPLATE (GstMatroskaDemux, gst_matroska_demux, GstElement,
185 gst_matroska_demux_base_init (gpointer klass)
187 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
189 gst_element_class_add_static_pad_template (element_class,
191 gst_element_class_add_static_pad_template (element_class,
193 gst_element_class_add_static_pad_template (element_class,
194 &subtitle_src_templ);
195 gst_element_class_add_static_pad_template (element_class, &sink_templ);
197 gst_element_class_set_details_simple (element_class, "Matroska demuxer",
199 "Demuxes Matroska/WebM streams into video/audio/subtitles",
200 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
204 gst_matroska_demux_finalize (GObject * object)
206 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
208 if (demux->common.src) {
209 g_ptr_array_free (demux->common.src, TRUE);
210 demux->common.src = NULL;
213 if (demux->common.global_tags) {
214 gst_tag_list_free (demux->common.global_tags);
215 demux->common.global_tags = NULL;
218 g_object_unref (demux->common.adapter);
220 G_OBJECT_CLASS (parent_class)->finalize (object);
224 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
226 GObjectClass *gobject_class = (GObjectClass *) klass;
227 GstElementClass *gstelement_class = (GstElementClass *) klass;
229 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
232 gobject_class->finalize = gst_matroska_demux_finalize;
234 gobject_class->get_property = gst_matroska_demux_get_property;
235 gobject_class->set_property = gst_matroska_demux_set_property;
237 g_object_class_install_property (gobject_class, ARG_MAX_GAP_TIME,
238 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
239 "The demuxer sends out newsegment events for skipping "
240 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
241 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
243 gstelement_class->change_state =
244 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
245 gstelement_class->send_event =
246 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
247 gstelement_class->query =
248 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
250 gstelement_class->set_index =
251 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
252 gstelement_class->get_index =
253 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
257 gst_matroska_demux_init (GstMatroskaDemux * demux,
258 GstMatroskaDemuxClass * klass)
260 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
262 gst_pad_set_activate_function (demux->common.sinkpad,
263 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
264 gst_pad_set_activatepull_function (demux->common.sinkpad,
265 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_pull));
266 gst_pad_set_chain_function (demux->common.sinkpad,
267 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
268 gst_pad_set_event_function (demux->common.sinkpad,
269 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
270 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
272 /* initial stream no. */
273 demux->common.src = NULL;
275 demux->common.writing_app = NULL;
276 demux->common.muxing_app = NULL;
277 demux->common.index = NULL;
278 demux->common.global_tags = NULL;
280 demux->common.adapter = gst_adapter_new ();
282 /* property defaults */
283 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
286 gst_matroska_demux_reset (GST_ELEMENT (demux));
290 gst_matroska_track_free (GstMatroskaTrackContext * track)
292 g_free (track->codec_id);
293 g_free (track->codec_name);
294 g_free (track->name);
295 g_free (track->language);
296 g_free (track->codec_priv);
297 g_free (track->codec_state);
299 if (track->encodings != NULL) {
302 for (i = 0; i < track->encodings->len; ++i) {
303 GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
304 GstMatroskaTrackEncoding,
307 g_free (enc->comp_settings);
309 g_array_free (track->encodings, TRUE);
312 if (track->pending_tags)
313 gst_tag_list_free (track->pending_tags);
315 if (track->index_table)
316 g_array_free (track->index_table, TRUE);
322 * Returns the aggregated GstFlowReturn.
325 gst_matroska_demux_combine_flows (GstMatroskaDemux * demux,
326 GstMatroskaTrackContext * track, GstFlowReturn ret)
330 /* store the value */
331 track->last_flow = ret;
333 /* any other error that is not-linked can be returned right away */
334 if (ret != GST_FLOW_NOT_LINKED)
337 /* only return NOT_LINKED if all other pads returned NOT_LINKED */
338 g_assert (demux->common.src->len == demux->common.num_streams);
339 for (i = 0; i < demux->common.src->len; i++) {
340 GstMatroskaTrackContext *ostream = g_ptr_array_index (demux->common.src,
346 ret = ostream->last_flow;
347 /* some other return value (must be SUCCESS but we can return
348 * other values as well) */
349 if (ret != GST_FLOW_NOT_LINKED)
352 /* if we get here, all other pads were unlinked and we return
355 GST_LOG_OBJECT (demux, "combined return %s", gst_flow_get_name (ret));
360 gst_matroska_demux_free_parsed_el (gpointer mem, gpointer user_data)
362 g_slice_free (guint64, mem);
366 gst_matroska_demux_reset (GstElement * element)
368 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
371 GST_DEBUG_OBJECT (demux, "Resetting state");
374 demux->common.state = GST_MATROSKA_READ_STATE_START;
376 /* clean up existing streams */
377 if (demux->common.src) {
378 g_assert (demux->common.src->len == demux->common.num_streams);
379 for (i = 0; i < demux->common.src->len; i++) {
380 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
383 if (context->pad != NULL)
384 gst_element_remove_pad (GST_ELEMENT (demux), context->pad);
386 gst_caps_replace (&context->caps, NULL);
387 gst_matroska_track_free (context);
389 g_ptr_array_free (demux->common.src, TRUE);
391 demux->common.src = g_ptr_array_new ();
393 demux->common.num_streams = 0;
394 demux->num_a_streams = 0;
395 demux->num_t_streams = 0;
396 demux->num_v_streams = 0;
398 /* reset media info */
399 g_free (demux->common.writing_app);
400 demux->common.writing_app = NULL;
401 g_free (demux->common.muxing_app);
402 demux->common.muxing_app = NULL;
405 if (demux->common.index) {
406 g_array_free (demux->common.index, TRUE);
407 demux->common.index = NULL;
410 if (demux->clusters) {
411 g_array_free (demux->clusters, TRUE);
412 demux->clusters = NULL;
417 demux->common.time_scale = 1000000;
418 demux->common.created = G_MININT64;
420 demux->common.index_parsed = FALSE;
421 demux->tracks_parsed = FALSE;
422 demux->common.segmentinfo_parsed = FALSE;
423 demux->common.attachments_parsed = FALSE;
425 g_list_foreach (demux->common.tags_parsed,
426 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
427 g_list_free (demux->common.tags_parsed);
428 demux->common.tags_parsed = NULL;
430 g_list_foreach (demux->seek_parsed,
431 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
432 g_list_free (demux->seek_parsed);
433 demux->seek_parsed = NULL;
435 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
436 demux->last_stop_end = GST_CLOCK_TIME_NONE;
437 demux->seek_block = 0;
438 demux->stream_start_time = GST_CLOCK_TIME_NONE;
440 demux->common.offset = 0;
441 demux->cluster_time = GST_CLOCK_TIME_NONE;
442 demux->cluster_offset = 0;
443 demux->next_cluster_offset = 0;
444 demux->index_offset = 0;
445 demux->seekable = FALSE;
446 demux->need_newsegment = FALSE;
447 demux->building_index = FALSE;
448 if (demux->seek_event) {
449 gst_event_unref (demux->seek_event);
450 demux->seek_event = NULL;
453 demux->seek_index = NULL;
454 demux->seek_entry = 0;
456 if (demux->close_segment) {
457 gst_event_unref (demux->close_segment);
458 demux->close_segment = NULL;
461 if (demux->new_segment) {
462 gst_event_unref (demux->new_segment);
463 demux->new_segment = NULL;
466 if (demux->common.element_index) {
467 gst_object_unref (demux->common.element_index);
468 demux->common.element_index = NULL;
470 demux->common.element_index_writer_id = -1;
472 if (demux->common.global_tags) {
473 gst_tag_list_free (demux->common.global_tags);
475 demux->common.global_tags = gst_tag_list_new ();
477 if (demux->common.cached_buffer) {
478 gst_buffer_unref (demux->common.cached_buffer);
479 demux->common.cached_buffer = NULL;
484 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
490 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
492 GST_DEBUG ("decoding buffer %p", buf);
494 data = GST_BUFFER_DATA (buf);
495 size = GST_BUFFER_SIZE (buf);
497 g_return_val_if_fail (data != NULL && size > 0, buf);
499 if (gst_matroska_decode_data (context->encodings, &data, &size,
500 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
501 new_buf = gst_buffer_new ();
502 GST_BUFFER_MALLOCDATA (new_buf) = (guint8 *) data;
503 GST_BUFFER_DATA (new_buf) = (guint8 *) data;
504 GST_BUFFER_SIZE (new_buf) = size;
506 gst_buffer_unref (buf);
511 GST_DEBUG ("decode data failed");
512 gst_buffer_unref (buf);
518 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
520 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
521 GstMatroskaTrackContext *context;
522 GstPadTemplate *templ = NULL;
523 GstCaps *caps = NULL;
524 gchar *padname = NULL;
526 guint32 id, riff_fourcc = 0;
527 guint16 riff_audio_fmt = 0;
528 GstTagList *list = NULL;
531 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
533 /* start with the master */
534 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
535 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
539 /* allocate generic... if we know the type, we'll g_renew()
540 * with the precise type */
541 context = g_new0 (GstMatroskaTrackContext, 1);
542 g_ptr_array_add (demux->common.src, context);
543 context->index = demux->common.num_streams;
544 context->index_writer_id = -1;
545 context->type = 0; /* no type yet */
546 context->default_duration = 0;
548 context->set_discont = TRUE;
549 context->timecodescale = 1.0;
551 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
552 GST_MATROSKA_TRACK_LACING;
553 context->last_flow = GST_FLOW_OK;
554 context->to_offset = G_MAXINT64;
555 context->alignment = 1;
556 demux->common.num_streams++;
557 g_assert (demux->common.src->len == demux->common.num_streams);
559 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
561 /* try reading the trackentry headers */
562 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
563 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
567 /* track number (unique stream ID) */
568 case GST_MATROSKA_ID_TRACKNUMBER:{
571 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
575 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
576 ret = GST_FLOW_ERROR;
578 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
580 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
581 " is not unique", num);
582 ret = GST_FLOW_ERROR;
586 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
590 /* track UID (unique identifier) */
591 case GST_MATROSKA_ID_TRACKUID:{
594 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
598 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
599 ret = GST_FLOW_ERROR;
603 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
608 /* track type (video, audio, combined, subtitle, etc.) */
609 case GST_MATROSKA_ID_TRACKTYPE:{
612 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
616 if (context->type != 0 && context->type != track_type) {
617 GST_WARNING_OBJECT (demux,
618 "More than one tracktype defined in a TrackEntry - skipping");
620 } else if (track_type < 1 || track_type > 254) {
621 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
626 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
628 /* ok, so we're actually going to reallocate this thing */
629 switch (track_type) {
630 case GST_MATROSKA_TRACK_TYPE_VIDEO:
631 gst_matroska_track_init_video_context (&context);
633 case GST_MATROSKA_TRACK_TYPE_AUDIO:
634 gst_matroska_track_init_audio_context (&context);
636 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
637 gst_matroska_track_init_subtitle_context (&context);
639 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
640 case GST_MATROSKA_TRACK_TYPE_LOGO:
641 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
642 case GST_MATROSKA_TRACK_TYPE_CONTROL:
644 GST_WARNING_OBJECT (demux,
645 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
650 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
655 /* tracktype specific stuff for video */
656 case GST_MATROSKA_ID_TRACKVIDEO:{
657 GstMatroskaTrackVideoContext *videocontext;
659 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
661 if (!gst_matroska_track_init_video_context (&context)) {
662 GST_WARNING_OBJECT (demux,
663 "TrackVideo element in non-video track - ignoring track");
664 ret = GST_FLOW_ERROR;
666 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
669 videocontext = (GstMatroskaTrackVideoContext *) context;
670 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
673 while (ret == GST_FLOW_OK &&
674 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
675 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
679 /* Should be one level up but some broken muxers write it here. */
680 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
683 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
687 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
691 GST_DEBUG_OBJECT (demux,
692 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
693 context->default_duration = num;
697 /* video framerate */
698 /* NOTE: This one is here only for backward compatibility.
699 * Use _TRACKDEFAULDURATION one level up. */
700 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
703 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
707 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
711 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
712 if (context->default_duration == 0)
713 context->default_duration =
714 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
715 videocontext->default_fps = num;
719 /* width of the size to display the video at */
720 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
723 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
727 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
731 GST_DEBUG_OBJECT (demux,
732 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
733 videocontext->display_width = num;
737 /* height of the size to display the video at */
738 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
741 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
745 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
749 GST_DEBUG_OBJECT (demux,
750 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
751 videocontext->display_height = num;
755 /* width of the video in the file */
756 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
759 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
763 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
767 GST_DEBUG_OBJECT (demux,
768 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
769 videocontext->pixel_width = num;
773 /* height of the video in the file */
774 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
777 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
781 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
785 GST_DEBUG_OBJECT (demux,
786 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
787 videocontext->pixel_height = num;
791 /* whether the video is interlaced */
792 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
795 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
799 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
801 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
802 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
803 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
808 /* aspect ratio behaviour */
809 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
812 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
815 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
816 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
817 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
818 GST_WARNING_OBJECT (demux,
819 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
822 GST_DEBUG_OBJECT (demux,
823 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
824 videocontext->asr_mode = num;
828 /* colourspace (only matters for raw video) fourcc */
829 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
834 gst_ebml_read_binary (ebml, &id, &data,
835 &datalen)) != GST_FLOW_OK)
840 GST_WARNING_OBJECT (demux,
841 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
846 memcpy (&videocontext->fourcc, data, 4);
847 GST_DEBUG_OBJECT (demux,
848 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
849 GST_FOURCC_ARGS (videocontext->fourcc));
855 GST_WARNING_OBJECT (demux,
856 "Unknown TrackVideo subelement 0x%x - ignoring", id);
858 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
859 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
860 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
861 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
862 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
863 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
864 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
865 ret = gst_ebml_read_skip (ebml);
870 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
874 /* tracktype specific stuff for audio */
875 case GST_MATROSKA_ID_TRACKAUDIO:{
876 GstMatroskaTrackAudioContext *audiocontext;
878 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
880 if (!gst_matroska_track_init_audio_context (&context)) {
881 GST_WARNING_OBJECT (demux,
882 "TrackAudio element in non-audio track - ignoring track");
883 ret = GST_FLOW_ERROR;
887 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
890 audiocontext = (GstMatroskaTrackAudioContext *) context;
891 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
894 while (ret == GST_FLOW_OK &&
895 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
896 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
901 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
904 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
909 GST_WARNING_OBJECT (demux,
910 "Invalid TrackAudioSamplingFrequency %lf", num);
914 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
915 audiocontext->samplerate = num;
920 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
923 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
927 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
931 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
933 audiocontext->bitdepth = num;
938 case GST_MATROSKA_ID_AUDIOCHANNELS:{
941 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
945 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
949 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
951 audiocontext->channels = num;
956 GST_WARNING_OBJECT (demux,
957 "Unknown TrackAudio subelement 0x%x - ignoring", id);
959 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
960 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
961 ret = gst_ebml_read_skip (ebml);
966 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
971 /* codec identifier */
972 case GST_MATROSKA_ID_CODECID:{
975 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
978 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
979 context->codec_id = text;
983 /* codec private data */
984 case GST_MATROSKA_ID_CODECPRIVATE:{
989 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
992 context->codec_priv = data;
993 context->codec_priv_size = size;
995 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1000 /* name of the codec */
1001 case GST_MATROSKA_ID_CODECNAME:{
1004 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1007 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1008 context->codec_name = text;
1012 /* name of this track */
1013 case GST_MATROSKA_ID_TRACKNAME:{
1016 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1019 context->name = text;
1020 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1024 /* language (matters for audio/subtitles, mostly) */
1025 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1028 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1032 context->language = text;
1035 if (strlen (context->language) >= 4 && context->language[3] == '-')
1036 context->language[3] = '\0';
1038 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1039 GST_STR_NULL (context->language));
1043 /* whether this is actually used */
1044 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1047 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1051 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1053 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1055 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1056 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1060 /* whether it's the default for this track type */
1061 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1064 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1068 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1070 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1072 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1073 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1077 /* whether the track must be used during playback */
1078 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1081 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1085 context->flags |= GST_MATROSKA_TRACK_FORCED;
1087 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1089 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1090 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1094 /* lacing (like MPEG, where blocks don't end/start on frame
1096 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1099 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1103 context->flags |= GST_MATROSKA_TRACK_LACING;
1105 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1107 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1108 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1112 /* default length (in time) of one data block in this track */
1113 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1116 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1121 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1125 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1127 context->default_duration = num;
1131 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1132 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1137 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1140 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1144 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1148 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1149 context->timecodescale = num;
1154 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1157 /* we ignore these because they're nothing useful (i.e. crap)
1158 * or simply not implemented yet. */
1159 case GST_MATROSKA_ID_TRACKMINCACHE:
1160 case GST_MATROSKA_ID_TRACKMAXCACHE:
1161 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1162 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1163 case GST_MATROSKA_ID_TRACKOVERLAY:
1164 case GST_MATROSKA_ID_TRACKTRANSLATE:
1165 case GST_MATROSKA_ID_TRACKOFFSET:
1166 case GST_MATROSKA_ID_CODECSETTINGS:
1167 case GST_MATROSKA_ID_CODECINFOURL:
1168 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1169 case GST_MATROSKA_ID_CODECDECODEALL:
1170 ret = gst_ebml_read_skip (ebml);
1175 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1177 /* Decode codec private data if necessary */
1178 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1179 && context->codec_priv_size > 0) {
1180 if (!gst_matroska_decode_data (context->encodings,
1181 &context->codec_priv, &context->codec_priv_size,
1182 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1183 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1184 ret = GST_FLOW_ERROR;
1188 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1189 && ret != GST_FLOW_UNEXPECTED)) {
1190 if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
1191 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1193 demux->common.num_streams--;
1194 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1195 g_assert (demux->common.src->len == demux->common.num_streams);
1197 gst_matroska_track_free (context);
1203 /* now create the GStreamer connectivity */
1204 switch (context->type) {
1205 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1206 GstMatroskaTrackVideoContext *videocontext =
1207 (GstMatroskaTrackVideoContext *) context;
1209 padname = g_strdup_printf ("video_%02d", demux->num_v_streams++);
1210 templ = gst_element_class_get_pad_template (klass, "video_%02d");
1211 caps = gst_matroska_demux_video_caps (videocontext,
1212 context->codec_id, (guint8 *) context->codec_priv,
1213 context->codec_priv_size, &codec, &riff_fourcc);
1216 list = gst_tag_list_new ();
1217 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1218 GST_TAG_VIDEO_CODEC, codec, NULL);
1224 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1225 GstMatroskaTrackAudioContext *audiocontext =
1226 (GstMatroskaTrackAudioContext *) context;
1228 padname = g_strdup_printf ("audio_%02d", demux->num_a_streams++);
1229 templ = gst_element_class_get_pad_template (klass, "audio_%02d");
1230 caps = gst_matroska_demux_audio_caps (audiocontext,
1231 context->codec_id, context->codec_priv, context->codec_priv_size,
1232 &codec, &riff_audio_fmt);
1235 list = gst_tag_list_new ();
1236 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1237 GST_TAG_AUDIO_CODEC, codec, NULL);
1243 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1244 GstMatroskaTrackSubtitleContext *subtitlecontext =
1245 (GstMatroskaTrackSubtitleContext *) context;
1247 padname = g_strdup_printf ("subtitle_%02d", demux->num_t_streams++);
1248 templ = gst_element_class_get_pad_template (klass, "subtitle_%02d");
1249 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1250 context->codec_id, context->codec_priv, context->codec_priv_size);
1254 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1255 case GST_MATROSKA_TRACK_TYPE_LOGO:
1256 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1257 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1259 /* we should already have quit by now */
1260 g_assert_not_reached ();
1263 if ((context->language == NULL || *context->language == '\0') &&
1264 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1265 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1266 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1267 context->language = g_strdup ("eng");
1270 if (context->language) {
1274 list = gst_tag_list_new ();
1276 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1277 lang = gst_tag_get_language_code (context->language);
1278 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1279 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1283 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1284 "codec_id='%s'", context->codec_id);
1285 switch (context->type) {
1286 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1287 caps = gst_caps_new_simple ("video/x-unknown", NULL);
1289 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1290 caps = gst_caps_new_simple ("audio/x-unknown", NULL);
1292 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1293 caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
1295 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1297 caps = gst_caps_new_simple ("application/x-matroska-unknown", NULL);
1300 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1303 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1304 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1305 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1306 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0)
1307 gst_caps_set_simple (caps, "fourcc", GST_TYPE_FOURCC, riff_fourcc, NULL);
1310 /* the pad in here */
1311 context->pad = gst_pad_new_from_template (templ, padname);
1312 context->caps = caps;
1314 gst_pad_set_event_function (context->pad,
1315 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1316 gst_pad_set_query_type_function (context->pad,
1317 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_src_query_types));
1318 gst_pad_set_query_function (context->pad,
1319 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1321 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1324 context->pending_tags = list;
1326 gst_pad_set_element_private (context->pad, context);
1328 gst_pad_use_fixed_caps (context->pad);
1329 gst_pad_set_caps (context->pad, context->caps);
1330 gst_pad_set_active (context->pad, TRUE);
1331 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1339 static const GstQueryType *
1340 gst_matroska_demux_get_src_query_types (GstPad * pad)
1342 static const GstQueryType query_types[] = {
1353 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1356 gboolean res = FALSE;
1357 GstMatroskaTrackContext *context = NULL;
1360 context = gst_pad_get_element_private (pad);
1363 switch (GST_QUERY_TYPE (query)) {
1364 case GST_QUERY_POSITION:
1368 gst_query_parse_position (query, &format, NULL);
1370 if (format == GST_FORMAT_TIME) {
1371 GST_OBJECT_LOCK (demux);
1373 gst_query_set_position (query, GST_FORMAT_TIME,
1374 context->pos - demux->stream_start_time);
1376 gst_query_set_position (query, GST_FORMAT_TIME,
1377 demux->common.segment.last_stop - demux->stream_start_time);
1378 GST_OBJECT_UNLOCK (demux);
1379 } else if (format == GST_FORMAT_DEFAULT && context
1380 && context->default_duration) {
1381 GST_OBJECT_LOCK (demux);
1382 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1383 context->pos / context->default_duration);
1384 GST_OBJECT_UNLOCK (demux);
1386 GST_DEBUG_OBJECT (demux,
1387 "only position query in TIME and DEFAULT format is supported");
1393 case GST_QUERY_DURATION:
1397 gst_query_parse_duration (query, &format, NULL);
1399 if (format == GST_FORMAT_TIME) {
1400 GST_OBJECT_LOCK (demux);
1401 gst_query_set_duration (query, GST_FORMAT_TIME,
1402 demux->common.segment.duration);
1403 GST_OBJECT_UNLOCK (demux);
1404 } else if (format == GST_FORMAT_DEFAULT && context
1405 && context->default_duration) {
1406 GST_OBJECT_LOCK (demux);
1407 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1408 demux->common.segment.duration / context->default_duration);
1409 GST_OBJECT_UNLOCK (demux);
1411 GST_DEBUG_OBJECT (demux,
1412 "only duration query in TIME and DEFAULT format is supported");
1419 case GST_QUERY_SEEKING:
1423 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1424 GST_OBJECT_LOCK (demux);
1425 if (fmt == GST_FORMAT_TIME) {
1428 if (demux->streaming) {
1429 /* assuming we'll be able to get an index ... */
1430 seekable = demux->seekable;
1435 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1436 0, demux->common.segment.duration);
1439 GST_OBJECT_UNLOCK (demux);
1443 res = gst_pad_query_default (pad, query);
1451 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1453 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1457 gst_matroska_demux_handle_src_query (GstPad * pad, GstQuery * query)
1460 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
1462 ret = gst_matroska_demux_query (demux, pad, query);
1464 gst_object_unref (demux);
1469 /* returns FALSE if there are no pads to deliver event to,
1470 * otherwise TRUE (whatever the outcome of event sending),
1471 * takes ownership of the passed event! */
1473 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1475 gboolean is_newsegment;
1476 gboolean ret = FALSE;
1479 g_return_val_if_fail (event != NULL, FALSE);
1481 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1482 GST_EVENT_TYPE_NAME (event));
1484 is_newsegment = (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
1486 g_assert (demux->common.src->len == demux->common.num_streams);
1487 for (i = 0; i < demux->common.src->len; i++) {
1488 GstMatroskaTrackContext *stream;
1490 stream = g_ptr_array_index (demux->common.src, i);
1491 gst_event_ref (event);
1492 gst_pad_push_event (stream->pad, event);
1495 /* FIXME: send global tags before stream tags */
1496 if (G_UNLIKELY (is_newsegment && stream->pending_tags != NULL)) {
1497 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
1498 GST_PTR_FORMAT, stream->pending_tags,
1499 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
1500 gst_element_found_tags_for_pad (GST_ELEMENT (demux), stream->pad,
1501 stream->pending_tags);
1502 stream->pending_tags = NULL;
1506 if (G_UNLIKELY (is_newsegment && demux->common.global_tags != NULL)) {
1507 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1508 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1509 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1510 demux->common.global_tags, demux->common.global_tags);
1511 gst_element_found_tags (GST_ELEMENT (demux), demux->common.global_tags);
1512 demux->common.global_tags = NULL;
1515 gst_event_unref (event);
1520 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1522 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1525 g_return_val_if_fail (event != NULL, FALSE);
1527 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1528 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1530 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1531 GST_EVENT_TYPE_NAME (event));
1534 gst_event_unref (event);
1539 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1540 GstMatroskaIndex * entry, gboolean reset)
1544 GST_OBJECT_LOCK (demux);
1546 /* seek (relative to matroska segment) */
1547 /* position might be invalid; will error when streaming resumes ... */
1548 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1550 GST_DEBUG_OBJECT (demux, "Seeked to offset %" G_GUINT64_FORMAT ", block %d, "
1551 "time %" GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1552 entry->block, GST_TIME_ARGS (entry->time));
1554 /* update the time */
1555 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1556 demux->common.segment.last_stop = entry->time;
1557 demux->seek_block = entry->block;
1558 demux->seek_first = TRUE;
1559 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1561 for (i = 0; i < demux->common.src->len; i++) {
1562 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1565 stream->to_offset = G_MAXINT64;
1567 if (stream->from_offset != -1)
1568 stream->to_offset = stream->from_offset;
1570 stream->from_offset = -1;
1573 GST_OBJECT_UNLOCK (demux);
1579 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1589 /* searches for a cluster start from @pos,
1590 * return GST_FLOW_OK and cluster position in @pos if found */
1591 static GstFlowReturn
1592 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1594 gint64 newpos = *pos;
1596 GstFlowReturn ret = GST_FLOW_OK;
1597 const guint chunk = 64 * 1024;
1598 GstBuffer *buf = NULL;
1603 orig_offset = demux->common.offset;
1605 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1608 if (demux->clusters) {
1611 cpos = gst_util_array_binary_search (demux->clusters->data,
1612 demux->clusters->len, sizeof (gint64),
1613 (GCompareDataFunc) gst_matroska_cluster_compare,
1614 GST_SEARCH_MODE_AFTER, pos, NULL);
1617 GST_DEBUG_OBJECT (demux,
1618 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1619 demux->common.offset = *cpos;
1620 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1621 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1622 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1629 /* read in at newpos and scan for ebml cluster id */
1631 GstByteReader reader;
1635 gst_buffer_unref (buf);
1638 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1639 if (ret != GST_FLOW_OK)
1641 GST_DEBUG_OBJECT (demux, "read buffer size %d at offset %" G_GINT64_FORMAT,
1642 GST_BUFFER_SIZE (buf), newpos);
1643 gst_byte_reader_init_from_buffer (&reader, buf);
1645 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1646 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1647 if (cluster_pos >= 0) {
1648 newpos += cluster_pos;
1649 /* prepare resuming at next byte */
1650 gst_byte_reader_skip (&reader, cluster_pos + 1);
1651 GST_DEBUG_OBJECT (demux,
1652 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1653 /* extra checks whether we really sync'ed to a cluster:
1654 * - either it is the first and only cluster
1655 * - either there is a cluster after this one
1656 * - either cluster length is undefined
1658 /* ok if first cluster (there may not a subsequent one) */
1659 if (newpos == demux->first_cluster_offset) {
1660 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1663 demux->common.offset = newpos;
1664 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1665 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1666 if (ret != GST_FLOW_OK) {
1667 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1670 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1671 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1673 /* ok if undefined length or first cluster */
1674 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1675 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1679 demux->common.offset += length + needed;
1680 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1681 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1682 if (ret != GST_FLOW_OK)
1684 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1685 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1686 if (id == GST_MATROSKA_ID_CLUSTER)
1688 /* not ok, resume */
1691 /* partial cluster id may have been in tail of buffer */
1692 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1697 gst_buffer_unref (buf);
1702 demux->common.offset = orig_offset;
1707 /* bisect and scan through file for cluster starting before @time,
1708 * returns fake index entry with corresponding info on cluster */
1709 static GstMatroskaIndex *
1710 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1712 GstMatroskaIndex *entry = NULL;
1713 GstMatroskaReadState current_state;
1714 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1715 gint64 opos, newpos, startpos = 0, current_offset;
1716 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1717 const guint chunk = 64 * 1024;
1718 GstBuffer *buf = NULL;
1724 /* (under)estimate new position, resync using cluster ebml id,
1725 * and scan forward to appropriate cluster
1726 * (and re-estimate if need to go backward) */
1728 prev_cluster_time = GST_CLOCK_TIME_NONE;
1730 /* store some current state */
1731 current_state = demux->common.state;
1732 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1734 current_cluster_offset = demux->cluster_offset;
1735 current_cluster_time = demux->cluster_time;
1736 current_offset = demux->common.offset;
1738 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1740 /* estimate using start and current position */
1741 GST_OBJECT_LOCK (demux);
1742 opos = demux->common.offset - demux->common.ebml_segment_start;
1743 otime = demux->common.segment.last_stop;
1744 GST_OBJECT_UNLOCK (demux);
1746 /* avoid division by zero in first estimation below */
1751 GST_LOG_OBJECT (demux,
1752 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1753 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1754 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1755 GST_TIME_ARGS (otime - demux->stream_start_time),
1756 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1758 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1759 time - demux->stream_start_time,
1760 otime - demux->stream_start_time) - chunk;
1763 /* favour undershoot */
1764 newpos = newpos * 90 / 100;
1765 newpos += demux->common.ebml_segment_start;
1767 GST_DEBUG_OBJECT (demux,
1768 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1769 GST_TIME_ARGS (time), newpos);
1771 /* and at least start scanning before previous scan start to avoid looping */
1772 startpos = startpos * 90 / 100;
1773 if (startpos && startpos < newpos)
1776 /* read in at newpos and scan for ebml cluster id */
1780 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1781 if (ret == GST_FLOW_UNEXPECTED) {
1782 /* heuristic HACK */
1783 newpos = startpos * 80 / 100;
1784 GST_DEBUG_OBJECT (demux, "EOS; "
1785 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1786 GST_TIME_ARGS (time), newpos);
1789 } else if (ret != GST_FLOW_OK) {
1796 /* then start scanning and parsing for cluster time,
1797 * re-estimate if overshoot, otherwise next cluster and so on */
1798 demux->common.offset = newpos;
1799 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1801 guint64 cluster_size = 0;
1803 /* peek and parse some elements */
1804 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1805 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1806 if (ret != GST_FLOW_OK)
1808 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1809 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1811 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1812 if (ret != GST_FLOW_OK)
1815 if (id == GST_MATROSKA_ID_CLUSTER) {
1816 cluster_time = GST_CLOCK_TIME_NONE;
1817 if (length == G_MAXUINT64)
1820 cluster_size = length + needed;
1822 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1823 cluster_time == GST_CLOCK_TIME_NONE) {
1824 cluster_time = demux->cluster_time * demux->common.time_scale;
1825 cluster_offset = demux->cluster_offset;
1826 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1827 " with time %" GST_TIME_FORMAT, cluster_offset,
1828 GST_TIME_ARGS (cluster_time));
1829 if (cluster_time > time) {
1830 GST_DEBUG_OBJECT (demux, "overshot target");
1831 /* cluster overshoots */
1832 if (cluster_offset == demux->first_cluster_offset) {
1833 /* but no prev one */
1834 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1835 prev_cluster_time = cluster_time;
1836 prev_cluster_offset = cluster_offset;
1839 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1840 /* prev cluster did not overshoot, so prev cluster is target */
1843 /* re-estimate using this new position info */
1844 opos = cluster_offset;
1845 otime = cluster_time;
1849 /* cluster undershoots, goto next one */
1850 prev_cluster_time = cluster_time;
1851 prev_cluster_offset = cluster_offset;
1852 /* skip cluster if length is defined,
1853 * otherwise will be skippingly parsed into */
1855 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1856 demux->common.offset = cluster_offset + cluster_size;
1857 demux->cluster_time = GST_CLOCK_TIME_NONE;
1859 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1866 if (ret == GST_FLOW_UNEXPECTED) {
1867 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1873 entry = g_new0 (GstMatroskaIndex, 1);
1874 entry->time = prev_cluster_time;
1875 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1876 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1877 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1881 gst_buffer_unref (buf);
1883 /* restore some state */
1884 demux->cluster_offset = current_cluster_offset;
1885 demux->cluster_time = current_cluster_time;
1886 demux->common.offset = current_offset;
1887 demux->common.state = current_state;
1893 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1894 GstPad * pad, GstEvent * event)
1896 GstMatroskaIndex *entry = NULL;
1897 GstMatroskaIndex scan_entry;
1899 GstSeekType cur_type, stop_type;
1901 gboolean flush, keyunit;
1904 GstMatroskaTrackContext *track = NULL;
1905 GstSegment seeksegment = { 0, };
1906 gboolean update = TRUE;
1909 track = gst_pad_get_element_private (pad);
1911 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1914 /* we can only seek on time */
1915 if (format != GST_FORMAT_TIME) {
1916 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1920 /* copy segment, we need this because we still need the old
1921 * segment when we close the current segment. */
1922 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1925 GST_DEBUG_OBJECT (demux, "configuring seek");
1926 gst_segment_set_seek (&seeksegment, rate, format, flags,
1927 cur_type, cur, stop_type, stop, &update);
1928 /* compensate for clip start time */
1929 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1930 seeksegment.last_stop += demux->stream_start_time;
1931 seeksegment.start += demux->stream_start_time;
1932 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1933 seeksegment.stop += demux->stream_start_time;
1934 /* note that time should stay at indicated position */
1938 flush = !!(flags & GST_SEEK_FLAG_FLUSH);
1939 keyunit = !!(flags & GST_SEEK_FLAG_KEY_UNIT);
1941 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1944 /* only have to update some segment,
1945 * but also still have to honour flush and so on */
1946 GST_DEBUG_OBJECT (demux, "... no update");
1947 /* bad goto, bad ... */
1951 /* check sanity before we start flushing and all that */
1952 GST_OBJECT_LOCK (demux);
1953 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
1954 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
1955 seeksegment.last_stop, &demux->seek_index, &demux->seek_entry)) ==
1957 /* pull mode without index can scan later on */
1958 if (demux->common.index || demux->streaming) {
1959 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
1960 GST_OBJECT_UNLOCK (demux);
1964 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
1965 GST_OBJECT_UNLOCK (demux);
1967 if (demux->streaming) {
1968 /* need to seek to cluster start to pick up cluster time */
1969 /* upstream takes care of flushing and all that
1970 * ... and newsegment event handling takes care of the rest */
1971 return perform_seek_to_offset (demux,
1972 entry->pos + demux->common.ebml_segment_start);
1977 GST_DEBUG_OBJECT (demux, "Starting flush");
1978 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_start ());
1979 gst_matroska_demux_send_event (demux, gst_event_new_flush_start ());
1981 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
1982 gst_pad_pause_task (demux->common.sinkpad);
1988 /* now grab the stream lock so that streaming cannot continue, for
1989 * non flushing seeks when the element is in PAUSED this could block
1991 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
1992 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
1994 /* pull mode without index can do some scanning */
1995 if (!demux->streaming && !demux->common.index) {
1996 /* need to stop flushing upstream as we need it next */
1998 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_stop ());
1999 entry = gst_matroska_demux_search_pos (demux, seeksegment.last_stop);
2000 /* keep local copy */
2002 scan_entry = *entry;
2004 entry = &scan_entry;
2006 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2008 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop ());
2014 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start to %"
2015 GST_TIME_FORMAT, GST_TIME_ARGS (entry->time));
2016 seeksegment.start = entry->time;
2017 seeksegment.last_stop = entry->time;
2018 seeksegment.time = entry->time - demux->stream_start_time;
2023 GST_DEBUG_OBJECT (demux, "Stopping flush");
2024 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_stop ());
2025 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop ());
2026 } else if (demux->segment_running && update) {
2027 GST_DEBUG_OBJECT (demux, "Closing currently running segment");
2029 GST_OBJECT_LOCK (demux);
2030 if (demux->close_segment)
2031 gst_event_unref (demux->close_segment);
2033 demux->close_segment = gst_event_new_new_segment (TRUE,
2034 demux->common.segment.rate, GST_FORMAT_TIME,
2035 demux->common.segment.start, demux->common.segment.last_stop,
2036 demux->common.segment.time);
2037 GST_OBJECT_UNLOCK (demux);
2040 GST_OBJECT_LOCK (demux);
2041 /* now update the real segment info */
2042 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2043 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2044 GST_OBJECT_UNLOCK (demux);
2046 /* update some (segment) state */
2047 if (update && !gst_matroska_demux_move_to_entry (demux, entry, TRUE))
2050 /* notify start of new segment */
2051 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2054 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2055 GST_FORMAT_TIME, demux->common.segment.start);
2056 gst_element_post_message (GST_ELEMENT (demux), msg);
2059 GST_OBJECT_LOCK (demux);
2060 if (demux->new_segment)
2061 gst_event_unref (demux->new_segment);
2062 demux->new_segment = gst_event_new_new_segment_full (!update,
2063 demux->common.segment.rate, demux->common.segment.applied_rate,
2064 demux->common.segment.format, demux->common.segment.start,
2065 demux->common.segment.stop, demux->common.segment.time);
2066 GST_OBJECT_UNLOCK (demux);
2068 /* restart our task since it might have been stopped when we did the
2070 demux->segment_running = TRUE;
2071 gst_pad_start_task (demux->common.sinkpad,
2072 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad);
2074 /* streaming can continue now */
2075 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2081 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2082 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2088 * Handle whether we can perform the seek event or if we have to let the chain
2089 * function handle seeks to build the seek indexes first.
2092 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2096 GstSeekType cur_type, stop_type;
2101 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2106 /* we can only seek on time */
2107 if (format != GST_FORMAT_TIME) {
2108 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2112 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2113 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2117 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2118 GST_DEBUG_OBJECT (demux,
2119 "Non-flushing seek not supported in streaming mode");
2123 if (flags & GST_SEEK_FLAG_SEGMENT) {
2124 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2128 /* check for having parsed index already */
2129 if (!demux->common.index_parsed) {
2130 gboolean building_index;
2133 if (!demux->index_offset) {
2134 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2138 GST_OBJECT_LOCK (demux);
2139 /* handle the seek event in the chain function */
2140 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2141 /* no more seek can be issued until state reset to _DATA */
2143 /* copy the event */
2144 if (demux->seek_event)
2145 gst_event_unref (demux->seek_event);
2146 demux->seek_event = gst_event_ref (event);
2148 /* set the building_index flag so that only one thread can setup the
2149 * structures for index seeking. */
2150 building_index = demux->building_index;
2151 if (!building_index) {
2152 demux->building_index = TRUE;
2153 offset = demux->index_offset;
2155 GST_OBJECT_UNLOCK (demux);
2157 if (!building_index) {
2158 /* seek to the first subindex or legacy index */
2159 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2160 return perform_seek_to_offset (demux, offset);
2163 /* well, we are handling it already */
2167 /* delegate to tweaked regular seek */
2168 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2172 gst_matroska_demux_handle_src_event (GstPad * pad, GstEvent * event)
2174 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
2175 gboolean res = TRUE;
2177 switch (GST_EVENT_TYPE (event)) {
2178 case GST_EVENT_SEEK:
2179 /* no seeking until we are (safely) ready */
2180 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2181 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2184 if (!demux->streaming)
2185 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2187 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2188 gst_event_unref (event);
2193 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2194 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2195 GstMatroskaTrackVideoContext *videocontext =
2196 (GstMatroskaTrackVideoContext *) context;
2198 GstClockTimeDiff diff;
2199 GstClockTime timestamp;
2201 gst_event_parse_qos (event, &proportion, &diff, ×tamp);
2203 GST_OBJECT_LOCK (demux);
2204 videocontext->earliest_time = timestamp + diff;
2205 GST_OBJECT_UNLOCK (demux);
2208 gst_event_unref (event);
2212 /* events we don't need to handle */
2213 case GST_EVENT_NAVIGATION:
2214 gst_event_unref (event);
2218 case GST_EVENT_LATENCY:
2220 res = gst_pad_push_event (demux->common.sinkpad, event);
2224 gst_object_unref (demux);
2229 static GstFlowReturn
2230 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2232 GstFlowReturn ret = GST_FLOW_UNEXPECTED;
2233 gboolean done = TRUE;
2236 g_return_val_if_fail (demux->seek_index, GST_FLOW_UNEXPECTED);
2237 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2238 GST_FLOW_UNEXPECTED);
2240 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2242 if (!demux->seek_entry) {
2243 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2247 for (i = 0; i < demux->common.src->len; i++) {
2248 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2250 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2251 ", stream %d at %" GST_TIME_FORMAT,
2252 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2253 GST_TIME_ARGS (stream->from_time));
2254 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2255 if (stream->from_time > demux->common.segment.start) {
2256 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2260 /* nothing pushed for this stream;
2261 * likely seek entry did not start at keyframe, so all was skipped.
2262 * So we need an earlier entry */
2268 GstMatroskaIndex *entry;
2270 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2271 --demux->seek_entry);
2272 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE))
2282 static GstFlowReturn
2283 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2285 GstFlowReturn ret = GST_FLOW_OK;
2288 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2290 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2291 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2295 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2296 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2300 /* one track within the "all-tracks" header */
2301 case GST_MATROSKA_ID_TRACKENTRY:
2302 ret = gst_matroska_demux_add_stream (demux, ebml);
2306 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2311 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2313 demux->tracks_parsed = TRUE;
2319 * Read signed/unsigned "EBML" numbers.
2320 * Return: number of bytes processed.
2324 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2326 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2334 while (read <= 8 && !(total & len_mask)) {
2341 if ((total &= (len_mask - 1)) == len_mask - 1)
2346 if (data[n] == 0xff)
2348 total = (total << 8) | data[n];
2352 if (read == num_ffs && total != 0)
2361 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2366 /* read as unsigned number first */
2367 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2371 if (unum == G_MAXUINT64)
2374 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2380 * Mostly used for subtitles. We add void filler data for each
2381 * lagging stream to make sure we don't deadlock.
2385 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2389 GST_OBJECT_LOCK (demux);
2391 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2392 GST_TIME_ARGS (demux->common.segment.last_stop));
2394 g_assert (demux->common.num_streams == demux->common.src->len);
2395 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2396 GstMatroskaTrackContext *context;
2398 context = g_ptr_array_index (demux->common.src, stream_nr);
2400 GST_LOG_OBJECT (demux,
2401 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2402 GST_TIME_ARGS (context->pos));
2404 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2405 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2409 /* does it lag? 0.5 seconds is a random threshold...
2410 * lag need only be considered if we have advanced into requested segment */
2411 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2412 GST_CLOCK_TIME_IS_VALID (demux->common.segment.last_stop) &&
2413 demux->common.segment.last_stop > demux->common.segment.start &&
2414 context->pos + (GST_SECOND / 2) < demux->common.segment.last_stop) {
2418 new_start = demux->common.segment.last_stop - (GST_SECOND / 2);
2419 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop))
2420 new_start = MIN (new_start, demux->common.segment.stop);
2421 GST_DEBUG_OBJECT (demux,
2422 "Synchronizing stream %d with others by advancing time " "from %"
2423 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2424 GST_TIME_ARGS (context->pos), GST_TIME_ARGS (new_start));
2426 context->pos = new_start;
2428 /* advance stream time */
2429 event = gst_event_new_new_segment (TRUE, demux->common.segment.rate,
2430 demux->common.segment.format, new_start, demux->common.segment.stop,
2432 GST_OBJECT_UNLOCK (demux);
2433 gst_pad_push_event (context->pad, event);
2434 GST_OBJECT_LOCK (demux);
2438 GST_OBJECT_UNLOCK (demux);
2441 static GstFlowReturn
2442 gst_matroska_demux_push_hdr_buf (GstMatroskaDemux * demux,
2443 GstMatroskaTrackContext * stream, guint8 * data, guint len)
2445 GstFlowReturn ret, cret;
2446 GstBuffer *header_buf;
2448 header_buf = gst_buffer_new_and_alloc (len);
2449 gst_buffer_set_caps (header_buf, stream->caps);
2450 memcpy (GST_BUFFER_DATA (header_buf), data, len);
2452 if (stream->set_discont) {
2453 GST_BUFFER_FLAG_SET (header_buf, GST_BUFFER_FLAG_DISCONT);
2454 stream->set_discont = FALSE;
2457 ret = gst_pad_push (stream->pad, header_buf);
2460 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
2465 static GstFlowReturn
2466 gst_matroska_demux_push_flac_codec_priv_data (GstMatroskaDemux * demux,
2467 GstMatroskaTrackContext * stream)
2473 GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
2475 pdata = (guint8 *) stream->codec_priv;
2477 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2478 if (stream->codec_priv_size < ((4) + (4 + 34))) {
2479 GST_WARNING_OBJECT (demux, "not enough codec priv data for flac headers");
2480 return GST_FLOW_ERROR;
2483 if (memcmp (pdata, "fLaC", 4) != 0) {
2484 GST_WARNING_OBJECT (demux, "no flac marker at start of stream headers");
2485 return GST_FLOW_ERROR;
2488 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 4);
2489 if (ret != GST_FLOW_OK)
2492 off = 4; /* skip fLaC marker */
2493 while (off < stream->codec_priv_size) {
2494 len = GST_READ_UINT8 (pdata + off + 1) << 16;
2495 len |= GST_READ_UINT8 (pdata + off + 2) << 8;
2496 len |= GST_READ_UINT8 (pdata + off + 3);
2498 GST_DEBUG_OBJECT (demux, "header packet: len=%u bytes, flags=0x%02x",
2499 len, (guint) pdata[off]);
2501 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata + off, len + 4);
2502 if (ret != GST_FLOW_OK)
2510 static GstFlowReturn
2511 gst_matroska_demux_push_speex_codec_priv_data (GstMatroskaDemux * demux,
2512 GstMatroskaTrackContext * stream)
2517 GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
2519 pdata = (guint8 *) stream->codec_priv;
2521 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2522 if (stream->codec_priv_size < 80) {
2523 GST_WARNING_OBJECT (demux, "not enough codec priv data for speex headers");
2524 return GST_FLOW_ERROR;
2527 if (memcmp (pdata, "Speex ", 8) != 0) {
2528 GST_WARNING_OBJECT (demux, "no Speex marker at start of stream headers");
2529 return GST_FLOW_ERROR;
2532 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 80);
2533 if (ret != GST_FLOW_OK)
2536 if (stream->codec_priv_size == 80)
2539 return gst_matroska_demux_push_hdr_buf (demux, stream, pdata + 80,
2540 stream->codec_priv_size - 80);
2543 static GstFlowReturn
2544 gst_matroska_demux_push_xiph_codec_priv_data (GstMatroskaDemux * demux,
2545 GstMatroskaTrackContext * stream)
2548 guint8 *p = (guint8 *) stream->codec_priv;
2549 gint i, offset, num_packets;
2550 guint *length, last;
2552 if (stream->codec_priv == NULL || stream->codec_priv_size == 0) {
2553 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
2554 ("Missing codec private data for xiph headers, broken file"));
2555 return GST_FLOW_ERROR;
2558 /* start of the stream and vorbis audio or theora video, need to
2559 * send the codec_priv data as first three packets */
2560 num_packets = p[0] + 1;
2561 GST_DEBUG_OBJECT (demux, "%u stream headers, total length=%u bytes",
2562 (guint) num_packets, stream->codec_priv_size);
2564 length = g_alloca (num_packets * sizeof (guint));
2568 /* first packets, read length values */
2569 for (i = 0; i < num_packets - 1; i++) {
2571 while (offset < stream->codec_priv_size) {
2572 length[i] += p[offset];
2573 if (p[offset++] != 0xff)
2578 if (offset + last > stream->codec_priv_size)
2579 return GST_FLOW_ERROR;
2581 /* last packet is the remaining size */
2582 length[i] = stream->codec_priv_size - offset - last;
2584 for (i = 0; i < num_packets; i++) {
2585 GST_DEBUG_OBJECT (demux, "buffer %d: length=%u bytes", i,
2587 if (offset + length[i] > stream->codec_priv_size)
2588 return GST_FLOW_ERROR;
2591 gst_matroska_demux_push_hdr_buf (demux, stream, p + offset, length[i]);
2592 if (ret != GST_FLOW_OK)
2595 offset += length[i];
2601 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2602 GstMatroskaTrackContext * stream)
2606 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2608 if (!stream->codec_priv)
2611 /* ideally, VobSub private data should be parsed and stored more convenient
2612 * elsewhere, but for now, only interested in a small part */
2614 /* make sure we have terminating 0 */
2615 buf = g_strndup ((gchar *) stream->codec_priv, stream->codec_priv_size);
2617 /* just locate and parse palette part */
2618 start = strstr (buf, "palette:");
2623 guint8 r, g, b, y, u, v;
2626 while (g_ascii_isspace (*start))
2628 for (i = 0; i < 16; i++) {
2629 if (sscanf (start, "%06x", &col) != 1)
2632 while ((*start == ',') || g_ascii_isspace (*start))
2634 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2635 r = (col >> 16) & 0xff;
2636 g = (col >> 8) & 0xff;
2638 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2640 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2641 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2642 clut[i] = (y << 16) | (u << 8) | v;
2645 /* got them all without problems; build and send event */
2649 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2650 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2651 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2652 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2653 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2654 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2655 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2656 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2657 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2658 G_TYPE_INT, clut[15], NULL);
2660 gst_pad_push_event (stream->pad,
2661 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
2667 static GstFlowReturn
2668 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2669 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2672 guint seq_header_len;
2675 if (stream->codec_state) {
2676 seq_header = stream->codec_state;
2677 seq_header_len = stream->codec_state_size;
2678 } else if (stream->codec_priv) {
2679 seq_header = stream->codec_priv;
2680 seq_header_len = stream->codec_priv_size;
2685 /* Sequence header only needed for keyframes */
2686 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2689 if (GST_BUFFER_SIZE (*buf) < 4)
2692 header = GST_READ_UINT32_BE (GST_BUFFER_DATA (*buf));
2693 /* Sequence start code, if not found prepend */
2694 if (header != 0x000001b3) {
2697 newbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (*buf) + seq_header_len);
2698 gst_buffer_set_caps (newbuf, stream->caps);
2700 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2701 gst_buffer_copy_metadata (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2702 GST_BUFFER_COPY_FLAGS);
2703 g_memmove (GST_BUFFER_DATA (newbuf), seq_header, seq_header_len);
2704 g_memmove (GST_BUFFER_DATA (newbuf) + seq_header_len,
2705 GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
2706 gst_buffer_unref (*buf);
2713 static GstFlowReturn
2714 gst_matroska_demux_add_wvpk_header (GstElement * element,
2715 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2717 GstMatroskaTrackAudioContext *audiocontext =
2718 (GstMatroskaTrackAudioContext *) stream;
2719 GstBuffer *newbuf = NULL;
2729 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2732 wvh.total_samples = -1;
2733 wvh.block_index = audiocontext->wvpk_block_index;
2735 if (audiocontext->channels <= 2) {
2736 guint32 block_samples;
2738 block_samples = GST_READ_UINT32_LE (GST_BUFFER_DATA (*buf));
2739 /* we need to reconstruct the header of the wavpack block */
2741 /* -20 because ck_size is the size of the wavpack block -8
2742 * and lace_size is the size of the wavpack block + 12
2743 * (the three guint32 of the header that already are in the buffer) */
2744 wvh.ck_size = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 20;
2746 /* block_samples, flags and crc are already in the buffer */
2747 newlen = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 12;
2748 newbuf = gst_buffer_new_and_alloc (newlen);
2749 gst_buffer_set_caps (newbuf, stream->caps);
2751 data = GST_BUFFER_DATA (newbuf);
2756 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2757 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2758 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2759 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2760 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2761 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2762 g_memmove (data + 20, GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
2763 gst_buffer_copy_metadata (newbuf, *buf,
2764 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
2765 gst_buffer_unref (*buf);
2767 audiocontext->wvpk_block_index += block_samples;
2772 guint32 block_samples, flags, crc, blocksize;
2774 data = GST_BUFFER_DATA (*buf);
2775 size = GST_BUFFER_SIZE (*buf);
2778 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2779 return GST_FLOW_ERROR;
2782 block_samples = GST_READ_UINT32_LE (data);
2787 flags = GST_READ_UINT32_LE (data);
2790 crc = GST_READ_UINT32_LE (data);
2793 blocksize = GST_READ_UINT32_LE (data);
2797 if (blocksize == 0 || size < blocksize)
2800 if (newbuf == NULL) {
2801 newbuf = gst_buffer_new_and_alloc (sizeof (Wavpack4Header) + blocksize);
2802 gst_buffer_set_caps (newbuf, stream->caps);
2804 gst_buffer_copy_metadata (newbuf, *buf,
2805 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
2808 outdata = GST_BUFFER_DATA (newbuf);
2810 GST_BUFFER_SIZE (newbuf) += sizeof (Wavpack4Header) + blocksize;
2811 GST_BUFFER_DATA (newbuf) =
2812 g_realloc (GST_BUFFER_DATA (newbuf), GST_BUFFER_SIZE (newbuf));
2813 GST_BUFFER_MALLOCDATA (newbuf) = GST_BUFFER_DATA (newbuf);
2814 outdata = GST_BUFFER_DATA (newbuf);
2817 outdata[outpos] = 'w';
2818 outdata[outpos + 1] = 'v';
2819 outdata[outpos + 2] = 'p';
2820 outdata[outpos + 3] = 'k';
2823 GST_WRITE_UINT32_LE (outdata + outpos,
2824 blocksize + sizeof (Wavpack4Header) - 8);
2825 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2826 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2827 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2828 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2829 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2830 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2831 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2832 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2835 g_memmove (outdata + outpos, data, blocksize);
2836 outpos += blocksize;
2840 gst_buffer_unref (*buf);
2842 audiocontext->wvpk_block_index += block_samples;
2848 /* @text must be null-terminated */
2850 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2855 /* yes, this might all lead to false positives ... */
2856 tag = (gchar *) text;
2857 while ((tag = strchr (tag, '<'))) {
2859 if (*tag != '\0' && *(tag + 1) == '>') {
2860 /* some common convenience ones */
2861 /* maybe any character will do here ? */
2874 if (strstr (text, "<span"))
2880 static GstFlowReturn
2881 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2882 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2884 GstMatroskaTrackSubtitleContext *sub_stream;
2885 const gchar *encoding, *data;
2891 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
2893 data = (const gchar *) GST_BUFFER_DATA (*buf);
2894 size = GST_BUFFER_SIZE (*buf);
2896 if (!sub_stream->invalid_utf8) {
2897 if (g_utf8_validate (data, size, NULL)) {
2900 GST_WARNING_OBJECT (element, "subtitle stream %d is not valid UTF-8, this "
2901 "is broken according to the matroska specification", stream->num);
2902 sub_stream->invalid_utf8 = TRUE;
2905 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
2906 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
2907 if (encoding == NULL || *encoding == '\0') {
2908 /* if local encoding is UTF-8 and no encoding specified
2909 * via the environment variable, assume ISO-8859-15 */
2910 if (g_get_charset (&encoding)) {
2911 encoding = "ISO-8859-15";
2915 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
2919 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
2920 encoding, err->message);
2924 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
2925 encoding = "ISO-8859-15";
2926 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
2930 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
2931 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
2934 utf8 = g_strdup ("invalid subtitle");
2936 newbuf = gst_buffer_new ();
2937 GST_BUFFER_MALLOCDATA (newbuf) = (guint8 *) utf8;
2938 GST_BUFFER_DATA (newbuf) = (guint8 *) utf8;
2939 GST_BUFFER_SIZE (newbuf) = strlen (utf8);
2940 gst_buffer_copy_metadata (newbuf, *buf,
2941 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
2942 gst_buffer_unref (*buf);
2945 data = (const gchar *) GST_BUFFER_DATA (*buf);
2946 size = GST_BUFFER_SIZE (*buf);
2949 /* caps claim markup text, so we need to escape text,
2950 * except if text is already markup and then needs no further escaping */
2951 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
2952 gst_matroska_demux_subtitle_chunk_has_tag (element, data);
2954 if (!sub_stream->seen_markup_tag) {
2955 utf8 = g_markup_escape_text (data, size);
2957 newbuf = gst_buffer_new ();
2958 GST_BUFFER_MALLOCDATA (newbuf) = (guint8 *) utf8;
2959 GST_BUFFER_DATA (newbuf) = (guint8 *) utf8;
2960 GST_BUFFER_SIZE (newbuf) = strlen (utf8);
2961 gst_buffer_copy_metadata (newbuf, *buf,
2962 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
2963 gst_buffer_unref (*buf);
2971 static GstFlowReturn
2972 gst_matroska_demux_check_aac (GstElement * element,
2973 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2978 data = GST_BUFFER_DATA (*buf);
2979 size = GST_BUFFER_SIZE (*buf);
2981 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
2985 /* tss, ADTS data, remove codec_data
2986 * still assume it is at least parsed */
2987 new_caps = gst_caps_copy (stream->caps);
2988 s = gst_caps_get_structure (new_caps, 0);
2990 gst_structure_remove_field (s, "codec_data");
2991 gst_caps_replace (&stream->caps, new_caps);
2992 gst_pad_set_caps (stream->pad, new_caps);
2993 gst_buffer_set_caps (*buf, new_caps);
2994 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
2995 "new caps: %" GST_PTR_FORMAT, new_caps);
2996 gst_caps_unref (new_caps);
2999 /* disable subsequent checking */
3000 stream->postprocess_frame = NULL;
3005 static GstFlowReturn
3006 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3007 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3008 gboolean is_simpleblock)
3010 GstMatroskaTrackContext *stream = NULL;
3011 GstFlowReturn ret = GST_FLOW_OK;
3012 gboolean readblock = FALSE;
3014 guint64 block_duration = -1;
3015 GstBuffer *buf = NULL;
3016 gint stream_num = -1, n, laces = 0;
3018 gint *lace_size = NULL;
3021 gint64 referenceblock = 0;
3024 offset = gst_ebml_read_get_offset (ebml);
3026 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3027 if (!is_simpleblock) {
3028 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3032 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3036 /* one block inside the group. Note, block parsing is one
3037 * of the harder things, so this code is a bit complicated.
3038 * See http://www.matroska.org/ for documentation. */
3039 case GST_MATROSKA_ID_SIMPLEBLOCK:
3040 case GST_MATROSKA_ID_BLOCK:
3046 gst_buffer_unref (buf);
3049 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3052 data = GST_BUFFER_DATA (buf);
3053 size = GST_BUFFER_SIZE (buf);
3055 /* first byte(s): blocknum */
3056 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3061 /* fetch stream from num */
3062 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3064 if (G_UNLIKELY (size < 3)) {
3065 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3066 /* non-fatal, try next block(group) */
3069 } else if (G_UNLIKELY (stream_num < 0 ||
3070 stream_num >= demux->common.num_streams)) {
3071 /* let's not give up on a stray invalid track number */
3072 GST_WARNING_OBJECT (demux,
3073 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3074 "; ignoring block", stream_num, num);
3078 stream = g_ptr_array_index (demux->common.src, stream_num);
3080 /* time (relative to cluster time) */
3081 time = ((gint16) GST_READ_UINT16_BE (data));
3084 flags = GST_READ_UINT8 (data);
3088 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3091 switch ((flags & 0x06) >> 1) {
3092 case 0x0: /* no lacing */
3094 lace_size = g_new (gint, 1);
3095 lace_size[0] = size;
3098 case 0x1: /* xiph lacing */
3099 case 0x2: /* fixed-size lacing */
3100 case 0x3: /* EBML lacing */
3102 goto invalid_lacing;
3103 laces = GST_READ_UINT8 (data) + 1;
3106 lace_size = g_new0 (gint, laces);
3108 switch ((flags & 0x06) >> 1) {
3109 case 0x1: /* xiph lacing */ {
3110 guint temp, total = 0;
3112 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3115 goto invalid_lacing;
3116 temp = GST_READ_UINT8 (data);
3117 lace_size[n] += temp;
3123 total += lace_size[n];
3125 lace_size[n] = size - total;
3129 case 0x2: /* fixed-size lacing */
3130 for (n = 0; n < laces; n++)
3131 lace_size[n] = size / laces;
3134 case 0x3: /* EBML lacing */ {
3137 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3141 total = lace_size[0] = num;
3142 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3146 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3150 lace_size[n] = lace_size[n - 1] + snum;
3151 total += lace_size[n];
3154 lace_size[n] = size - total;
3161 if (stream->send_xiph_headers) {
3162 ret = gst_matroska_demux_push_xiph_codec_priv_data (demux, stream);
3163 stream->send_xiph_headers = FALSE;
3166 if (stream->send_flac_headers) {
3167 ret = gst_matroska_demux_push_flac_codec_priv_data (demux, stream);
3168 stream->send_flac_headers = FALSE;
3171 if (stream->send_speex_headers) {
3172 ret = gst_matroska_demux_push_speex_codec_priv_data (demux, stream);
3173 stream->send_speex_headers = FALSE;
3176 if (stream->send_dvd_event) {
3177 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
3178 /* FIXME: should we send this event again after (flushing) seek ? */
3179 stream->send_dvd_event = FALSE;
3182 if (ret != GST_FLOW_OK)
3189 case GST_MATROSKA_ID_BLOCKDURATION:{
3190 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3191 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3196 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3197 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3198 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3203 case GST_MATROSKA_ID_CODECSTATE:{
3205 guint64 data_len = 0;
3208 gst_ebml_read_binary (ebml, &id, &data,
3209 &data_len)) != GST_FLOW_OK)
3212 if (G_UNLIKELY (stream == NULL)) {
3213 GST_WARNING_OBJECT (demux,
3214 "Unexpected CodecState subelement - ignoring");
3218 g_free (stream->codec_state);
3219 stream->codec_state = data;
3220 stream->codec_state_size = data_len;
3222 /* Decode if necessary */
3223 if (stream->encodings && stream->encodings->len > 0
3224 && stream->codec_state && stream->codec_state_size > 0) {
3225 if (!gst_matroska_decode_data (stream->encodings,
3226 &stream->codec_state, &stream->codec_state_size,
3227 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3228 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3232 GST_DEBUG_OBJECT (demux, "CodecState of %u bytes",
3233 stream->codec_state_size);
3238 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3242 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3243 case GST_MATROSKA_ID_BLOCKADDITIONS:
3244 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3245 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3246 case GST_MATROSKA_ID_SLICES:
3247 GST_DEBUG_OBJECT (demux,
3248 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3249 ret = gst_ebml_read_skip (ebml);
3257 /* reading a number or so could have failed */
3258 if (ret != GST_FLOW_OK)
3261 if (ret == GST_FLOW_OK && readblock) {
3262 guint64 duration = 0;
3263 gint64 lace_time = 0;
3264 gboolean delta_unit;
3266 stream = g_ptr_array_index (demux->common.src, stream_num);
3268 if (cluster_time != GST_CLOCK_TIME_NONE) {
3269 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3270 * Drop unless the lace contains timestamp 0? */
3271 if (time < 0 && (-time) > cluster_time) {
3274 if (stream->timecodescale == 1.0)
3275 lace_time = (cluster_time + time) * demux->common.time_scale;
3278 gst_util_guint64_to_gdouble ((cluster_time + time) *
3279 demux->common.time_scale) * stream->timecodescale;
3282 lace_time = GST_CLOCK_TIME_NONE;
3285 /* need to refresh segment info ASAP */
3286 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_newsegment) {
3287 GST_DEBUG_OBJECT (demux,
3288 "generating segment starting at %" GST_TIME_FORMAT,
3289 GST_TIME_ARGS (lace_time));
3290 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3291 demux->stream_start_time = lace_time;
3292 GST_DEBUG_OBJECT (demux,
3293 "Setting stream start time to %" GST_TIME_FORMAT,
3294 GST_TIME_ARGS (lace_time));
3296 gst_segment_set_newsegment (&demux->common.segment, FALSE,
3297 demux->common.segment.rate, GST_FORMAT_TIME, lace_time,
3298 GST_CLOCK_TIME_NONE, lace_time - demux->stream_start_time);
3299 /* now convey our segment notion downstream */
3300 gst_matroska_demux_send_event (demux, gst_event_new_new_segment (FALSE,
3301 demux->common.segment.rate, demux->common.segment.format,
3302 demux->common.segment.start, demux->common.segment.stop,
3303 demux->common.segment.start));
3304 demux->need_newsegment = FALSE;
3307 if (block_duration != -1) {
3308 if (stream->timecodescale == 1.0)
3309 duration = gst_util_uint64_scale (block_duration,
3310 demux->common.time_scale, 1);
3313 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3314 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3315 1)) * stream->timecodescale);
3316 } else if (stream->default_duration) {
3317 duration = stream->default_duration * laces;
3319 /* else duration is diff between timecode of this and next block */
3321 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3322 a ReferenceBlock implies that this is not a keyframe. In either
3323 case, it only makes sense for video streams. */
3324 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3325 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
3327 if (delta_unit && stream->set_discont) {
3328 /* When doing seeks or such, we need to restart on key frames or
3329 * decoders might choke. */
3330 GST_DEBUG_OBJECT (demux, "skipping delta unit");
3334 for (n = 0; n < laces; n++) {
3337 if (G_UNLIKELY (lace_size[n] > size)) {
3338 GST_WARNING_OBJECT (demux, "Invalid lace size");
3342 /* QoS for video track with an index. the assumption is that
3343 index entries point to keyframes, but if that is not true we
3344 will instad skip until the next keyframe. */
3345 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3346 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3347 stream->index_table && demux->common.segment.rate > 0.0) {
3348 GstMatroskaTrackVideoContext *videocontext =
3349 (GstMatroskaTrackVideoContext *) stream;
3350 GstClockTime earliest_time;
3351 GstClockTime earliest_stream_time;
3353 GST_OBJECT_LOCK (demux);
3354 earliest_time = videocontext->earliest_time;
3355 GST_OBJECT_UNLOCK (demux);
3356 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3357 GST_FORMAT_TIME, earliest_time);
3359 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3360 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3361 lace_time <= earliest_stream_time) {
3362 /* find index entry (keyframe) <= earliest_stream_time */
3363 GstMatroskaIndex *entry =
3364 gst_util_array_binary_search (stream->index_table->data,
3365 stream->index_table->len, sizeof (GstMatroskaIndex),
3366 (GCompareDataFunc) gst_matroska_index_seek_find,
3367 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3369 /* if that entry (keyframe) is after the current the current
3370 buffer, we can skip pushing (and thus decoding) all
3371 buffers until that keyframe. */
3372 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3373 entry->time > lace_time) {
3374 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3375 stream->set_discont = TRUE;
3381 sub = gst_buffer_create_sub (buf,
3382 GST_BUFFER_SIZE (buf) - size, lace_size[n]);
3383 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3386 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3388 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3390 if (stream->encodings != NULL && stream->encodings->len > 0)
3391 sub = gst_matroska_decode_buffer (stream, sub);
3394 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3398 GST_BUFFER_TIMESTAMP (sub) = lace_time;
3400 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3401 GstClockTime last_stop_end;
3403 /* Check if this stream is after segment stop */
3404 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3405 lace_time >= demux->common.segment.stop) {
3406 GST_DEBUG_OBJECT (demux,
3407 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3408 GST_TIME_ARGS (demux->common.segment.stop));
3409 gst_buffer_unref (sub);
3412 if (offset >= stream->to_offset) {
3413 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3415 gst_buffer_unref (sub);
3419 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3420 * that landed us with timestamps not quite intended */
3421 GST_OBJECT_LOCK (demux);
3422 if (demux->max_gap_time &&
3423 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3424 demux->common.segment.rate > 0.0) {
3425 GstClockTimeDiff diff;
3426 GstEvent *event1, *event2;
3428 /* only send newsegments with increasing start times,
3429 * otherwise if these go back and forth downstream (sinks) increase
3430 * accumulated time and running_time */
3431 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3432 if (diff > 0 && diff > demux->max_gap_time
3433 && lace_time > demux->common.segment.start
3434 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3435 || lace_time < demux->common.segment.stop)) {
3436 GST_DEBUG_OBJECT (demux,
3437 "Gap of %" G_GINT64_FORMAT " ns detected in"
3438 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3439 "Sending updated NEWSEGMENT events", diff,
3440 stream->index, GST_TIME_ARGS (stream->pos),
3441 GST_TIME_ARGS (lace_time));
3442 /* send newsegment events such that the gap is not accounted in
3443 * accum time, hence running_time */
3444 /* close ahead of gap */
3445 event1 = gst_event_new_new_segment (TRUE,
3446 demux->common.segment.rate, demux->common.segment.format,
3447 demux->last_stop_end, demux->last_stop_end,
3448 demux->last_stop_end);
3450 event2 = gst_event_new_new_segment (FALSE,
3451 demux->common.segment.rate,
3452 demux->common.segment.format, lace_time,
3453 demux->common.segment.stop, lace_time);
3454 GST_OBJECT_UNLOCK (demux);
3455 gst_matroska_demux_send_event (demux, event1);
3456 gst_matroska_demux_send_event (demux, event2);
3457 GST_OBJECT_LOCK (demux);
3458 /* align segment view with downstream,
3459 * prevents double-counting accum when closing segment */
3460 gst_segment_set_newsegment (&demux->common.segment, FALSE,
3461 demux->common.segment.rate, demux->common.segment.format,
3462 lace_time, demux->common.segment.stop, lace_time);
3463 demux->common.segment.last_stop = lace_time;
3467 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.last_stop)
3468 || demux->common.segment.last_stop < lace_time) {
3469 demux->common.segment.last_stop = lace_time;
3471 GST_OBJECT_UNLOCK (demux);
3473 last_stop_end = lace_time;
3475 GST_BUFFER_DURATION (sub) = duration / laces;
3476 last_stop_end += GST_BUFFER_DURATION (sub);
3479 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3480 demux->last_stop_end < last_stop_end)
3481 demux->last_stop_end = last_stop_end;
3483 GST_OBJECT_LOCK (demux);
3484 if (demux->common.segment.duration == -1 ||
3485 demux->common.segment.duration <
3486 lace_time - demux->stream_start_time) {
3487 gst_segment_set_duration (&demux->common.segment, GST_FORMAT_TIME,
3488 last_stop_end - demux->stream_start_time);
3489 GST_OBJECT_UNLOCK (demux);
3490 gst_element_post_message (GST_ELEMENT_CAST (demux),
3491 gst_message_new_duration (GST_OBJECT_CAST (demux),
3492 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
3494 GST_OBJECT_UNLOCK (demux);
3498 stream->pos = lace_time;
3500 gst_matroska_demux_sync_streams (demux);
3502 if (stream->set_discont) {
3503 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3504 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3505 stream->set_discont = FALSE;
3508 /* reverse playback book-keeping */
3509 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3510 stream->from_time = lace_time;
3511 if (stream->from_offset == -1)
3512 stream->from_offset = offset;
3514 GST_DEBUG_OBJECT (demux,
3515 "Pushing lace %d, data of size %d for stream %d, time=%"
3516 GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
3517 GST_BUFFER_SIZE (sub), stream_num,
3518 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
3519 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3521 if (demux->common.element_index) {
3522 if (stream->index_writer_id == -1)
3523 gst_index_get_writer_id (demux->common.element_index,
3524 GST_OBJECT (stream->pad), &stream->index_writer_id);
3526 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3527 G_GUINT64_FORMAT " for writer id %d",
3528 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
3529 stream->index_writer_id);
3530 gst_index_add_association (demux->common.element_index,
3531 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3532 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3533 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
3534 cluster_offset, NULL);
3537 gst_buffer_set_caps (sub, GST_PAD_CAPS (stream->pad));
3539 /* Postprocess the buffers depending on the codec used */
3540 if (stream->postprocess_frame) {
3541 GST_LOG_OBJECT (demux, "running post process");
3542 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3545 /* At this point, we have a sub-buffer pointing at data within a larger
3546 buffer. This data might not be aligned with anything. If the data is
3547 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3548 for 32 bit samples, etc), or bad things will happen downstream as
3549 elements typically assume minimal alignment.
3550 Therefore, create an aligned copy if necessary. */
3551 g_assert (stream->alignment <= G_MEM_ALIGN);
3552 if (((guintptr) GST_BUFFER_DATA (sub)) & (stream->alignment - 1)) {
3553 GstBuffer *buffer = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (sub));
3554 memcpy (GST_BUFFER_DATA (buffer), GST_BUFFER_DATA (sub),
3555 GST_BUFFER_SIZE (sub));
3556 gst_buffer_copy_metadata (buffer, sub, GST_BUFFER_COPY_ALL);
3557 GST_DEBUG_OBJECT (demux, "We want output aligned on %d, reallocated",
3559 gst_buffer_unref (sub);
3563 ret = gst_pad_push (stream->pad, sub);
3564 if (demux->common.segment.rate < 0) {
3565 if (lace_time > demux->common.segment.stop
3566 && ret == GST_FLOW_UNEXPECTED) {
3567 /* In reverse playback we can get a GST_FLOW_UNEXPECTED when
3568 * we are at the end of the segment, so we just need to jump
3569 * back to the previous section. */
3570 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3575 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3578 size -= lace_size[n];
3579 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3580 lace_time += duration / laces;
3582 lace_time = GST_CLOCK_TIME_NONE;
3588 gst_buffer_unref (buf);
3599 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3604 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3605 /* non-fatal, try next block(group) */
3611 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3612 /* non-fatal, try next block(group) */
3618 /* return FALSE if block(group) should be skipped (due to a seek) */
3619 static inline gboolean
3620 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3622 if (G_UNLIKELY (demux->seek_block)) {
3623 if (!(--demux->seek_block)) {
3626 GST_LOG_OBJECT (demux, "should skip block due to seek");
3634 static GstFlowReturn
3635 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3639 guint64 seek_pos = (guint64) - 1;
3640 guint32 seek_id = 0;
3643 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3645 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3646 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3650 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3651 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3655 case GST_MATROSKA_ID_SEEKID:
3659 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3662 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3667 case GST_MATROSKA_ID_SEEKPOSITION:
3671 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3674 if (t > G_MAXINT64) {
3675 GST_WARNING_OBJECT (demux,
3676 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3680 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3686 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3692 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
3695 if (!seek_id || seek_pos == (guint64) - 1) {
3696 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3697 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3702 case GST_MATROSKA_ID_SEEKHEAD:
3705 case GST_MATROSKA_ID_CUES:
3706 case GST_MATROSKA_ID_TAGS:
3707 case GST_MATROSKA_ID_TRACKS:
3708 case GST_MATROSKA_ID_SEGMENTINFO:
3709 case GST_MATROSKA_ID_ATTACHMENTS:
3710 case GST_MATROSKA_ID_CHAPTERS:
3712 guint64 before_pos, length;
3716 length = gst_matroska_read_common_get_length (&demux->common);
3717 before_pos = demux->common.offset;
3719 if (length == (guint64) - 1) {
3720 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3724 /* check for validity */
3725 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3726 GST_WARNING_OBJECT (demux,
3727 "SeekHead reference lies outside file!" " (%"
3728 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3729 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3734 /* only pick up index location when streaming */
3735 if (demux->streaming) {
3736 if (seek_id == GST_MATROSKA_ID_CUES) {
3737 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3738 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3739 demux->index_offset);
3745 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3748 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3749 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3753 if (id != seek_id) {
3754 GST_WARNING_OBJECT (demux,
3755 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3756 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3759 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3764 demux->common.offset = before_pos;
3768 case GST_MATROSKA_ID_CLUSTER:
3770 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3772 GST_LOG_OBJECT (demux, "Cluster position");
3773 if (G_UNLIKELY (!demux->clusters))
3774 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3775 g_array_append_val (demux->clusters, pos);
3780 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3783 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3788 static GstFlowReturn
3789 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3791 GstFlowReturn ret = GST_FLOW_OK;
3794 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3796 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3797 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3801 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3802 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3806 case GST_MATROSKA_ID_SEEKENTRY:
3808 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3809 /* Ignore EOS and errors here */
3810 if (ret != GST_FLOW_OK) {
3811 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3818 ret = gst_matroska_read_common_parse_skip (&demux->common,
3819 ebml, "SeekHead", id);
3824 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3826 /* Sort clusters by position for easier searching */
3827 if (demux->clusters)
3828 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3833 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3835 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3837 static inline GstFlowReturn
3838 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
3840 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
3841 /* only a few blocks are expected/allowed to be large,
3842 * and will be recursed into, whereas others will be read and must fit */
3843 if (demux->streaming) {
3844 /* fatal in streaming case, as we can't step over easily */
3845 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3846 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
3847 "file might be corrupt.", bytes));
3848 return GST_FLOW_ERROR;
3850 /* indicate higher level to quietly give up */
3851 GST_DEBUG_OBJECT (demux,
3852 "too large block of size %" G_GUINT64_FORMAT, bytes);
3853 return GST_FLOW_ERROR;
3860 /* returns TRUE if we truely are in error state, and should give up */
3861 static inline gboolean
3862 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
3864 if (!demux->streaming && demux->next_cluster_offset > 0) {
3865 /* just repositioning to where next cluster should be and try from there */
3866 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
3867 G_GUINT64_FORMAT, demux->next_cluster_offset);
3868 demux->common.offset = demux->next_cluster_offset;
3869 demux->next_cluster_offset = 0;
3874 /* sigh, one last attempt above and beyond call of duty ...;
3875 * search for cluster mark following current pos */
3876 pos = demux->common.offset;
3877 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
3878 if (gst_matroska_demux_search_cluster (demux, &pos) != GST_FLOW_OK) {
3879 /* did not work, give up */
3882 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
3883 /* try that position */
3884 demux->common.offset = pos;
3890 static inline GstFlowReturn
3891 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
3893 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
3894 demux->common.offset += flush;
3895 if (demux->streaming) {
3898 /* hard to skip large blocks when streaming */
3899 ret = gst_matroska_demux_check_read_size (demux, flush);
3900 if (ret != GST_FLOW_OK)
3902 if (flush <= gst_adapter_available (demux->common.adapter))
3903 gst_adapter_flush (demux->common.adapter, flush);
3905 return GST_FLOW_UNEXPECTED;
3910 /* initializes @ebml with @bytes from input stream at current offset.
3911 * Returns UNEXPECTED if insufficient available,
3912 * ERROR if too much was attempted to read. */
3913 static inline GstFlowReturn
3914 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
3917 GstBuffer *buffer = NULL;
3918 GstFlowReturn ret = GST_FLOW_OK;
3920 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
3922 ret = gst_matroska_demux_check_read_size (demux, bytes);
3923 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
3924 if (!demux->streaming) {
3925 /* in pull mode, we can skip */
3926 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
3927 ret = GST_FLOW_OVERFLOW;
3929 /* otherwise fatal */
3930 ret = GST_FLOW_ERROR;
3934 if (demux->streaming) {
3935 if (gst_adapter_available (demux->common.adapter) >= bytes)
3936 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
3938 ret = GST_FLOW_UNEXPECTED;
3940 ret = gst_matroska_read_common_peek_bytes (&demux->common,
3941 demux->common.offset, bytes, &buffer, NULL);
3942 if (G_LIKELY (buffer)) {
3943 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
3944 demux->common.offset);
3945 demux->common.offset += bytes;
3952 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
3955 gboolean seekable = FALSE;
3956 gint64 start = -1, stop = -1;
3958 query = gst_query_new_seeking (GST_FORMAT_BYTES);
3959 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
3960 GST_DEBUG_OBJECT (demux, "seeking query failed");
3964 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
3966 /* try harder to query upstream size if we didn't get it the first time */
3967 if (seekable && stop == -1) {
3968 GstFormat fmt = GST_FORMAT_BYTES;
3970 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
3971 gst_pad_query_peer_duration (demux->common.sinkpad, &fmt, &stop);
3974 /* if upstream doesn't know the size, it's likely that it's not seekable in
3975 * practice even if it technically may be seekable */
3976 if (seekable && (start != 0 || stop <= start)) {
3977 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
3982 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
3983 G_GUINT64_FORMAT ")", seekable, start, stop);
3984 demux->seekable = seekable;
3986 gst_query_unref (query);
3989 static GstFlowReturn
3990 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
3996 GstFlowReturn ret = GST_FLOW_OK;
3998 GST_WARNING_OBJECT (demux,
3999 "Found Cluster element before Tracks, searching Tracks");
4002 before_pos = demux->common.offset;
4004 /* Search Tracks element */
4006 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4007 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4008 if (ret != GST_FLOW_OK)
4011 if (id != GST_MATROSKA_ID_TRACKS) {
4012 /* we may be skipping large cluster here, so forego size check etc */
4013 /* ... but we can't skip undefined size; force error */
4014 if (length == G_MAXUINT64) {
4015 ret = gst_matroska_demux_check_read_size (demux, length);
4018 demux->common.offset += needed;
4019 demux->common.offset += length;
4024 /* will lead to track parsing ... */
4025 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4030 demux->common.offset = before_pos;
4035 #define GST_READ_CHECK(stmt) \
4037 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4038 if (ret == GST_FLOW_OVERFLOW) { \
4039 ret = GST_FLOW_OK; \
4045 static GstFlowReturn
4046 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4047 guint64 length, guint needed)
4049 GstEbmlRead ebml = { 0, };
4050 GstFlowReturn ret = GST_FLOW_OK;
4053 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4054 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4056 /* if we plan to read and parse this element, we need prefix (id + length)
4057 * and the contents */
4058 /* mind about overflow wrap-around when dealing with undefined size */
4060 if (G_LIKELY (length != G_MAXUINT64))
4063 switch (demux->common.state) {
4064 case GST_MATROSKA_READ_STATE_START:
4066 case GST_EBML_ID_HEADER:
4067 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4068 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4069 if (ret != GST_FLOW_OK)
4071 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4072 gst_matroska_demux_check_seekability (demux);
4075 goto invalid_header;
4079 case GST_MATROSKA_READ_STATE_SEGMENT:
4081 case GST_MATROSKA_ID_SEGMENT:
4082 /* eat segment prefix */
4083 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4084 GST_DEBUG_OBJECT (demux,
4085 "Found Segment start at offset %" G_GUINT64_FORMAT,
4086 demux->common.offset);
4087 /* seeks are from the beginning of the segment,
4088 * after the segment ID/length */
4089 demux->common.ebml_segment_start = demux->common.offset;
4090 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4093 GST_WARNING_OBJECT (demux,
4094 "Expected a Segment ID (0x%x), but received 0x%x!",
4095 GST_MATROSKA_ID_SEGMENT, id);
4096 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4100 case GST_MATROSKA_READ_STATE_SCANNING:
4101 if (id != GST_MATROSKA_ID_CLUSTER &&
4102 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4105 case GST_MATROSKA_READ_STATE_HEADER:
4106 case GST_MATROSKA_READ_STATE_DATA:
4107 case GST_MATROSKA_READ_STATE_SEEK:
4109 case GST_MATROSKA_ID_SEGMENTINFO:
4110 if (!demux->common.segmentinfo_parsed) {
4111 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4112 ret = gst_matroska_read_common_parse_info (&demux->common,
4113 GST_ELEMENT_CAST (demux), &ebml);
4115 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4118 case GST_MATROSKA_ID_TRACKS:
4119 if (!demux->tracks_parsed) {
4120 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4121 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4123 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4126 case GST_MATROSKA_ID_CLUSTER:
4127 if (G_UNLIKELY (!demux->tracks_parsed)) {
4128 if (demux->streaming) {
4129 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4130 goto not_streamable;
4132 ret = gst_matroska_demux_find_tracks (demux);
4133 if (!demux->tracks_parsed)
4137 if (G_UNLIKELY (demux->common.state
4138 == GST_MATROSKA_READ_STATE_HEADER)) {
4139 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4140 demux->first_cluster_offset = demux->common.offset;
4141 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4142 gst_element_no_more_pads (GST_ELEMENT (demux));
4143 /* send initial newsegment - we wait till we know the first
4144 incoming timestamp, so we can properly set the start of
4146 demux->need_newsegment = TRUE;
4148 demux->cluster_time = GST_CLOCK_TIME_NONE;
4149 demux->cluster_offset = demux->common.offset;
4150 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4151 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4152 " not found in Cluster, trying next Cluster's first block instead",
4154 demux->seek_block = 0;
4156 demux->seek_first = FALSE;
4157 /* record next cluster for recovery */
4158 if (read != G_MAXUINT64)
4159 demux->next_cluster_offset = demux->cluster_offset + read;
4160 /* eat cluster prefix */
4161 gst_matroska_demux_flush (demux, needed);
4163 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4167 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4168 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4170 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4171 demux->cluster_time = num;
4172 if (demux->common.element_index) {
4173 if (demux->common.element_index_writer_id == -1)
4174 gst_index_get_writer_id (demux->common.element_index,
4175 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4176 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4177 G_GUINT64_FORMAT " for writer id %d",
4178 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4179 demux->common.element_index_writer_id);
4180 gst_index_add_association (demux->common.element_index,
4181 demux->common.element_index_writer_id,
4182 GST_ASSOCIATION_FLAG_KEY_UNIT,
4183 GST_FORMAT_TIME, demux->cluster_time,
4184 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4188 case GST_MATROSKA_ID_BLOCKGROUP:
4189 if (!gst_matroska_demux_seek_block (demux))
4191 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4192 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4193 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4194 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4195 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4197 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4199 case GST_MATROSKA_ID_SIMPLEBLOCK:
4200 if (!gst_matroska_demux_seek_block (demux))
4202 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4203 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4204 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4205 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4206 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4208 case GST_MATROSKA_ID_ATTACHMENTS:
4209 if (!demux->common.attachments_parsed) {
4210 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4211 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4212 GST_ELEMENT_CAST (demux), &ebml);
4214 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4217 case GST_MATROSKA_ID_TAGS:
4218 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4219 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4220 GST_ELEMENT_CAST (demux), &ebml);
4222 case GST_MATROSKA_ID_CHAPTERS:
4223 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4224 ret = gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4226 case GST_MATROSKA_ID_SEEKHEAD:
4227 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4228 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4230 case GST_MATROSKA_ID_CUES:
4231 if (demux->common.index_parsed) {
4232 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4235 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4236 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4237 /* only push based; delayed index building */
4238 if (ret == GST_FLOW_OK
4239 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4242 GST_OBJECT_LOCK (demux);
4243 event = demux->seek_event;
4244 demux->seek_event = NULL;
4245 GST_OBJECT_UNLOCK (demux);
4248 /* unlikely to fail, since we managed to seek to this point */
4249 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4251 /* resume data handling, main thread clear to seek again */
4252 GST_OBJECT_LOCK (demux);
4253 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4254 GST_OBJECT_UNLOCK (demux);
4257 case GST_MATROSKA_ID_POSITION:
4258 case GST_MATROSKA_ID_PREVSIZE:
4259 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4260 case GST_MATROSKA_ID_SILENTTRACKS:
4261 GST_DEBUG_OBJECT (demux,
4262 "Skipping Cluster subelement 0x%x - ignoring", id);
4266 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4267 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4273 if (ret == GST_FLOW_PARSE)
4277 gst_ebml_read_clear (&ebml);
4283 /* simply exit, maybe not enough data yet */
4284 /* no ebml to clear if read error */
4289 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4290 ("Failed to parse Element 0x%x", id));
4291 ret = GST_FLOW_ERROR;
4296 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4297 ("File layout does not permit streaming"));
4298 ret = GST_FLOW_ERROR;
4303 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4304 ("No Tracks element found"));
4305 ret = GST_FLOW_ERROR;
4310 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4311 ret = GST_FLOW_ERROR;
4316 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4317 ret = GST_FLOW_ERROR;
4323 gst_matroska_demux_loop (GstPad * pad)
4325 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4331 /* If we have to close a segment, send a new segment to do this now */
4332 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4333 if (G_UNLIKELY (demux->close_segment)) {
4334 gst_matroska_demux_send_event (demux, demux->close_segment);
4335 demux->close_segment = NULL;
4337 if (G_UNLIKELY (demux->new_segment)) {
4338 gst_matroska_demux_send_event (demux, demux->new_segment);
4339 demux->new_segment = NULL;
4343 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4344 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4345 if (ret == GST_FLOW_UNEXPECTED)
4347 if (ret != GST_FLOW_OK) {
4348 if (gst_matroska_demux_check_parse_error (demux))
4354 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4355 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4358 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4359 if (ret == GST_FLOW_UNEXPECTED)
4361 if (ret != GST_FLOW_OK)
4364 /* check if we're at the end of a configured segment */
4365 if (G_LIKELY (demux->common.src->len)) {
4368 g_assert (demux->common.num_streams == demux->common.src->len);
4369 for (i = 0; i < demux->common.src->len; i++) {
4370 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4372 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4373 GST_TIME_ARGS (context->pos));
4374 if (context->eos == FALSE)
4378 GST_INFO_OBJECT (demux, "All streams are EOS");
4379 ret = GST_FLOW_UNEXPECTED;
4384 if (G_UNLIKELY (demux->common.offset ==
4385 gst_matroska_read_common_get_length (&demux->common))) {
4386 GST_LOG_OBJECT (demux, "Reached end of stream");
4387 ret = GST_FLOW_UNEXPECTED;
4396 if (demux->common.segment.rate < 0.0) {
4397 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4398 if (ret == GST_FLOW_OK)
4405 const gchar *reason = gst_flow_get_name (ret);
4406 gboolean push_eos = FALSE;
4408 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4409 demux->segment_running = FALSE;
4410 gst_pad_pause_task (demux->common.sinkpad);
4412 if (ret == GST_FLOW_UNEXPECTED) {
4413 /* perform EOS logic */
4415 /* If we were in the headers, make sure we send no-more-pads.
4416 This will ensure decodebin2 does not get stuck thinking
4417 the chain is not complete yet, and waiting indefinitely. */
4418 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4419 if (demux->common.src->len == 0) {
4420 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4421 ("No pads created"));
4423 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4424 ("Failed to finish reading headers"));
4426 gst_element_no_more_pads (GST_ELEMENT (demux));
4429 /* Close the segment, i.e. update segment stop with the duration
4430 * if no stop was set */
4431 if (GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
4432 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)) {
4434 gst_event_new_new_segment_full (TRUE, demux->common.segment.rate,
4435 demux->common.segment.applied_rate, demux->common.segment.format,
4436 demux->common.segment.start,
4437 MAX (demux->last_stop_end, demux->common.segment.start),
4438 demux->common.segment.time);
4439 gst_matroska_demux_send_event (demux, event);
4442 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4445 /* for segment playback we need to post when (in stream time)
4446 * we stopped, this is either stop (when set) or the duration. */
4447 if ((stop = demux->common.segment.stop) == -1)
4448 stop = demux->last_stop_end;
4450 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4451 gst_element_post_message (GST_ELEMENT (demux),
4452 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4457 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_UNEXPECTED) {
4458 /* for fatal errors we post an error message */
4459 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4460 ("stream stopped, reason %s", reason));
4464 /* send EOS, and prevent hanging if no streams yet */
4465 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4466 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4467 (ret == GST_FLOW_UNEXPECTED)) {
4468 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4469 (NULL), ("got eos but no streams (yet)"));
4477 * Create and push a flushing seek event upstream
4480 perform_seek_to_offset (GstMatroskaDemux * demux, guint64 offset)
4485 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4488 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
4489 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4490 GST_SEEK_TYPE_NONE, -1);
4492 res = gst_pad_push_event (demux->common.sinkpad, event);
4494 /* newsegment event will update offset */
4498 static GstFlowReturn
4499 gst_matroska_demux_chain (GstPad * pad, GstBuffer * buffer)
4501 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4503 GstFlowReturn ret = GST_FLOW_OK;
4508 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4509 GST_DEBUG_OBJECT (demux, "got DISCONT");
4510 gst_adapter_clear (demux->common.adapter);
4511 GST_OBJECT_LOCK (demux);
4512 gst_matroska_read_common_reset_streams (&demux->common,
4513 GST_CLOCK_TIME_NONE, FALSE);
4514 GST_OBJECT_UNLOCK (demux);
4517 gst_adapter_push (demux->common.adapter, buffer);
4521 available = gst_adapter_available (demux->common.adapter);
4523 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4524 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4525 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED))
4528 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4529 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4530 demux->common.offset, id, length, needed, available);
4532 if (needed > available)
4535 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4536 if (ret == GST_FLOW_UNEXPECTED) {
4537 /* need more data */
4539 } else if (ret != GST_FLOW_OK) {
4546 gst_matroska_demux_handle_sink_event (GstPad * pad, GstEvent * event)
4548 gboolean res = TRUE;
4549 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4551 GST_DEBUG_OBJECT (demux,
4552 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4554 switch (GST_EVENT_TYPE (event)) {
4555 case GST_EVENT_NEWSEGMENT:
4558 gdouble rate, arate;
4559 gint64 start, stop, time = 0;
4563 /* some debug output */
4564 gst_segment_init (&segment, GST_FORMAT_UNDEFINED);
4565 gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
4566 &start, &stop, &time);
4567 gst_segment_set_newsegment_full (&segment, update, rate, arate, format,
4569 GST_DEBUG_OBJECT (demux,
4570 "received format %d newsegment %" GST_SEGMENT_FORMAT, format,
4573 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4574 GST_DEBUG_OBJECT (demux, "still starting");
4578 /* we only expect a BYTE segment, e.g. following a seek */
4579 if (format != GST_FORMAT_BYTES) {
4580 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4584 GST_DEBUG_OBJECT (demux, "clearing segment state");
4585 GST_OBJECT_LOCK (demux);
4586 /* clear current segment leftover */
4587 gst_adapter_clear (demux->common.adapter);
4588 /* and some streaming setup */
4589 demux->common.offset = start;
4590 /* do not know where we are;
4591 * need to come across a cluster and generate newsegment */
4592 demux->common.segment.last_stop = GST_CLOCK_TIME_NONE;
4593 demux->cluster_time = GST_CLOCK_TIME_NONE;
4594 demux->cluster_offset = 0;
4595 demux->need_newsegment = TRUE;
4596 /* but keep some of the upstream segment */
4597 demux->common.segment.rate = rate;
4598 GST_OBJECT_UNLOCK (demux);
4600 /* chain will send initial newsegment after pads have been added,
4601 * or otherwise come up with one */
4602 GST_DEBUG_OBJECT (demux, "eating event");
4603 gst_event_unref (event);
4609 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4610 gst_event_unref (event);
4611 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4612 (NULL), ("got eos and didn't receive a complete header object"));
4613 } else if (demux->common.num_streams == 0) {
4614 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4615 (NULL), ("got eos but no streams (yet)"));
4617 gst_matroska_demux_send_event (demux, event);
4621 case GST_EVENT_FLUSH_STOP:
4623 gst_adapter_clear (demux->common.adapter);
4624 GST_OBJECT_LOCK (demux);
4625 gst_matroska_read_common_reset_streams (&demux->common,
4626 GST_CLOCK_TIME_NONE, TRUE);
4627 demux->common.segment.last_stop = GST_CLOCK_TIME_NONE;
4628 demux->cluster_time = GST_CLOCK_TIME_NONE;
4629 demux->cluster_offset = 0;
4630 GST_OBJECT_UNLOCK (demux);
4634 res = gst_pad_event_default (pad, event);
4642 gst_matroska_demux_sink_activate (GstPad * sinkpad)
4644 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
4646 if (gst_pad_check_pull_range (sinkpad)) {
4647 GST_DEBUG ("going to pull mode");
4648 demux->streaming = FALSE;
4649 return gst_pad_activate_pull (sinkpad, TRUE);
4651 GST_DEBUG ("going to push (streaming) mode");
4652 demux->streaming = TRUE;
4653 return gst_pad_activate_push (sinkpad, TRUE);
4660 gst_matroska_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
4662 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
4665 /* if we have a scheduler we can start the task */
4666 demux->segment_running = TRUE;
4667 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4670 demux->segment_running = FALSE;
4671 gst_pad_stop_task (sinkpad);
4678 gst_duration_to_fraction (guint64 duration, gint * dest_n, gint * dest_d)
4680 static const int common_den[] = { 1, 2, 3, 4, 1001 };
4685 for (i = 0; i < G_N_ELEMENTS (common_den); i++) {
4687 n = floor (0.5 + (d * 1e9) / duration);
4688 a = gst_util_uint64_scale_int (1000000000, d, n);
4689 if (duration >= a - 1 && duration <= a + 1) {
4694 gst_util_double_to_fraction (1e9 / duration, &n, &d);
4703 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4704 videocontext, const gchar * codec_id, guint8 * data, guint size,
4705 gchar ** codec_name, guint32 * riff_fourcc)
4707 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4708 GstCaps *caps = NULL;
4710 g_assert (videocontext != NULL);
4711 g_assert (codec_name != NULL);
4713 context->send_xiph_headers = FALSE;
4714 context->send_flac_headers = FALSE;
4715 context->send_speex_headers = FALSE;
4720 /* TODO: check if we have all codec types from matroska-ids.h
4721 * check if we have to do more special things with codec_private
4724 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4725 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4728 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4729 gst_riff_strf_vids *vids = NULL;
4732 GstBuffer *buf = NULL;
4734 vids = (gst_riff_strf_vids *) data;
4736 /* assure size is big enough */
4738 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4741 if (size < sizeof (gst_riff_strf_vids)) {
4742 vids = g_new (gst_riff_strf_vids, 1);
4743 memcpy (vids, data, size);
4746 /* little-endian -> byte-order */
4747 vids->size = GUINT32_FROM_LE (vids->size);
4748 vids->width = GUINT32_FROM_LE (vids->width);
4749 vids->height = GUINT32_FROM_LE (vids->height);
4750 vids->planes = GUINT16_FROM_LE (vids->planes);
4751 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4752 vids->compression = GUINT32_FROM_LE (vids->compression);
4753 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4754 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4755 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4756 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4757 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4759 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4760 buf = gst_buffer_new_and_alloc (size - sizeof (gst_riff_strf_vids));
4761 memcpy (GST_BUFFER_DATA (buf),
4762 (guint8 *) vids + sizeof (gst_riff_strf_vids),
4763 GST_BUFFER_SIZE (buf));
4767 *riff_fourcc = vids->compression;
4769 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4770 buf, NULL, codec_name);
4773 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4774 GST_FOURCC_ARGS (vids->compression));
4778 gst_buffer_unref (buf);
4780 if (vids != (gst_riff_strf_vids *) data)
4783 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4786 switch (videocontext->fourcc) {
4787 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4788 *codec_name = g_strdup ("Raw planar YUV 4:2:0");
4789 fourcc = videocontext->fourcc;
4791 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4792 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
4793 fourcc = videocontext->fourcc;
4795 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4796 *codec_name = g_strdup ("Raw packed YUV 4:2:0");
4797 fourcc = videocontext->fourcc;
4799 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4800 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
4801 fourcc = videocontext->fourcc;
4803 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4804 *codec_name = g_strdup ("Raw packed YUV 4:4:4 with alpha channel");
4805 fourcc = videocontext->fourcc;
4809 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
4810 GST_FOURCC_ARGS (videocontext->fourcc));
4814 caps = gst_caps_new_simple ("video/x-raw-yuv",
4815 "format", GST_TYPE_FOURCC, fourcc, NULL);
4816 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
4817 caps = gst_caps_new_simple ("video/x-divx",
4818 "divxversion", G_TYPE_INT, 4, NULL);
4819 *codec_name = g_strdup ("MPEG-4 simple profile");
4820 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
4821 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
4823 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4824 "divxversion", G_TYPE_INT, 5, NULL),
4825 gst_structure_new ("video/x-xvid", NULL),
4826 gst_structure_new ("video/mpeg",
4827 "mpegversion", G_TYPE_INT, 4,
4828 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
4830 caps = gst_caps_new_simple ("video/mpeg",
4831 "mpegversion", G_TYPE_INT, 4,
4832 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
4834 GstBuffer *priv = gst_buffer_new_and_alloc (size);
4836 memcpy (GST_BUFFER_DATA (priv), data, size);
4837 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4838 gst_buffer_unref (priv);
4840 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
4841 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
4843 *codec_name = g_strdup ("MPEG-4 advanced profile");
4844 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
4846 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4847 "divxversion", G_TYPE_INT, 3, NULL),
4848 gst_structure_new ("video/x-msmpeg",
4849 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
4851 caps = gst_caps_new_simple ("video/x-msmpeg",
4852 "msmpegversion", G_TYPE_INT, 43, NULL);
4853 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
4854 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
4855 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
4858 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
4863 caps = gst_caps_new_simple ("video/mpeg",
4864 "systemstream", G_TYPE_BOOLEAN, FALSE,
4865 "mpegversion", G_TYPE_INT, mpegversion, NULL);
4866 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
4867 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
4868 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
4869 caps = gst_caps_new_simple ("image/jpeg", NULL);
4870 *codec_name = g_strdup ("Motion-JPEG");
4871 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
4872 caps = gst_caps_new_simple ("video/x-h264", NULL);
4874 GstBuffer *priv = gst_buffer_new_and_alloc (size);
4876 /* First byte is the version, second is the profile indication, and third
4877 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
4878 * level indication. */
4879 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
4882 memcpy (GST_BUFFER_DATA (priv), data, size);
4883 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4884 gst_buffer_unref (priv);
4886 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
4887 "alignment", G_TYPE_STRING, "au", NULL);
4889 GST_WARNING ("No codec data found, assuming output is byte-stream");
4890 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
4893 *codec_name = g_strdup ("H264");
4894 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
4895 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
4896 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
4897 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
4898 gint rmversion = -1;
4900 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
4902 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
4904 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
4906 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
4909 caps = gst_caps_new_simple ("video/x-pn-realvideo",
4910 "rmversion", G_TYPE_INT, rmversion, NULL);
4911 GST_DEBUG ("data:%p, size:0x%x", data, size);
4912 /* We need to extract the extradata ! */
4913 if (data && (size >= 0x22)) {
4918 subformat = GST_READ_UINT32_BE (data + 0x1a);
4919 rformat = GST_READ_UINT32_BE (data + 0x1e);
4921 priv = gst_buffer_new_and_alloc (size - 0x1a);
4923 memcpy (GST_BUFFER_DATA (priv), data + 0x1a, size - 0x1a);
4924 gst_caps_set_simple (caps,
4925 "codec_data", GST_TYPE_BUFFER, priv,
4926 "format", G_TYPE_INT, rformat,
4927 "subformat", G_TYPE_INT, subformat, NULL);
4928 gst_buffer_unref (priv);
4931 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
4932 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
4933 caps = gst_caps_new_simple ("video/x-theora", NULL);
4934 context->send_xiph_headers = TRUE;
4935 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
4936 caps = gst_caps_new_simple ("video/x-dirac", NULL);
4937 *codec_name = g_strdup_printf ("Dirac");
4938 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
4939 caps = gst_caps_new_simple ("video/x-vp8", NULL);
4940 *codec_name = g_strdup_printf ("On2 VP8");
4942 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
4948 GstStructure *structure;
4950 for (i = 0; i < gst_caps_get_size (caps); i++) {
4951 structure = gst_caps_get_structure (caps, i);
4953 /* FIXME: use the real unit here! */
4954 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
4955 videocontext->pixel_width,
4956 videocontext->pixel_height,
4957 videocontext->display_width, videocontext->display_height);
4959 /* pixel width and height are the w and h of the video in pixels */
4960 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
4961 gint w = videocontext->pixel_width;
4962 gint h = videocontext->pixel_height;
4964 gst_structure_set (structure,
4965 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
4968 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
4971 if (videocontext->display_width <= 0)
4972 videocontext->display_width = videocontext->pixel_width;
4973 if (videocontext->display_height <= 0)
4974 videocontext->display_height = videocontext->pixel_height;
4976 /* calculate the pixel aspect ratio using the display and pixel w/h */
4977 n = videocontext->display_width * videocontext->pixel_height;
4978 d = videocontext->display_height * videocontext->pixel_width;
4979 GST_DEBUG ("setting PAR to %d/%d", n, d);
4980 gst_structure_set (structure, "pixel-aspect-ratio",
4982 videocontext->display_width * videocontext->pixel_height,
4983 videocontext->display_height * videocontext->pixel_width, NULL);
4986 if (videocontext->default_fps > 0.0) {
4987 GValue fps_double = { 0, };
4988 GValue fps_fraction = { 0, };
4990 g_value_init (&fps_double, G_TYPE_DOUBLE);
4991 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
4992 g_value_set_double (&fps_double, videocontext->default_fps);
4993 g_value_transform (&fps_double, &fps_fraction);
4995 GST_DEBUG ("using default fps %f", videocontext->default_fps);
4997 gst_structure_set_value (structure, "framerate", &fps_fraction);
4998 g_value_unset (&fps_double);
4999 g_value_unset (&fps_fraction);
5000 } else if (context->default_duration > 0) {
5003 gst_duration_to_fraction (context->default_duration, &fps_n, &fps_d);
5005 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5006 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5008 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5009 fps_n, fps_d, NULL);
5011 /* sort of a hack to get most codecs to support,
5012 * even if the default_duration is missing */
5013 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5017 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5018 gst_structure_set (structure, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
5021 gst_caps_do_simplify (caps);
5028 * Some AAC specific code... *sigh*
5029 * FIXME: maybe we should use '15' and code the sample rate explicitly
5030 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5034 aac_rate_idx (gint rate)
5038 else if (75132 <= rate)
5040 else if (55426 <= rate)
5042 else if (46009 <= rate)
5044 else if (37566 <= rate)
5046 else if (27713 <= rate)
5048 else if (23004 <= rate)
5050 else if (18783 <= rate)
5052 else if (13856 <= rate)
5054 else if (11502 <= rate)
5056 else if (9391 <= rate)
5063 aac_profile_idx (const gchar * codec_id)
5067 if (strlen (codec_id) <= 12)
5069 else if (!strncmp (&codec_id[12], "MAIN", 4))
5071 else if (!strncmp (&codec_id[12], "LC", 2))
5073 else if (!strncmp (&codec_id[12], "SSR", 3))
5081 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5084 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5085 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5086 gchar ** codec_name, guint16 * riff_audio_fmt)
5088 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5089 GstCaps *caps = NULL;
5091 g_assert (audiocontext != NULL);
5092 g_assert (codec_name != NULL);
5095 *riff_audio_fmt = 0;
5097 context->send_xiph_headers = FALSE;
5098 context->send_flac_headers = FALSE;
5099 context->send_speex_headers = FALSE;
5101 /* TODO: check if we have all codec types from matroska-ids.h
5102 * check if we have to do more special things with codec_private
5103 * check if we need bitdepth in different places too
5104 * implement channel position magic
5106 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5107 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5108 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5109 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5112 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5113 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5114 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5117 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5119 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5124 caps = gst_caps_new_simple ("audio/mpeg",
5125 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5126 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5127 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5128 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5131 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5132 endianness = G_BIG_ENDIAN;
5134 endianness = G_LITTLE_ENDIAN;
5136 caps = gst_caps_new_simple ("audio/x-raw-int",
5137 "width", G_TYPE_INT, audiocontext->bitdepth,
5138 "depth", G_TYPE_INT, audiocontext->bitdepth,
5139 "signed", G_TYPE_BOOLEAN, audiocontext->bitdepth != 8,
5140 "endianness", G_TYPE_INT, endianness, NULL);
5142 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5143 audiocontext->bitdepth);
5144 context->alignment = audiocontext->bitdepth / 8;
5145 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5146 caps = gst_caps_new_simple ("audio/x-raw-float",
5147 "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
5148 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5149 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5150 audiocontext->bitdepth);
5151 context->alignment = audiocontext->bitdepth / 8;
5152 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5153 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5154 caps = gst_caps_new_simple ("audio/x-ac3",
5155 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5156 *codec_name = g_strdup ("AC-3 audio");
5157 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5158 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5159 caps = gst_caps_new_simple ("audio/x-eac3",
5160 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5161 *codec_name = g_strdup ("E-AC-3 audio");
5162 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5163 caps = gst_caps_new_simple ("audio/x-dts", NULL);
5164 *codec_name = g_strdup ("DTS audio");
5165 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5166 caps = gst_caps_new_simple ("audio/x-vorbis", NULL);
5167 context->send_xiph_headers = TRUE;
5168 /* vorbis decoder does tags */
5169 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5170 caps = gst_caps_new_simple ("audio/x-flac", NULL);
5171 context->send_flac_headers = TRUE;
5172 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5173 caps = gst_caps_new_simple ("audio/x-speex", NULL);
5174 context->send_speex_headers = TRUE;
5175 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5176 gst_riff_strf_auds auds;
5179 GstBuffer *codec_data = gst_buffer_new ();
5181 /* little-endian -> byte-order */
5182 auds.format = GST_READ_UINT16_LE (data);
5183 auds.channels = GST_READ_UINT16_LE (data + 2);
5184 auds.rate = GST_READ_UINT32_LE (data + 4);
5185 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5186 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5187 auds.size = GST_READ_UINT16_LE (data + 16);
5189 /* 18 is the waveformatex size */
5190 gst_buffer_set_data (codec_data, data + 18, auds.size);
5193 *riff_audio_fmt = auds.format;
5195 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5196 codec_data, codec_name);
5197 gst_buffer_unref (codec_data);
5200 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5203 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5204 GstBuffer *priv = NULL;
5206 gint rate_idx, profile;
5207 guint8 *data = NULL;
5209 /* unspecified AAC profile with opaque private codec data */
5210 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5211 if (context->codec_priv_size >= 2) {
5212 guint obj_type, freq_index, explicit_freq_bytes = 0;
5214 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5216 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5217 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5218 if (freq_index == 15)
5219 explicit_freq_bytes = 3;
5220 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5221 priv = gst_buffer_new_and_alloc (context->codec_priv_size);
5222 memcpy (GST_BUFFER_DATA (priv), context->codec_priv,
5223 context->codec_priv_size);
5224 /* assume SBR if samplerate <= 24kHz */
5225 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5226 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5227 audiocontext->samplerate *= 2;
5230 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5231 /* this is pretty broken;
5232 * maybe we need to make up some default private,
5233 * or maybe ADTS data got dumped in.
5234 * Let's set up some private data now, and check actual data later */
5235 /* just try this and see what happens ... */
5236 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5237 context->postprocess_frame = gst_matroska_demux_check_aac;
5241 /* make up decoder-specific data if it is not supplied */
5243 priv = gst_buffer_new_and_alloc (5);
5244 data = GST_BUFFER_DATA (priv);
5245 rate_idx = aac_rate_idx (audiocontext->samplerate);
5246 profile = aac_profile_idx (codec_id);
5248 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5249 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5250 GST_BUFFER_SIZE (priv) = 2;
5252 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5253 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5255 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5256 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5259 if (g_strrstr (codec_id, "SBR")) {
5260 /* HE-AAC (aka SBR AAC) */
5261 audiocontext->samplerate *= 2;
5262 rate_idx = aac_rate_idx (audiocontext->samplerate);
5263 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5264 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5265 data[4] = (1 << 7) | (rate_idx << 3);
5266 GST_BUFFER_SIZE (priv) = 5;
5269 gst_buffer_unref (priv);
5271 GST_ERROR ("Unknown AAC profile and no codec private data");
5276 caps = gst_caps_new_simple ("audio/mpeg",
5277 "mpegversion", G_TYPE_INT, mpegversion,
5278 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5279 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5280 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5281 gst_buffer_unref (priv);
5283 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5284 caps = gst_caps_new_simple ("audio/x-tta",
5285 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5286 *codec_name = g_strdup ("TTA audio");
5287 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5288 caps = gst_caps_new_simple ("audio/x-wavpack",
5289 "width", G_TYPE_INT, audiocontext->bitdepth,
5290 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5291 *codec_name = g_strdup ("Wavpack audio");
5292 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5293 audiocontext->wvpk_block_index = 0;
5294 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5295 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5296 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5297 gint raversion = -1;
5299 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5301 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5306 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5307 "raversion", G_TYPE_INT, raversion, NULL);
5308 /* Extract extra information from caps, mapping varies based on codec */
5309 if (data && (size >= 0x50)) {
5316 guint extra_data_size;
5318 GST_ERROR ("real audio raversion:%d", raversion);
5319 if (raversion == 8) {
5321 flavor = GST_READ_UINT16_BE (data + 22);
5322 packet_size = GST_READ_UINT32_BE (data + 24);
5323 height = GST_READ_UINT16_BE (data + 40);
5324 leaf_size = GST_READ_UINT16_BE (data + 44);
5325 sample_width = GST_READ_UINT16_BE (data + 58);
5326 extra_data_size = GST_READ_UINT32_BE (data + 74);
5329 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5330 flavor, packet_size, height, leaf_size, sample_width,
5332 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5333 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5334 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5336 if ((size - 78) >= extra_data_size) {
5337 priv = gst_buffer_new_and_alloc (extra_data_size);
5338 memcpy (GST_BUFFER_DATA (priv), data + 78, extra_data_size);
5339 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5340 gst_buffer_unref (priv);
5345 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5346 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5347 caps = gst_caps_new_simple ("audio/x-sipro", NULL);
5348 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5349 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5350 caps = gst_caps_new_simple ("audio/x-ralf-mpeg4-generic", NULL);
5351 *codec_name = g_strdup ("Real Audio Lossless");
5352 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5353 caps = gst_caps_new_simple ("audio/x-vnd.sony.atrac3", NULL);
5354 *codec_name = g_strdup ("Sony ATRAC3");
5356 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5361 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5364 for (i = 0; i < gst_caps_get_size (caps); i++) {
5365 gst_structure_set (gst_caps_get_structure (caps, i),
5366 "channels", G_TYPE_INT, audiocontext->channels,
5367 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5371 gst_caps_do_simplify (caps);
5378 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5379 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5381 GstCaps *caps = NULL;
5382 GstMatroskaTrackContext *context =
5383 (GstMatroskaTrackContext *) subtitlecontext;
5385 /* for backwards compatibility */
5386 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5387 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5388 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5389 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5390 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5391 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5392 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5393 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5395 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5396 * Check if we have to do something with codec_private */
5397 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5398 /* well, plain text simply does not have a lot of markup ... */
5399 caps = gst_caps_new_simple ("text/x-pango-markup", NULL);
5400 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5401 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5402 caps = gst_caps_new_simple ("application/x-ssa", NULL);
5403 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5404 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5405 caps = gst_caps_new_simple ("application/x-ass", NULL);
5406 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5407 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5408 caps = gst_caps_new_simple ("application/x-usf", NULL);
5409 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5410 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5411 caps = gst_caps_new_simple ("video/x-dvd-subpicture", NULL);
5412 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5413 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5414 caps = gst_caps_new_simple ("subpicture/x-pgs", NULL);
5415 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5416 caps = gst_caps_new_simple ("subtitle/x-kate", NULL);
5417 context->send_xiph_headers = TRUE;
5419 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5420 caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
5423 if (data != NULL && size > 0) {
5426 buf = gst_buffer_new_and_alloc (size);
5427 memcpy (GST_BUFFER_DATA (buf), data, size);
5428 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5429 gst_buffer_unref (buf);
5436 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5438 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5440 GST_OBJECT_LOCK (demux);
5441 if (demux->common.element_index)
5442 gst_object_unref (demux->common.element_index);
5443 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5444 GST_OBJECT_UNLOCK (demux);
5445 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5446 demux->common.element_index);
5450 gst_matroska_demux_get_index (GstElement * element)
5452 GstIndex *result = NULL;
5453 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5455 GST_OBJECT_LOCK (demux);
5456 if (demux->common.element_index)
5457 result = gst_object_ref (demux->common.element_index);
5458 GST_OBJECT_UNLOCK (demux);
5460 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5465 static GstStateChangeReturn
5466 gst_matroska_demux_change_state (GstElement * element,
5467 GstStateChange transition)
5469 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5470 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5472 /* handle upwards state changes here */
5473 switch (transition) {
5478 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5480 /* handle downwards state changes */
5481 switch (transition) {
5482 case GST_STATE_CHANGE_PAUSED_TO_READY:
5483 gst_matroska_demux_reset (GST_ELEMENT (demux));
5493 gst_matroska_demux_set_property (GObject * object,
5494 guint prop_id, const GValue * value, GParamSpec * pspec)
5496 GstMatroskaDemux *demux;
5498 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5499 demux = GST_MATROSKA_DEMUX (object);
5502 case ARG_MAX_GAP_TIME:
5503 GST_OBJECT_LOCK (demux);
5504 demux->max_gap_time = g_value_get_uint64 (value);
5505 GST_OBJECT_UNLOCK (demux);
5508 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5514 gst_matroska_demux_get_property (GObject * object,
5515 guint prop_id, GValue * value, GParamSpec * pspec)
5517 GstMatroskaDemux *demux;
5519 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5520 demux = GST_MATROSKA_DEMUX (object);
5523 case ARG_MAX_GAP_TIME:
5524 GST_OBJECT_LOCK (demux);
5525 g_value_set_uint64 (value, demux->max_gap_time);
5526 GST_OBJECT_UNLOCK (demux);
5529 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5535 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5539 /* parser helper separate debug */
5540 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5541 0, "EBML stream helper class");
5543 /* create an elementfactory for the matroska_demux element */
5544 if (!gst_element_register (plugin, "matroskademux",
5545 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))