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/audio/audio.h>
63 #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_%u",
102 GST_STATIC_CAPS ("ANY")
105 static GstStaticPadTemplate video_src_templ =
106 GST_STATIC_PAD_TEMPLATE ("video_%u",
109 GST_STATIC_CAPS ("ANY")
112 static GstStaticPadTemplate subtitle_src_templ =
113 GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
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 (GstPad * sinkpad,
135 static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
136 GstObject * parent, GstPadMode mode, gboolean active);
138 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
139 GstPad * pad, GstEvent * event);
140 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
141 GstObject * parent, GstEvent * event);
142 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
143 GstObject * parent, GstQuery * query);
145 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
146 GstObject * parent, GstEvent * event);
147 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
148 GstObject * object, GstBuffer * buffer);
150 static GstStateChangeReturn
151 gst_matroska_demux_change_state (GstElement * element,
152 GstStateChange transition);
155 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
156 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
160 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
161 * videocontext, const gchar * codec_id, guint8 * data, guint size,
162 gchar ** codec_name, guint32 * riff_fourcc);
163 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
164 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
165 gchar ** codec_name, guint16 * riff_audio_fmt);
167 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
168 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
171 static void gst_matroska_demux_reset (GstElement * element);
172 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
175 /* gobject functions */
176 static void gst_matroska_demux_set_property (GObject * object,
177 guint prop_id, const GValue * value, GParamSpec * pspec);
178 static void gst_matroska_demux_get_property (GObject * object,
179 guint prop_id, GValue * value, GParamSpec * pspec);
181 GType gst_matroska_demux_get_type (void);
182 #define parent_class gst_matroska_demux_parent_class
183 G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
186 gst_matroska_demux_finalize (GObject * object)
188 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
190 if (demux->common.src) {
191 g_ptr_array_free (demux->common.src, TRUE);
192 demux->common.src = NULL;
195 if (demux->common.global_tags) {
196 gst_tag_list_free (demux->common.global_tags);
197 demux->common.global_tags = NULL;
200 g_object_unref (demux->common.adapter);
202 G_OBJECT_CLASS (parent_class)->finalize (object);
206 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
208 GObjectClass *gobject_class = (GObjectClass *) klass;
209 GstElementClass *gstelement_class = (GstElementClass *) klass;
211 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
214 gobject_class->finalize = gst_matroska_demux_finalize;
216 gobject_class->get_property = gst_matroska_demux_get_property;
217 gobject_class->set_property = gst_matroska_demux_set_property;
219 g_object_class_install_property (gobject_class, ARG_MAX_GAP_TIME,
220 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
221 "The demuxer sends out segment events for skipping "
222 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
223 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
225 gstelement_class->change_state =
226 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
227 gstelement_class->send_event =
228 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
229 gstelement_class->query =
230 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
232 gstelement_class->set_index =
233 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
234 gstelement_class->get_index =
235 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
238 gst_element_class_add_pad_template (gstelement_class,
239 gst_static_pad_template_get (&video_src_templ));
240 gst_element_class_add_pad_template (gstelement_class,
241 gst_static_pad_template_get (&audio_src_templ));
242 gst_element_class_add_pad_template (gstelement_class,
243 gst_static_pad_template_get (&subtitle_src_templ));
244 gst_element_class_add_pad_template (gstelement_class,
245 gst_static_pad_template_get (&sink_templ));
247 gst_element_class_set_details_simple (gstelement_class, "Matroska demuxer",
249 "Demuxes Matroska/WebM streams into video/audio/subtitles",
250 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
254 gst_matroska_demux_init (GstMatroskaDemux * demux)
256 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
258 gst_pad_set_activate_function (demux->common.sinkpad,
259 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
260 gst_pad_set_activatemode_function (demux->common.sinkpad,
261 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
262 gst_pad_set_chain_function (demux->common.sinkpad,
263 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
264 gst_pad_set_event_function (demux->common.sinkpad,
265 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
266 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
268 /* initial stream no. */
269 demux->common.src = NULL;
271 demux->common.writing_app = NULL;
272 demux->common.muxing_app = NULL;
273 demux->common.index = NULL;
274 demux->common.global_tags = NULL;
276 demux->common.adapter = gst_adapter_new ();
278 /* property defaults */
279 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
281 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
284 gst_matroska_demux_reset (GST_ELEMENT (demux));
288 gst_matroska_track_free (GstMatroskaTrackContext * track)
290 g_free (track->codec_id);
291 g_free (track->codec_name);
292 g_free (track->name);
293 g_free (track->language);
294 g_free (track->codec_priv);
295 g_free (track->codec_state);
297 if (track->encodings != NULL) {
300 for (i = 0; i < track->encodings->len; ++i) {
301 GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
302 GstMatroskaTrackEncoding,
305 g_free (enc->comp_settings);
307 g_array_free (track->encodings, TRUE);
310 if (track->pending_tags)
311 gst_tag_list_free (track->pending_tags);
313 if (track->index_table)
314 g_array_free (track->index_table, TRUE);
320 * Returns the aggregated GstFlowReturn.
323 gst_matroska_demux_combine_flows (GstMatroskaDemux * demux,
324 GstMatroskaTrackContext * track, GstFlowReturn ret)
328 /* store the value */
329 track->last_flow = ret;
331 /* any other error that is not-linked can be returned right away */
332 if (ret != GST_FLOW_NOT_LINKED)
335 /* only return NOT_LINKED if all other pads returned NOT_LINKED */
336 g_assert (demux->common.src->len == demux->common.num_streams);
337 for (i = 0; i < demux->common.src->len; i++) {
338 GstMatroskaTrackContext *ostream = g_ptr_array_index (demux->common.src,
344 ret = ostream->last_flow;
345 /* some other return value (must be SUCCESS but we can return
346 * other values as well) */
347 if (ret != GST_FLOW_NOT_LINKED)
350 /* if we get here, all other pads were unlinked and we return
353 GST_LOG_OBJECT (demux, "combined return %s", gst_flow_get_name (ret));
358 gst_matroska_demux_free_parsed_el (gpointer mem, gpointer user_data)
360 g_slice_free (guint64, mem);
364 gst_matroska_demux_reset (GstElement * element)
366 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
369 GST_DEBUG_OBJECT (demux, "Resetting state");
372 demux->common.state = GST_MATROSKA_READ_STATE_START;
374 /* clean up existing streams */
375 if (demux->common.src) {
376 g_assert (demux->common.src->len == demux->common.num_streams);
377 for (i = 0; i < demux->common.src->len; i++) {
378 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
381 if (context->pad != NULL)
382 gst_element_remove_pad (GST_ELEMENT (demux), context->pad);
384 gst_caps_replace (&context->caps, NULL);
385 gst_matroska_track_free (context);
387 g_ptr_array_free (demux->common.src, TRUE);
389 demux->common.src = g_ptr_array_new ();
391 demux->common.num_streams = 0;
392 demux->num_a_streams = 0;
393 demux->num_t_streams = 0;
394 demux->num_v_streams = 0;
396 /* reset media info */
397 g_free (demux->common.writing_app);
398 demux->common.writing_app = NULL;
399 g_free (demux->common.muxing_app);
400 demux->common.muxing_app = NULL;
403 if (demux->common.index) {
404 g_array_free (demux->common.index, TRUE);
405 demux->common.index = NULL;
408 if (demux->clusters) {
409 g_array_free (demux->clusters, TRUE);
410 demux->clusters = NULL;
415 demux->common.time_scale = 1000000;
416 demux->common.created = G_MININT64;
418 demux->common.index_parsed = FALSE;
419 demux->tracks_parsed = FALSE;
420 demux->common.segmentinfo_parsed = FALSE;
421 demux->common.attachments_parsed = FALSE;
423 g_list_foreach (demux->common.tags_parsed,
424 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
425 g_list_free (demux->common.tags_parsed);
426 demux->common.tags_parsed = NULL;
428 g_list_foreach (demux->seek_parsed,
429 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
430 g_list_free (demux->seek_parsed);
431 demux->seek_parsed = NULL;
433 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
434 demux->last_stop_end = GST_CLOCK_TIME_NONE;
435 demux->seek_block = 0;
436 demux->stream_start_time = GST_CLOCK_TIME_NONE;
438 demux->common.offset = 0;
439 demux->cluster_time = GST_CLOCK_TIME_NONE;
440 demux->cluster_offset = 0;
441 demux->next_cluster_offset = 0;
442 demux->index_offset = 0;
443 demux->seekable = FALSE;
444 demux->need_segment = FALSE;
445 demux->building_index = FALSE;
446 if (demux->seek_event) {
447 gst_event_unref (demux->seek_event);
448 demux->seek_event = NULL;
451 demux->seek_index = NULL;
452 demux->seek_entry = 0;
454 if (demux->close_segment) {
455 gst_event_unref (demux->close_segment);
456 demux->close_segment = NULL;
459 if (demux->new_segment) {
460 gst_event_unref (demux->new_segment);
461 demux->new_segment = NULL;
464 if (demux->common.element_index) {
465 gst_object_unref (demux->common.element_index);
466 demux->common.element_index = NULL;
468 demux->common.element_index_writer_id = -1;
471 if (demux->common.global_tags) {
472 gst_tag_list_free (demux->common.global_tags);
474 demux->common.global_tags = gst_tag_list_new_empty ();
476 if (demux->common.cached_buffer) {
477 if (demux->common.cached_data) {
478 gst_buffer_unmap (demux->common.cached_buffer,
479 demux->common.cached_data, -1);
480 demux->common.cached_data = NULL;
482 gst_buffer_unref (demux->common.cached_buffer);
483 demux->common.cached_buffer = NULL;
488 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
490 gpointer data, buf_data;
491 gsize size, buf_size;
493 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
495 GST_DEBUG ("decoding buffer %p", buf);
497 buf_data = gst_buffer_map (buf, &buf_size, NULL, GST_MAP_READ);
499 g_return_val_if_fail (buf_size > 0, buf);
504 if (gst_matroska_decode_data (context->encodings, &data, &size,
505 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
506 gst_buffer_unmap (buf, buf_data, buf_size);
507 gst_buffer_unref (buf);
508 return gst_buffer_new_wrapped (data, size);
510 GST_DEBUG ("decode data failed");
511 gst_buffer_unmap (buf, buf_data, buf_size);
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_EOS)) {
1190 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
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_%u", demux->num_v_streams++);
1210 templ = gst_element_class_get_pad_template (klass, "video_%u");
1211 caps = gst_matroska_demux_video_caps (videocontext,
1212 context->codec_id, context->codec_priv,
1213 context->codec_priv_size, &codec, &riff_fourcc);
1216 list = gst_tag_list_new (GST_TAG_VIDEO_CODEC, codec, NULL);
1222 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1223 GstMatroskaTrackAudioContext *audiocontext =
1224 (GstMatroskaTrackAudioContext *) context;
1226 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1227 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1228 caps = gst_matroska_demux_audio_caps (audiocontext,
1229 context->codec_id, context->codec_priv, context->codec_priv_size,
1230 &codec, &riff_audio_fmt);
1233 list = gst_tag_list_new (GST_TAG_AUDIO_CODEC, codec, NULL);
1239 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1240 GstMatroskaTrackSubtitleContext *subtitlecontext =
1241 (GstMatroskaTrackSubtitleContext *) context;
1243 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1244 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1245 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1246 context->codec_id, context->codec_priv, context->codec_priv_size);
1250 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1251 case GST_MATROSKA_TRACK_TYPE_LOGO:
1252 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1253 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1255 /* we should already have quit by now */
1256 g_assert_not_reached ();
1259 if ((context->language == NULL || *context->language == '\0') &&
1260 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1261 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1262 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1263 context->language = g_strdup ("eng");
1266 if (context->language) {
1270 list = gst_tag_list_new_empty ();
1272 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1273 lang = gst_tag_get_language_code (context->language);
1274 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1275 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1279 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1280 "codec_id='%s'", context->codec_id);
1281 switch (context->type) {
1282 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1283 caps = gst_caps_new_empty_simple ("video/x-unknown");
1285 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1286 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1288 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1289 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1291 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1293 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1296 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1299 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1300 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1301 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1302 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1303 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1304 GST_FOURCC_ARGS (riff_fourcc));
1305 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, 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_function (context->pad,
1317 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1319 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1322 context->pending_tags = list;
1324 gst_pad_set_element_private (context->pad, context);
1326 gst_pad_use_fixed_caps (context->pad);
1327 gst_pad_set_active (context->pad, TRUE);
1328 gst_pad_set_caps (context->pad, context->caps);
1329 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1338 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1341 gboolean res = FALSE;
1342 GstMatroskaTrackContext *context = NULL;
1345 context = gst_pad_get_element_private (pad);
1348 switch (GST_QUERY_TYPE (query)) {
1349 case GST_QUERY_POSITION:
1353 gst_query_parse_position (query, &format, NULL);
1355 if (format == GST_FORMAT_TIME) {
1356 GST_OBJECT_LOCK (demux);
1358 gst_query_set_position (query, GST_FORMAT_TIME,
1359 context->pos - demux->stream_start_time);
1361 gst_query_set_position (query, GST_FORMAT_TIME,
1362 demux->common.segment.position - demux->stream_start_time);
1363 GST_OBJECT_UNLOCK (demux);
1364 } else if (format == GST_FORMAT_DEFAULT && context
1365 && context->default_duration) {
1366 GST_OBJECT_LOCK (demux);
1367 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1368 context->pos / context->default_duration);
1369 GST_OBJECT_UNLOCK (demux);
1371 GST_DEBUG_OBJECT (demux,
1372 "only position query in TIME and DEFAULT format is supported");
1378 case GST_QUERY_DURATION:
1382 gst_query_parse_duration (query, &format, NULL);
1384 if (format == GST_FORMAT_TIME) {
1385 GST_OBJECT_LOCK (demux);
1386 gst_query_set_duration (query, GST_FORMAT_TIME,
1387 demux->common.segment.duration);
1388 GST_OBJECT_UNLOCK (demux);
1389 } else if (format == GST_FORMAT_DEFAULT && context
1390 && context->default_duration) {
1391 GST_OBJECT_LOCK (demux);
1392 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1393 demux->common.segment.duration / context->default_duration);
1394 GST_OBJECT_UNLOCK (demux);
1396 GST_DEBUG_OBJECT (demux,
1397 "only duration query in TIME and DEFAULT format is supported");
1404 case GST_QUERY_SEEKING:
1408 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1409 GST_OBJECT_LOCK (demux);
1410 if (fmt == GST_FORMAT_TIME) {
1413 if (demux->streaming) {
1414 /* assuming we'll be able to get an index ... */
1415 seekable = demux->seekable;
1420 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1421 0, demux->common.segment.duration);
1424 GST_OBJECT_UNLOCK (demux);
1428 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1436 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1438 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1442 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1445 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1447 return gst_matroska_demux_query (demux, pad, query);
1450 /* returns FALSE if there are no pads to deliver event to,
1451 * otherwise TRUE (whatever the outcome of event sending),
1452 * takes ownership of the passed event! */
1454 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1456 gboolean is_segment;
1457 gboolean ret = FALSE;
1460 g_return_val_if_fail (event != NULL, FALSE);
1462 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1463 GST_EVENT_TYPE_NAME (event));
1465 is_segment = (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
1467 g_assert (demux->common.src->len == demux->common.num_streams);
1468 for (i = 0; i < demux->common.src->len; i++) {
1469 GstMatroskaTrackContext *stream;
1471 stream = g_ptr_array_index (demux->common.src, i);
1472 gst_event_ref (event);
1473 gst_pad_push_event (stream->pad, event);
1476 /* FIXME: send global tags before stream tags */
1477 if (G_UNLIKELY (is_segment && stream->pending_tags != NULL)) {
1478 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
1479 GST_PTR_FORMAT, stream->pending_tags,
1480 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
1481 gst_pad_push_event (stream->pad,
1482 gst_event_new_tag (stream->pending_tags));
1483 stream->pending_tags = NULL;
1487 if (G_UNLIKELY (is_segment && demux->common.global_tags != NULL)) {
1488 GstEvent *tag_event;
1489 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1490 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1491 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1492 demux->common.global_tags, demux->common.global_tags);
1494 tag_event = gst_event_new_tag (demux->common.global_tags);
1496 for (i = 0; i < demux->common.src->len; i++) {
1497 GstMatroskaTrackContext *stream;
1499 stream = g_ptr_array_index (demux->common.src, i);
1500 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1503 gst_event_unref (tag_event);
1504 demux->common.global_tags = NULL;
1507 gst_event_unref (event);
1512 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1514 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1517 g_return_val_if_fail (event != NULL, FALSE);
1519 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1520 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1522 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1523 GST_EVENT_TYPE_NAME (event));
1526 gst_event_unref (event);
1531 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1532 GstMatroskaIndex * entry, gboolean reset)
1536 GST_OBJECT_LOCK (demux);
1538 /* seek (relative to matroska segment) */
1539 /* position might be invalid; will error when streaming resumes ... */
1540 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1542 GST_DEBUG_OBJECT (demux, "Seeked to offset %" G_GUINT64_FORMAT ", block %d, "
1543 "time %" GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1544 entry->block, GST_TIME_ARGS (entry->time));
1546 /* update the time */
1547 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1548 demux->common.segment.position = entry->time;
1549 demux->seek_block = entry->block;
1550 demux->seek_first = TRUE;
1551 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1553 for (i = 0; i < demux->common.src->len; i++) {
1554 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1557 stream->to_offset = G_MAXINT64;
1559 if (stream->from_offset != -1)
1560 stream->to_offset = stream->from_offset;
1562 stream->from_offset = -1;
1565 GST_OBJECT_UNLOCK (demux);
1571 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1581 /* searches for a cluster start from @pos,
1582 * return GST_FLOW_OK and cluster position in @pos if found */
1583 static GstFlowReturn
1584 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1586 gint64 newpos = *pos;
1588 GstFlowReturn ret = GST_FLOW_OK;
1589 const guint chunk = 64 * 1024;
1590 GstBuffer *buf = NULL;
1591 gpointer data = NULL;
1597 orig_offset = demux->common.offset;
1599 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1602 if (demux->clusters) {
1605 cpos = gst_util_array_binary_search (demux->clusters->data,
1606 demux->clusters->len, sizeof (gint64),
1607 (GCompareDataFunc) gst_matroska_cluster_compare,
1608 GST_SEARCH_MODE_AFTER, pos, NULL);
1611 GST_DEBUG_OBJECT (demux,
1612 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1613 demux->common.offset = *cpos;
1614 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1615 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1616 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1623 /* read in at newpos and scan for ebml cluster id */
1625 GstByteReader reader;
1629 gst_buffer_unmap (buf, data, size);
1630 gst_buffer_unref (buf);
1633 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1634 if (ret != GST_FLOW_OK)
1636 GST_DEBUG_OBJECT (demux, "read buffer size %d at offset %" G_GINT64_FORMAT,
1637 gst_buffer_get_size (buf), newpos);
1638 data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
1639 gst_byte_reader_init (&reader, data, size);
1641 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1642 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1643 if (cluster_pos >= 0) {
1644 newpos += cluster_pos;
1645 /* prepare resuming at next byte */
1646 gst_byte_reader_skip (&reader, cluster_pos + 1);
1647 GST_DEBUG_OBJECT (demux,
1648 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1649 /* extra checks whether we really sync'ed to a cluster:
1650 * - either it is the first and only cluster
1651 * - either there is a cluster after this one
1652 * - either cluster length is undefined
1654 /* ok if first cluster (there may not a subsequent one) */
1655 if (newpos == demux->first_cluster_offset) {
1656 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1659 demux->common.offset = newpos;
1660 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1661 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1662 if (ret != GST_FLOW_OK) {
1663 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1666 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1667 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1669 /* ok if undefined length or first cluster */
1670 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1671 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1675 demux->common.offset += length + needed;
1676 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1677 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1678 if (ret != GST_FLOW_OK)
1680 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1681 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1682 if (id == GST_MATROSKA_ID_CLUSTER)
1684 /* not ok, resume */
1687 /* partial cluster id may have been in tail of buffer */
1688 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1693 gst_buffer_unmap (buf, data, size);
1694 gst_buffer_unref (buf);
1699 demux->common.offset = orig_offset;
1704 /* bisect and scan through file for cluster starting before @time,
1705 * returns fake index entry with corresponding info on cluster */
1706 static GstMatroskaIndex *
1707 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1709 GstMatroskaIndex *entry = NULL;
1710 GstMatroskaReadState current_state;
1711 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1712 gint64 opos, newpos, startpos = 0, current_offset;
1713 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1714 const guint chunk = 64 * 1024;
1715 GstBuffer *buf = NULL;
1721 /* (under)estimate new position, resync using cluster ebml id,
1722 * and scan forward to appropriate cluster
1723 * (and re-estimate if need to go backward) */
1725 prev_cluster_time = GST_CLOCK_TIME_NONE;
1727 /* store some current state */
1728 current_state = demux->common.state;
1729 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1731 current_cluster_offset = demux->cluster_offset;
1732 current_cluster_time = demux->cluster_time;
1733 current_offset = demux->common.offset;
1735 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1737 /* estimate using start and current position */
1738 GST_OBJECT_LOCK (demux);
1739 opos = demux->common.offset - demux->common.ebml_segment_start;
1740 otime = demux->common.segment.position;
1741 GST_OBJECT_UNLOCK (demux);
1743 /* avoid division by zero in first estimation below */
1748 GST_LOG_OBJECT (demux,
1749 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1750 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1751 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1752 GST_TIME_ARGS (otime - demux->stream_start_time),
1753 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1755 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1756 time - demux->stream_start_time,
1757 otime - demux->stream_start_time) - chunk;
1760 /* favour undershoot */
1761 newpos = newpos * 90 / 100;
1762 newpos += demux->common.ebml_segment_start;
1764 GST_DEBUG_OBJECT (demux,
1765 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1766 GST_TIME_ARGS (time), newpos);
1768 /* and at least start scanning before previous scan start to avoid looping */
1769 startpos = startpos * 90 / 100;
1770 if (startpos && startpos < newpos)
1773 /* read in at newpos and scan for ebml cluster id */
1777 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1778 if (ret == GST_FLOW_EOS) {
1779 /* heuristic HACK */
1780 newpos = startpos * 80 / 100;
1781 GST_DEBUG_OBJECT (demux, "EOS; "
1782 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1783 GST_TIME_ARGS (time), newpos);
1786 } else if (ret != GST_FLOW_OK) {
1793 /* then start scanning and parsing for cluster time,
1794 * re-estimate if overshoot, otherwise next cluster and so on */
1795 demux->common.offset = newpos;
1796 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1798 guint64 cluster_size = 0;
1800 /* peek and parse some elements */
1801 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1802 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1803 if (ret != GST_FLOW_OK)
1805 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1806 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1808 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1809 if (ret != GST_FLOW_OK)
1812 if (id == GST_MATROSKA_ID_CLUSTER) {
1813 cluster_time = GST_CLOCK_TIME_NONE;
1814 if (length == G_MAXUINT64)
1817 cluster_size = length + needed;
1819 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1820 cluster_time == GST_CLOCK_TIME_NONE) {
1821 cluster_time = demux->cluster_time * demux->common.time_scale;
1822 cluster_offset = demux->cluster_offset;
1823 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1824 " with time %" GST_TIME_FORMAT, cluster_offset,
1825 GST_TIME_ARGS (cluster_time));
1826 if (cluster_time > time) {
1827 GST_DEBUG_OBJECT (demux, "overshot target");
1828 /* cluster overshoots */
1829 if (cluster_offset == demux->first_cluster_offset) {
1830 /* but no prev one */
1831 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1832 prev_cluster_time = cluster_time;
1833 prev_cluster_offset = cluster_offset;
1836 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1837 /* prev cluster did not overshoot, so prev cluster is target */
1840 /* re-estimate using this new position info */
1841 opos = cluster_offset;
1842 otime = cluster_time;
1846 /* cluster undershoots, goto next one */
1847 prev_cluster_time = cluster_time;
1848 prev_cluster_offset = cluster_offset;
1849 /* skip cluster if length is defined,
1850 * otherwise will be skippingly parsed into */
1852 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1853 demux->common.offset = cluster_offset + cluster_size;
1854 demux->cluster_time = GST_CLOCK_TIME_NONE;
1856 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1863 if (ret == GST_FLOW_EOS) {
1864 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1870 entry = g_new0 (GstMatroskaIndex, 1);
1871 entry->time = prev_cluster_time;
1872 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1873 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1874 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1878 gst_buffer_unref (buf);
1880 /* restore some state */
1881 demux->cluster_offset = current_cluster_offset;
1882 demux->cluster_time = current_cluster_time;
1883 demux->common.offset = current_offset;
1884 demux->common.state = current_state;
1890 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1891 GstPad * pad, GstEvent * event)
1893 GstMatroskaIndex *entry = NULL;
1894 GstMatroskaIndex scan_entry;
1896 GstSeekType cur_type, stop_type;
1898 gboolean flush, keyunit;
1901 GstMatroskaTrackContext *track = NULL;
1902 GstSegment seeksegment = { 0, };
1903 gboolean update = TRUE;
1906 track = gst_pad_get_element_private (pad);
1908 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1911 /* we can only seek on time */
1912 if (format != GST_FORMAT_TIME) {
1913 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1917 /* copy segment, we need this because we still need the old
1918 * segment when we close the current segment. */
1919 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1922 GST_DEBUG_OBJECT (demux, "configuring seek");
1923 gst_segment_do_seek (&seeksegment, rate, format, flags,
1924 cur_type, cur, stop_type, stop, &update);
1925 /* compensate for clip start time */
1926 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1927 seeksegment.position += demux->stream_start_time;
1928 seeksegment.start += demux->stream_start_time;
1929 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1930 seeksegment.stop += demux->stream_start_time;
1931 /* note that time should stay at indicated position */
1935 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
1936 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
1938 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1941 /* only have to update some segment,
1942 * but also still have to honour flush and so on */
1943 GST_DEBUG_OBJECT (demux, "... no update");
1944 /* bad goto, bad ... */
1948 /* check sanity before we start flushing and all that */
1949 GST_OBJECT_LOCK (demux);
1950 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
1951 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
1952 seeksegment.position, &demux->seek_index, &demux->seek_entry)) ==
1954 /* pull mode without index can scan later on */
1955 if (demux->common.index || demux->streaming) {
1956 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
1957 GST_OBJECT_UNLOCK (demux);
1961 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
1962 GST_OBJECT_UNLOCK (demux);
1964 if (demux->streaming) {
1965 /* need to seek to cluster start to pick up cluster time */
1966 /* upstream takes care of flushing and all that
1967 * ... and segment event handling takes care of the rest */
1968 return perform_seek_to_offset (demux,
1969 entry->pos + demux->common.ebml_segment_start);
1974 GST_DEBUG_OBJECT (demux, "Starting flush");
1975 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_start ());
1976 gst_matroska_demux_send_event (demux, gst_event_new_flush_start ());
1978 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
1979 gst_pad_pause_task (demux->common.sinkpad);
1985 /* now grab the stream lock so that streaming cannot continue, for
1986 * non flushing seeks when the element is in PAUSED this could block
1988 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
1989 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
1991 /* pull mode without index can do some scanning */
1992 if (!demux->streaming && !demux->common.index) {
1993 /* need to stop flushing upstream as we need it next */
1995 gst_pad_push_event (demux->common.sinkpad,
1996 gst_event_new_flush_stop (TRUE));
1997 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
1998 /* keep local copy */
2000 scan_entry = *entry;
2002 entry = &scan_entry;
2004 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2006 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop (TRUE));
2012 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start to %"
2013 GST_TIME_FORMAT, GST_TIME_ARGS (entry->time));
2014 seeksegment.start = entry->time;
2015 seeksegment.position = entry->time;
2016 seeksegment.time = entry->time - demux->stream_start_time;
2021 GST_DEBUG_OBJECT (demux, "Stopping flush");
2022 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_stop (TRUE));
2023 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop (TRUE));
2024 } else if (demux->segment_running && update) {
2026 GST_DEBUG_OBJECT (demux, "Closing currently running segment");
2028 GST_OBJECT_LOCK (demux);
2029 if (demux->close_segment)
2030 gst_event_unref (demux->close_segment);
2032 segment = demux->common.segment;
2033 segment.stop = segment.position;
2034 demux->close_segment = gst_event_new_segment (&segment);
2035 GST_OBJECT_UNLOCK (demux);
2038 GST_OBJECT_LOCK (demux);
2039 /* now update the real segment info */
2040 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2041 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2042 GST_OBJECT_UNLOCK (demux);
2044 /* update some (segment) state */
2045 if (update && !gst_matroska_demux_move_to_entry (demux, entry, TRUE))
2048 /* notify start of new segment */
2049 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2052 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2053 GST_FORMAT_TIME, demux->common.segment.start);
2054 gst_element_post_message (GST_ELEMENT (demux), msg);
2057 GST_OBJECT_LOCK (demux);
2058 if (demux->new_segment)
2059 gst_event_unref (demux->new_segment);
2060 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2061 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2062 GST_OBJECT_UNLOCK (demux);
2064 /* restart our task since it might have been stopped when we did the
2066 demux->segment_running = TRUE;
2067 gst_pad_start_task (demux->common.sinkpad,
2068 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad);
2070 /* streaming can continue now */
2071 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2077 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2078 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2084 * Handle whether we can perform the seek event or if we have to let the chain
2085 * function handle seeks to build the seek indexes first.
2088 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2092 GstSeekType cur_type, stop_type;
2097 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2102 /* we can only seek on time */
2103 if (format != GST_FORMAT_TIME) {
2104 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2108 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2109 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2113 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2114 GST_DEBUG_OBJECT (demux,
2115 "Non-flushing seek not supported in streaming mode");
2119 if (flags & GST_SEEK_FLAG_SEGMENT) {
2120 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2124 /* check for having parsed index already */
2125 if (!demux->common.index_parsed) {
2126 gboolean building_index;
2129 if (!demux->index_offset) {
2130 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2134 GST_OBJECT_LOCK (demux);
2135 /* handle the seek event in the chain function */
2136 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2137 /* no more seek can be issued until state reset to _DATA */
2139 /* copy the event */
2140 if (demux->seek_event)
2141 gst_event_unref (demux->seek_event);
2142 demux->seek_event = gst_event_ref (event);
2144 /* set the building_index flag so that only one thread can setup the
2145 * structures for index seeking. */
2146 building_index = demux->building_index;
2147 if (!building_index) {
2148 demux->building_index = TRUE;
2149 offset = demux->index_offset;
2151 GST_OBJECT_UNLOCK (demux);
2153 if (!building_index) {
2154 /* seek to the first subindex or legacy index */
2155 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2156 return perform_seek_to_offset (demux, offset);
2159 /* well, we are handling it already */
2163 /* delegate to tweaked regular seek */
2164 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2168 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2171 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2172 gboolean res = TRUE;
2174 switch (GST_EVENT_TYPE (event)) {
2175 case GST_EVENT_SEEK:
2176 /* no seeking until we are (safely) ready */
2177 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2178 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2181 if (!demux->streaming)
2182 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2184 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2185 gst_event_unref (event);
2190 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2191 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2192 GstMatroskaTrackVideoContext *videocontext =
2193 (GstMatroskaTrackVideoContext *) context;
2195 GstClockTimeDiff diff;
2196 GstClockTime timestamp;
2198 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2200 GST_OBJECT_LOCK (demux);
2201 videocontext->earliest_time = timestamp + diff;
2202 GST_OBJECT_UNLOCK (demux);
2205 gst_event_unref (event);
2209 /* events we don't need to handle */
2210 case GST_EVENT_NAVIGATION:
2211 gst_event_unref (event);
2215 case GST_EVENT_LATENCY:
2217 res = gst_pad_push_event (demux->common.sinkpad, event);
2224 static GstFlowReturn
2225 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2227 GstFlowReturn ret = GST_FLOW_EOS;
2228 gboolean done = TRUE;
2231 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2232 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2235 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2237 if (!demux->seek_entry) {
2238 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2242 for (i = 0; i < demux->common.src->len; i++) {
2243 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2245 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2246 ", stream %d at %" GST_TIME_FORMAT,
2247 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2248 GST_TIME_ARGS (stream->from_time));
2249 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2250 if (stream->from_time > demux->common.segment.start) {
2251 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2255 /* nothing pushed for this stream;
2256 * likely seek entry did not start at keyframe, so all was skipped.
2257 * So we need an earlier entry */
2263 GstMatroskaIndex *entry;
2265 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2266 --demux->seek_entry);
2267 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE))
2277 static GstFlowReturn
2278 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2280 GstFlowReturn ret = GST_FLOW_OK;
2283 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2285 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2286 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2290 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2291 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2295 /* one track within the "all-tracks" header */
2296 case GST_MATROSKA_ID_TRACKENTRY:
2297 ret = gst_matroska_demux_add_stream (demux, ebml);
2301 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2306 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2308 demux->tracks_parsed = TRUE;
2314 * Read signed/unsigned "EBML" numbers.
2315 * Return: number of bytes processed.
2319 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2321 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2329 while (read <= 8 && !(total & len_mask)) {
2336 if ((total &= (len_mask - 1)) == len_mask - 1)
2341 if (data[n] == 0xff)
2343 total = (total << 8) | data[n];
2347 if (read == num_ffs && total != 0)
2356 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2361 /* read as unsigned number first */
2362 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2366 if (unum == G_MAXUINT64)
2369 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2375 * Mostly used for subtitles. We add void filler data for each
2376 * lagging stream to make sure we don't deadlock.
2380 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2384 GST_OBJECT_LOCK (demux);
2386 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2387 GST_TIME_ARGS (demux->common.segment.position));
2389 g_assert (demux->common.num_streams == demux->common.src->len);
2390 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2391 GstMatroskaTrackContext *context;
2393 context = g_ptr_array_index (demux->common.src, stream_nr);
2395 GST_LOG_OBJECT (demux,
2396 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2397 GST_TIME_ARGS (context->pos));
2399 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2400 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2404 /* does it lag? 0.5 seconds is a random threshold...
2405 * lag need only be considered if we have advanced into requested segment */
2406 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2407 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2408 demux->common.segment.position > demux->common.segment.start &&
2409 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2414 new_start = demux->common.segment.position - (GST_SECOND / 2);
2415 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop))
2416 new_start = MIN (new_start, demux->common.segment.stop);
2417 GST_DEBUG_OBJECT (demux,
2418 "Synchronizing stream %d with others by advancing time " "from %"
2419 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2420 GST_TIME_ARGS (context->pos), GST_TIME_ARGS (new_start));
2422 context->pos = new_start;
2424 /* advance stream time */
2425 segment = demux->common.segment;
2426 segment.start = new_start;
2427 segment.position = new_start;
2428 event = gst_event_new_segment (&segment);
2429 GST_OBJECT_UNLOCK (demux);
2430 gst_pad_push_event (context->pad, event);
2431 GST_OBJECT_LOCK (demux);
2435 GST_OBJECT_UNLOCK (demux);
2438 static GstFlowReturn
2439 gst_matroska_demux_push_hdr_buf (GstMatroskaDemux * demux,
2440 GstMatroskaTrackContext * stream, guint8 * data, guint len)
2442 GstFlowReturn ret, cret;
2443 GstBuffer *header_buf;
2445 header_buf = gst_buffer_new_wrapped (g_memdup (data, len), len);
2447 if (stream->set_discont) {
2448 GST_BUFFER_FLAG_SET (header_buf, GST_BUFFER_FLAG_DISCONT);
2449 stream->set_discont = FALSE;
2452 ret = gst_pad_push (stream->pad, header_buf);
2455 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
2460 static GstFlowReturn
2461 gst_matroska_demux_push_flac_codec_priv_data (GstMatroskaDemux * demux,
2462 GstMatroskaTrackContext * stream)
2468 GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
2470 pdata = (guint8 *) stream->codec_priv;
2472 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2473 if (stream->codec_priv_size < ((4) + (4 + 34))) {
2474 GST_WARNING_OBJECT (demux, "not enough codec priv data for flac headers");
2475 return GST_FLOW_ERROR;
2478 if (memcmp (pdata, "fLaC", 4) != 0) {
2479 GST_WARNING_OBJECT (demux, "no flac marker at start of stream headers");
2480 return GST_FLOW_ERROR;
2483 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 4);
2484 if (ret != GST_FLOW_OK)
2487 off = 4; /* skip fLaC marker */
2488 while (off < stream->codec_priv_size) {
2489 len = GST_READ_UINT8 (pdata + off + 1) << 16;
2490 len |= GST_READ_UINT8 (pdata + off + 2) << 8;
2491 len |= GST_READ_UINT8 (pdata + off + 3);
2493 GST_DEBUG_OBJECT (demux, "header packet: len=%u bytes, flags=0x%02x",
2494 len, (guint) pdata[off]);
2496 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata + off, len + 4);
2497 if (ret != GST_FLOW_OK)
2505 static GstFlowReturn
2506 gst_matroska_demux_push_speex_codec_priv_data (GstMatroskaDemux * demux,
2507 GstMatroskaTrackContext * stream)
2510 guint8 *pdata = stream->codec_priv;
2512 GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
2514 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2515 if (stream->codec_priv_size < 80) {
2516 GST_WARNING_OBJECT (demux, "not enough codec priv data for speex headers");
2517 return GST_FLOW_ERROR;
2520 if (memcmp (pdata, "Speex ", 8) != 0) {
2521 GST_WARNING_OBJECT (demux, "no Speex marker at start of stream headers");
2522 return GST_FLOW_ERROR;
2525 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 80);
2526 if (ret != GST_FLOW_OK)
2529 if (stream->codec_priv_size == 80)
2532 return gst_matroska_demux_push_hdr_buf (demux, stream, pdata + 80,
2533 stream->codec_priv_size - 80);
2536 static GstFlowReturn
2537 gst_matroska_demux_push_xiph_codec_priv_data (GstMatroskaDemux * demux,
2538 GstMatroskaTrackContext * stream)
2541 guint8 *p = stream->codec_priv;
2542 gint i, offset, num_packets;
2543 guint *length, last;
2545 if (stream->codec_priv == NULL || stream->codec_priv_size == 0) {
2546 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
2547 ("Missing codec private data for xiph headers, broken file"));
2548 return GST_FLOW_ERROR;
2551 /* start of the stream and vorbis audio or theora video, need to
2552 * send the codec_priv data as first three packets */
2553 num_packets = p[0] + 1;
2554 GST_DEBUG_OBJECT (demux, "%u stream headers, total length=%u bytes",
2555 (guint) num_packets, stream->codec_priv_size);
2557 length = g_alloca (num_packets * sizeof (guint));
2561 /* first packets, read length values */
2562 for (i = 0; i < num_packets - 1; i++) {
2564 while (offset < stream->codec_priv_size) {
2565 length[i] += p[offset];
2566 if (p[offset++] != 0xff)
2571 if (offset + last > stream->codec_priv_size)
2572 return GST_FLOW_ERROR;
2574 /* last packet is the remaining size */
2575 length[i] = stream->codec_priv_size - offset - last;
2577 for (i = 0; i < num_packets; i++) {
2578 GST_DEBUG_OBJECT (demux, "buffer %d: length=%u bytes", i,
2580 if (offset + length[i] > stream->codec_priv_size)
2581 return GST_FLOW_ERROR;
2584 gst_matroska_demux_push_hdr_buf (demux, stream, p + offset, length[i]);
2585 if (ret != GST_FLOW_OK)
2588 offset += length[i];
2594 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2595 GstMatroskaTrackContext * stream)
2599 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2601 if (!stream->codec_priv)
2604 /* ideally, VobSub private data should be parsed and stored more convenient
2605 * elsewhere, but for now, only interested in a small part */
2607 /* make sure we have terminating 0 */
2608 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2610 /* just locate and parse palette part */
2611 start = strstr (buf, "palette:");
2616 guint8 r, g, b, y, u, v;
2619 while (g_ascii_isspace (*start))
2621 for (i = 0; i < 16; i++) {
2622 if (sscanf (start, "%06x", &col) != 1)
2625 while ((*start == ',') || g_ascii_isspace (*start))
2627 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2628 r = (col >> 16) & 0xff;
2629 g = (col >> 8) & 0xff;
2631 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2633 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2634 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2635 clut[i] = (y << 16) | (u << 8) | v;
2638 /* got them all without problems; build and send event */
2642 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2643 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2644 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2645 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2646 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2647 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2648 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2649 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2650 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2651 G_TYPE_INT, clut[15], NULL);
2653 gst_pad_push_event (stream->pad,
2654 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
2660 static GstFlowReturn
2661 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2662 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2665 guint seq_header_len;
2666 guint32 header, tmp;
2668 if (stream->codec_state) {
2669 seq_header = stream->codec_state;
2670 seq_header_len = stream->codec_state_size;
2671 } else if (stream->codec_priv) {
2672 seq_header = stream->codec_priv;
2673 seq_header_len = stream->codec_priv_size;
2678 /* Sequence header only needed for keyframes */
2679 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2682 if (gst_buffer_get_size (*buf) < 4)
2685 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2686 header = GUINT32_FROM_BE (tmp);
2688 /* Sequence start code, if not found prepend */
2689 if (header != 0x000001b3) {
2692 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2694 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2697 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2698 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2699 gst_buffer_get_size (*buf));
2701 gst_buffer_unref (*buf);
2708 static GstFlowReturn
2709 gst_matroska_demux_add_wvpk_header (GstElement * element,
2710 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2712 GstMatroskaTrackAudioContext *audiocontext =
2713 (GstMatroskaTrackAudioContext *) stream;
2714 GstBuffer *newbuf = NULL;
2715 guint8 *buf_data, *data;
2723 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2726 wvh.total_samples = -1;
2727 wvh.block_index = audiocontext->wvpk_block_index;
2729 if (audiocontext->channels <= 2) {
2730 guint32 block_samples, tmp;
2731 gsize size = gst_buffer_get_size (*buf);
2733 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2734 block_samples = GUINT32_FROM_LE (tmp);
2735 /* we need to reconstruct the header of the wavpack block */
2737 /* -20 because ck_size is the size of the wavpack block -8
2738 * and lace_size is the size of the wavpack block + 12
2739 * (the three guint32 of the header that already are in the buffer) */
2740 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2742 /* block_samples, flags and crc are already in the buffer */
2743 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, 0);
2745 data = gst_buffer_map (newbuf, NULL, NULL, GST_MAP_WRITE);
2750 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2751 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2752 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2753 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2754 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2755 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2757 /* Append data from buf: */
2758 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2759 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2761 gst_buffer_unref (*buf);
2763 audiocontext->wvpk_block_index += block_samples;
2765 guint8 *outdata = NULL;
2767 gsize buf_size, size, out_size = 0;
2768 guint32 block_samples, flags, crc, blocksize;
2770 buf_data = gst_buffer_map (*buf, &buf_size, NULL, GST_MAP_READ);
2773 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2774 gst_buffer_unmap (*buf, buf_data, buf_size);
2775 return GST_FLOW_ERROR;
2781 block_samples = GST_READ_UINT32_LE (data);
2786 flags = GST_READ_UINT32_LE (data);
2789 crc = GST_READ_UINT32_LE (data);
2792 blocksize = GST_READ_UINT32_LE (data);
2796 if (blocksize == 0 || size < blocksize)
2799 g_assert ((newbuf == NULL) == (outdata == NULL));
2801 if (newbuf == NULL) {
2802 out_size = sizeof (Wavpack4Header) + blocksize;
2803 newbuf = gst_buffer_new_allocate (NULL, out_size, 0);
2805 gst_buffer_copy_into (newbuf, *buf,
2806 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2809 outdata = gst_buffer_map (newbuf, NULL, NULL, GST_MAP_WRITE);
2811 gst_buffer_unmap (newbuf, outdata, out_size);
2812 out_size += sizeof (Wavpack4Header) + blocksize;
2813 gst_buffer_set_size (newbuf, out_size);
2814 outdata = gst_buffer_map (newbuf, NULL, NULL, GST_MAP_WRITE);
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_unmap (*buf, buf_data, buf_size);
2841 gst_buffer_unref (*buf);
2844 gst_buffer_unmap (newbuf, outdata, out_size);
2847 audiocontext->wvpk_block_index += block_samples;
2853 /* @text must be null-terminated */
2855 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2860 /* yes, this might all lead to false positives ... */
2861 tag = (gchar *) text;
2862 while ((tag = strchr (tag, '<'))) {
2864 if (*tag != '\0' && *(tag + 1) == '>') {
2865 /* some common convenience ones */
2866 /* maybe any character will do here ? */
2879 if (strstr (text, "<span"))
2885 static GstFlowReturn
2886 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2887 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2889 GstMatroskaTrackSubtitleContext *sub_stream;
2890 const gchar *encoding;
2897 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
2899 data = gst_buffer_map (*buf, &size, NULL, GST_MAP_READ);
2901 if (!sub_stream->invalid_utf8) {
2902 if (g_utf8_validate (data, size, NULL)) {
2905 GST_WARNING_OBJECT (element, "subtitle stream %d is not valid UTF-8, this "
2906 "is broken according to the matroska specification", stream->num);
2907 sub_stream->invalid_utf8 = TRUE;
2910 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
2911 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
2912 if (encoding == NULL || *encoding == '\0') {
2913 /* if local encoding is UTF-8 and no encoding specified
2914 * via the environment variable, assume ISO-8859-15 */
2915 if (g_get_charset (&encoding)) {
2916 encoding = "ISO-8859-15";
2920 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
2924 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
2925 encoding, err->message);
2929 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
2930 encoding = "ISO-8859-15";
2931 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
2935 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
2936 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
2939 utf8 = g_strdup ("invalid subtitle");
2941 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
2942 gst_buffer_copy_into (newbuf, *buf,
2943 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
2945 gst_buffer_unmap (*buf, data, size);
2947 gst_buffer_unref (*buf);
2950 data = gst_buffer_map (*buf, &size, NULL, GST_MAP_READ);
2953 if (sub_stream->check_markup) {
2954 /* caps claim markup text, so we need to escape text,
2955 * except if text is already markup and then needs no further escaping */
2956 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
2957 gst_matroska_demux_subtitle_chunk_has_tag (element, data);
2959 if (!sub_stream->seen_markup_tag) {
2960 utf8 = g_markup_escape_text (data, size);
2962 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
2963 gst_buffer_copy_into (newbuf, *buf,
2964 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
2965 GST_BUFFER_COPY_META, 0, -1);
2966 gst_buffer_unmap (*buf, data, size);
2967 gst_buffer_unref (*buf);
2976 static GstFlowReturn
2977 gst_matroska_demux_check_aac (GstElement * element,
2978 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2983 gst_buffer_extract (*buf, 0, data, 2);
2984 size = gst_buffer_get_size (*buf);
2986 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
2990 /* tss, ADTS data, remove codec_data
2991 * still assume it is at least parsed */
2992 new_caps = gst_caps_copy (stream->caps);
2993 s = gst_caps_get_structure (new_caps, 0);
2995 gst_structure_remove_field (s, "codec_data");
2996 gst_caps_replace (&stream->caps, new_caps);
2997 gst_pad_set_caps (stream->pad, new_caps);
2998 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
2999 "new caps: %" GST_PTR_FORMAT, new_caps);
3000 gst_caps_unref (new_caps);
3003 /* disable subsequent checking */
3004 stream->postprocess_frame = NULL;
3010 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3011 GstBuffer * buffer, gsize alignment)
3016 data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
3018 if (size < sizeof (guintptr)) {
3019 gst_buffer_unmap (buffer, data, size);
3023 if (((guintptr) data) & (alignment - 1)) {
3024 GstBuffer *new_buffer;
3027 new_buffer = gst_buffer_new_allocate (NULL,
3028 gst_buffer_get_size (buffer), alignment);
3029 /* Copy data "by hand", so ensure alignment is kept: */
3030 new_data = gst_buffer_map (new_buffer, NULL, NULL, GST_MAP_WRITE);
3031 memcpy (new_data, data, size);
3032 gst_buffer_unmap (new_buffer, new_data, -1);
3033 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3034 GST_DEBUG_OBJECT (demux, "We want output aligned on %d, reallocated",
3037 gst_buffer_unmap (buffer, data, size);
3038 gst_buffer_unref (buffer);
3043 gst_buffer_unmap (buffer, data, size);
3047 static GstFlowReturn
3048 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3049 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3050 gboolean is_simpleblock)
3052 GstMatroskaTrackContext *stream = NULL;
3053 GstFlowReturn ret = GST_FLOW_OK;
3054 gboolean readblock = FALSE;
3056 guint64 block_duration = -1;
3057 GstBuffer *buf = NULL;
3058 gpointer buf_data = NULL;
3060 gint stream_num = -1, n, laces = 0;
3062 gint *lace_size = NULL;
3065 gint64 referenceblock = 0;
3068 offset = gst_ebml_read_get_offset (ebml);
3070 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3071 if (!is_simpleblock) {
3072 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3076 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3080 /* one block inside the group. Note, block parsing is one
3081 * of the harder things, so this code is a bit complicated.
3082 * See http://www.matroska.org/ for documentation. */
3083 case GST_MATROSKA_ID_SIMPLEBLOCK:
3084 case GST_MATROSKA_ID_BLOCK:
3090 gst_buffer_unmap (buf, buf_data, buf_size);
3091 gst_buffer_unref (buf);
3094 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3097 buf_data = gst_buffer_map (buf, &buf_size, NULL, GST_MAP_READ);
3101 /* first byte(s): blocknum */
3102 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3107 /* fetch stream from num */
3108 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3110 if (G_UNLIKELY (size < 3)) {
3111 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3112 /* non-fatal, try next block(group) */
3115 } else if (G_UNLIKELY (stream_num < 0 ||
3116 stream_num >= demux->common.num_streams)) {
3117 /* let's not give up on a stray invalid track number */
3118 GST_WARNING_OBJECT (demux,
3119 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3120 "; ignoring block", stream_num, num);
3124 stream = g_ptr_array_index (demux->common.src, stream_num);
3126 /* time (relative to cluster time) */
3127 time = ((gint16) GST_READ_UINT16_BE (data));
3130 flags = GST_READ_UINT8 (data);
3134 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3137 switch ((flags & 0x06) >> 1) {
3138 case 0x0: /* no lacing */
3140 lace_size = g_new (gint, 1);
3141 lace_size[0] = size;
3144 case 0x1: /* xiph lacing */
3145 case 0x2: /* fixed-size lacing */
3146 case 0x3: /* EBML lacing */
3148 goto invalid_lacing;
3149 laces = GST_READ_UINT8 (data) + 1;
3152 lace_size = g_new0 (gint, laces);
3154 switch ((flags & 0x06) >> 1) {
3155 case 0x1: /* xiph lacing */ {
3156 guint temp, total = 0;
3158 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3161 goto invalid_lacing;
3162 temp = GST_READ_UINT8 (data);
3163 lace_size[n] += temp;
3169 total += lace_size[n];
3171 lace_size[n] = size - total;
3175 case 0x2: /* fixed-size lacing */
3176 for (n = 0; n < laces; n++)
3177 lace_size[n] = size / laces;
3180 case 0x3: /* EBML lacing */ {
3183 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3187 total = lace_size[0] = num;
3188 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3192 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3196 lace_size[n] = lace_size[n - 1] + snum;
3197 total += lace_size[n];
3200 lace_size[n] = size - total;
3207 if (stream->send_xiph_headers) {
3208 ret = gst_matroska_demux_push_xiph_codec_priv_data (demux, stream);
3209 stream->send_xiph_headers = FALSE;
3212 if (stream->send_flac_headers) {
3213 ret = gst_matroska_demux_push_flac_codec_priv_data (demux, stream);
3214 stream->send_flac_headers = FALSE;
3217 if (stream->send_speex_headers) {
3218 ret = gst_matroska_demux_push_speex_codec_priv_data (demux, stream);
3219 stream->send_speex_headers = FALSE;
3222 if (stream->send_dvd_event) {
3223 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
3224 /* FIXME: should we send this event again after (flushing) seek ? */
3225 stream->send_dvd_event = FALSE;
3228 if (ret != GST_FLOW_OK)
3235 case GST_MATROSKA_ID_BLOCKDURATION:{
3236 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3237 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3242 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3243 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3244 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3249 case GST_MATROSKA_ID_CODECSTATE:{
3251 guint64 data_len = 0;
3254 gst_ebml_read_binary (ebml, &id, &data,
3255 &data_len)) != GST_FLOW_OK)
3258 if (G_UNLIKELY (stream == NULL)) {
3259 GST_WARNING_OBJECT (demux,
3260 "Unexpected CodecState subelement - ignoring");
3264 g_free (stream->codec_state);
3265 stream->codec_state = data;
3266 stream->codec_state_size = data_len;
3268 /* Decode if necessary */
3269 if (stream->encodings && stream->encodings->len > 0
3270 && stream->codec_state && stream->codec_state_size > 0) {
3271 if (!gst_matroska_decode_data (stream->encodings,
3272 &stream->codec_state, &stream->codec_state_size,
3273 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3274 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3278 GST_DEBUG_OBJECT (demux, "CodecState of %u bytes",
3279 stream->codec_state_size);
3284 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3288 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3289 case GST_MATROSKA_ID_BLOCKADDITIONS:
3290 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3291 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3292 case GST_MATROSKA_ID_SLICES:
3293 GST_DEBUG_OBJECT (demux,
3294 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3295 ret = gst_ebml_read_skip (ebml);
3303 /* reading a number or so could have failed */
3304 if (ret != GST_FLOW_OK)
3307 if (ret == GST_FLOW_OK && readblock) {
3308 guint64 duration = 0;
3309 gint64 lace_time = 0;
3310 gboolean delta_unit;
3312 stream = g_ptr_array_index (demux->common.src, stream_num);
3314 if (cluster_time != GST_CLOCK_TIME_NONE) {
3315 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3316 * Drop unless the lace contains timestamp 0? */
3317 if (time < 0 && (-time) > cluster_time) {
3320 if (stream->timecodescale == 1.0)
3321 lace_time = (cluster_time + time) * demux->common.time_scale;
3324 gst_util_guint64_to_gdouble ((cluster_time + time) *
3325 demux->common.time_scale) * stream->timecodescale;
3328 lace_time = GST_CLOCK_TIME_NONE;
3331 /* need to refresh segment info ASAP */
3332 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3333 GstSegment *segment = &demux->common.segment;
3334 guint64 segment_duration = 0;
3336 GST_DEBUG_OBJECT (demux,
3337 "generating segment starting at %" GST_TIME_FORMAT,
3338 GST_TIME_ARGS (lace_time));
3339 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3340 demux->stream_start_time = lace_time;
3341 GST_DEBUG_OBJECT (demux,
3342 "Setting stream start time to %" GST_TIME_FORMAT,
3343 GST_TIME_ARGS (lace_time));
3345 if (GST_CLOCK_TIME_IS_VALID (segment->stop))
3346 segment_duration = segment->stop - segment->start;
3347 else if (GST_CLOCK_TIME_IS_VALID (segment->position))
3348 segment_duration = segment->position - segment->start;
3349 segment->base += segment_duration / fabs (segment->rate);
3350 segment->start = lace_time;
3351 segment->stop = GST_CLOCK_TIME_NONE;
3352 segment->position = lace_time - demux->stream_start_time;
3353 /* now convey our segment notion downstream */
3354 gst_matroska_demux_send_event (demux, gst_event_new_segment (segment));
3355 demux->need_segment = FALSE;
3358 if (block_duration != -1) {
3359 if (stream->timecodescale == 1.0)
3360 duration = gst_util_uint64_scale (block_duration,
3361 demux->common.time_scale, 1);
3364 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3365 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3366 1)) * stream->timecodescale);
3367 } else if (stream->default_duration) {
3368 duration = stream->default_duration * laces;
3370 /* else duration is diff between timecode of this and next block */
3372 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3373 a ReferenceBlock implies that this is not a keyframe. In either
3374 case, it only makes sense for video streams. */
3375 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3376 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
3378 if (delta_unit && stream->set_discont) {
3379 /* When doing seeks or such, we need to restart on key frames or
3380 * decoders might choke. */
3381 GST_DEBUG_OBJECT (demux, "skipping delta unit");
3385 for (n = 0; n < laces; n++) {
3388 if (G_UNLIKELY (lace_size[n] > size)) {
3389 GST_WARNING_OBJECT (demux, "Invalid lace size");
3393 /* QoS for video track with an index. the assumption is that
3394 index entries point to keyframes, but if that is not true we
3395 will instad skip until the next keyframe. */
3396 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3397 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3398 stream->index_table && demux->common.segment.rate > 0.0) {
3399 GstMatroskaTrackVideoContext *videocontext =
3400 (GstMatroskaTrackVideoContext *) stream;
3401 GstClockTime earliest_time;
3402 GstClockTime earliest_stream_time;
3404 GST_OBJECT_LOCK (demux);
3405 earliest_time = videocontext->earliest_time;
3406 GST_OBJECT_UNLOCK (demux);
3407 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3408 GST_FORMAT_TIME, earliest_time);
3410 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3411 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3412 lace_time <= earliest_stream_time) {
3413 /* find index entry (keyframe) <= earliest_stream_time */
3414 GstMatroskaIndex *entry =
3415 gst_util_array_binary_search (stream->index_table->data,
3416 stream->index_table->len, sizeof (GstMatroskaIndex),
3417 (GCompareDataFunc) gst_matroska_index_seek_find,
3418 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3420 /* if that entry (keyframe) is after the current the current
3421 buffer, we can skip pushing (and thus decoding) all
3422 buffers until that keyframe. */
3423 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3424 entry->time > lace_time) {
3425 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3426 stream->set_discont = TRUE;
3432 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3433 gst_buffer_get_size (buf) - size, lace_size[n]);
3434 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3437 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3439 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3441 if (stream->encodings != NULL && stream->encodings->len > 0)
3442 sub = gst_matroska_decode_buffer (stream, sub);
3445 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3449 GST_BUFFER_TIMESTAMP (sub) = lace_time;
3451 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3452 GstClockTime last_stop_end;
3454 /* Check if this stream is after segment stop */
3455 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3456 lace_time >= demux->common.segment.stop) {
3457 GST_DEBUG_OBJECT (demux,
3458 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3459 GST_TIME_ARGS (demux->common.segment.stop));
3460 gst_buffer_unref (sub);
3463 if (offset >= stream->to_offset) {
3464 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3466 gst_buffer_unref (sub);
3470 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3471 * that landed us with timestamps not quite intended */
3472 GST_OBJECT_LOCK (demux);
3473 if (demux->max_gap_time &&
3474 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3475 demux->common.segment.rate > 0.0) {
3476 GstClockTimeDiff diff;
3478 /* only send segments with increasing start times,
3479 * otherwise if these go back and forth downstream (sinks) increase
3480 * accumulated time and running_time */
3481 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3482 if (diff > 0 && diff > demux->max_gap_time
3483 && lace_time > demux->common.segment.start
3484 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3485 || lace_time < demux->common.segment.stop)) {
3487 GstEvent *event1, *event2;
3488 GST_DEBUG_OBJECT (demux,
3489 "Gap of %" G_GINT64_FORMAT " ns detected in"
3490 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3491 "Sending updated SEGMENT events", diff,
3492 stream->index, GST_TIME_ARGS (stream->pos),
3493 GST_TIME_ARGS (lace_time));
3494 /* send segment events such that the gap is not accounted in
3495 * segment base time, hence running_time */
3496 /* close ahead of gap */
3497 segment = demux->common.segment;
3498 segment.start = demux->last_stop_end;
3499 segment.stop = demux->last_stop_end;
3500 segment.position = demux->last_stop_end;
3501 event1 = gst_event_new_segment (&segment);
3503 segment.start = lace_time;
3504 segment.stop = demux->common.segment.stop;
3505 segment.position = lace_time;
3506 event2 = gst_event_new_segment (&segment);
3507 GST_OBJECT_UNLOCK (demux);
3508 gst_matroska_demux_send_event (demux, event1);
3509 gst_matroska_demux_send_event (demux, event2);
3510 GST_OBJECT_LOCK (demux);
3511 /* align segment view with downstream,
3512 * prevents double-counting base time when closing segment */
3513 /* FIXME: in 0.10, the segment base/accum got updated here, but
3514 * maybe we don't need that because of the double accounting
3515 * mentioned above? */
3516 demux->common.segment = segment;
3520 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3521 || demux->common.segment.position < lace_time) {
3522 demux->common.segment.position = lace_time;
3524 GST_OBJECT_UNLOCK (demux);
3526 last_stop_end = lace_time;
3528 GST_BUFFER_DURATION (sub) = duration / laces;
3529 last_stop_end += GST_BUFFER_DURATION (sub);
3532 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3533 demux->last_stop_end < last_stop_end)
3534 demux->last_stop_end = last_stop_end;
3536 GST_OBJECT_LOCK (demux);
3537 if (demux->common.segment.duration == -1 ||
3538 demux->common.segment.duration <
3539 lace_time - demux->stream_start_time) {
3540 demux->common.segment.duration =
3541 last_stop_end - demux->stream_start_time;
3542 GST_OBJECT_UNLOCK (demux);
3543 gst_element_post_message (GST_ELEMENT_CAST (demux),
3544 gst_message_new_duration (GST_OBJECT_CAST (demux),
3545 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
3547 GST_OBJECT_UNLOCK (demux);
3551 stream->pos = lace_time;
3553 gst_matroska_demux_sync_streams (demux);
3555 if (stream->set_discont) {
3556 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3557 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3558 stream->set_discont = FALSE;
3561 /* reverse playback book-keeping */
3562 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3563 stream->from_time = lace_time;
3564 if (stream->from_offset == -1)
3565 stream->from_offset = offset;
3567 GST_DEBUG_OBJECT (demux,
3568 "Pushing lace %d, data of size %d for stream %d, time=%"
3569 GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
3570 gst_buffer_get_size (sub), stream_num,
3571 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
3572 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3575 if (demux->common.element_index) {
3576 if (stream->index_writer_id == -1)
3577 gst_index_get_writer_id (demux->common.element_index,
3578 GST_OBJECT (stream->pad), &stream->index_writer_id);
3580 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3581 G_GUINT64_FORMAT " for writer id %d",
3582 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
3583 stream->index_writer_id);
3584 gst_index_add_association (demux->common.element_index,
3585 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3586 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3587 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
3588 cluster_offset, NULL);
3592 /* Postprocess the buffers depending on the codec used */
3593 if (stream->postprocess_frame) {
3594 GST_LOG_OBJECT (demux, "running post process");
3595 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3598 /* At this point, we have a sub-buffer pointing at data within a larger
3599 buffer. This data might not be aligned with anything. If the data is
3600 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3601 for 32 bit samples, etc), or bad things will happen downstream as
3602 elements typically assume minimal alignment.
3603 Therefore, create an aligned copy if necessary. */
3604 g_assert (stream->alignment <= G_MEM_ALIGN);
3605 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3607 ret = gst_pad_push (stream->pad, sub);
3608 if (demux->common.segment.rate < 0) {
3609 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3610 /* In reverse playback we can get a GST_FLOW_EOS when
3611 * we are at the end of the segment, so we just need to jump
3612 * back to the previous section. */
3613 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3618 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3621 size -= lace_size[n];
3622 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3623 lace_time += duration / laces;
3625 lace_time = GST_CLOCK_TIME_NONE;
3631 gst_buffer_unmap (buf, buf_data, buf_size);
3632 gst_buffer_unref (buf);
3644 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3649 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3650 /* non-fatal, try next block(group) */
3656 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3657 /* non-fatal, try next block(group) */
3663 /* return FALSE if block(group) should be skipped (due to a seek) */
3664 static inline gboolean
3665 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3667 if (G_UNLIKELY (demux->seek_block)) {
3668 if (!(--demux->seek_block)) {
3671 GST_LOG_OBJECT (demux, "should skip block due to seek");
3679 static GstFlowReturn
3680 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3684 guint64 seek_pos = (guint64) - 1;
3685 guint32 seek_id = 0;
3688 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3690 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3691 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3695 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3696 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3700 case GST_MATROSKA_ID_SEEKID:
3704 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3707 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3712 case GST_MATROSKA_ID_SEEKPOSITION:
3716 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3719 if (t > G_MAXINT64) {
3720 GST_WARNING_OBJECT (demux,
3721 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3725 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3731 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3737 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3740 if (!seek_id || seek_pos == (guint64) - 1) {
3741 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3742 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3747 case GST_MATROSKA_ID_SEEKHEAD:
3750 case GST_MATROSKA_ID_CUES:
3751 case GST_MATROSKA_ID_TAGS:
3752 case GST_MATROSKA_ID_TRACKS:
3753 case GST_MATROSKA_ID_SEGMENTINFO:
3754 case GST_MATROSKA_ID_ATTACHMENTS:
3755 case GST_MATROSKA_ID_CHAPTERS:
3757 guint64 before_pos, length;
3761 length = gst_matroska_read_common_get_length (&demux->common);
3762 before_pos = demux->common.offset;
3764 if (length == (guint64) - 1) {
3765 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3769 /* check for validity */
3770 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3771 GST_WARNING_OBJECT (demux,
3772 "SeekHead reference lies outside file!" " (%"
3773 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3774 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3779 /* only pick up index location when streaming */
3780 if (demux->streaming) {
3781 if (seek_id == GST_MATROSKA_ID_CUES) {
3782 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3783 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3784 demux->index_offset);
3790 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3793 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3794 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3798 if (id != seek_id) {
3799 GST_WARNING_OBJECT (demux,
3800 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3801 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3804 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3809 demux->common.offset = before_pos;
3813 case GST_MATROSKA_ID_CLUSTER:
3815 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3817 GST_LOG_OBJECT (demux, "Cluster position");
3818 if (G_UNLIKELY (!demux->clusters))
3819 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3820 g_array_append_val (demux->clusters, pos);
3825 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3828 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3833 static GstFlowReturn
3834 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3836 GstFlowReturn ret = GST_FLOW_OK;
3839 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3841 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3842 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3846 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3847 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3851 case GST_MATROSKA_ID_SEEKENTRY:
3853 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3854 /* Ignore EOS and errors here */
3855 if (ret != GST_FLOW_OK) {
3856 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3863 ret = gst_matroska_read_common_parse_skip (&demux->common,
3864 ebml, "SeekHead", id);
3869 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3871 /* Sort clusters by position for easier searching */
3872 if (demux->clusters)
3873 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3878 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3880 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3882 static inline GstFlowReturn
3883 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
3885 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
3886 /* only a few blocks are expected/allowed to be large,
3887 * and will be recursed into, whereas others will be read and must fit */
3888 if (demux->streaming) {
3889 /* fatal in streaming case, as we can't step over easily */
3890 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3891 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
3892 "file might be corrupt.", bytes));
3893 return GST_FLOW_ERROR;
3895 /* indicate higher level to quietly give up */
3896 GST_DEBUG_OBJECT (demux,
3897 "too large block of size %" G_GUINT64_FORMAT, bytes);
3898 return GST_FLOW_ERROR;
3905 /* returns TRUE if we truely are in error state, and should give up */
3906 static inline gboolean
3907 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
3909 if (!demux->streaming && demux->next_cluster_offset > 0) {
3910 /* just repositioning to where next cluster should be and try from there */
3911 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
3912 G_GUINT64_FORMAT, demux->next_cluster_offset);
3913 demux->common.offset = demux->next_cluster_offset;
3914 demux->next_cluster_offset = 0;
3919 /* sigh, one last attempt above and beyond call of duty ...;
3920 * search for cluster mark following current pos */
3921 pos = demux->common.offset;
3922 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
3923 if (gst_matroska_demux_search_cluster (demux, &pos) != GST_FLOW_OK) {
3924 /* did not work, give up */
3927 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
3928 /* try that position */
3929 demux->common.offset = pos;
3935 static inline GstFlowReturn
3936 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
3938 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
3939 demux->common.offset += flush;
3940 if (demux->streaming) {
3943 /* hard to skip large blocks when streaming */
3944 ret = gst_matroska_demux_check_read_size (demux, flush);
3945 if (ret != GST_FLOW_OK)
3947 if (flush <= gst_adapter_available (demux->common.adapter))
3948 gst_adapter_flush (demux->common.adapter, flush);
3950 return GST_FLOW_EOS;
3955 /* initializes @ebml with @bytes from input stream at current offset.
3956 * Returns EOS if insufficient available,
3957 * ERROR if too much was attempted to read. */
3958 static inline GstFlowReturn
3959 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
3962 GstBuffer *buffer = NULL;
3963 GstFlowReturn ret = GST_FLOW_OK;
3965 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
3967 ret = gst_matroska_demux_check_read_size (demux, bytes);
3968 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
3969 if (!demux->streaming) {
3970 /* in pull mode, we can skip */
3971 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
3972 ret = GST_FLOW_OVERFLOW;
3974 /* otherwise fatal */
3975 ret = GST_FLOW_ERROR;
3979 if (demux->streaming) {
3980 if (gst_adapter_available (demux->common.adapter) >= bytes)
3981 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
3985 ret = gst_matroska_read_common_peek_bytes (&demux->common,
3986 demux->common.offset, bytes, &buffer, NULL);
3987 if (G_LIKELY (buffer)) {
3988 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
3989 demux->common.offset);
3990 demux->common.offset += bytes;
3997 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4000 gboolean seekable = FALSE;
4001 gint64 start = -1, stop = -1;
4003 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4004 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4005 GST_DEBUG_OBJECT (demux, "seeking query failed");
4009 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4011 /* try harder to query upstream size if we didn't get it the first time */
4012 if (seekable && stop == -1) {
4013 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4014 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4018 /* if upstream doesn't know the size, it's likely that it's not seekable in
4019 * practice even if it technically may be seekable */
4020 if (seekable && (start != 0 || stop <= start)) {
4021 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4026 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4027 G_GUINT64_FORMAT ")", seekable, start, stop);
4028 demux->seekable = seekable;
4030 gst_query_unref (query);
4033 static GstFlowReturn
4034 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4040 GstFlowReturn ret = GST_FLOW_OK;
4042 GST_WARNING_OBJECT (demux,
4043 "Found Cluster element before Tracks, searching Tracks");
4046 before_pos = demux->common.offset;
4048 /* Search Tracks element */
4050 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4051 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4052 if (ret != GST_FLOW_OK)
4055 if (id != GST_MATROSKA_ID_TRACKS) {
4056 /* we may be skipping large cluster here, so forego size check etc */
4057 /* ... but we can't skip undefined size; force error */
4058 if (length == G_MAXUINT64) {
4059 ret = gst_matroska_demux_check_read_size (demux, length);
4062 demux->common.offset += needed;
4063 demux->common.offset += length;
4068 /* will lead to track parsing ... */
4069 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4074 demux->common.offset = before_pos;
4079 #define GST_READ_CHECK(stmt) \
4081 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4082 if (ret == GST_FLOW_OVERFLOW) { \
4083 ret = GST_FLOW_OK; \
4089 static GstFlowReturn
4090 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4091 guint64 length, guint needed)
4093 GstEbmlRead ebml = { 0, };
4094 GstFlowReturn ret = GST_FLOW_OK;
4097 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4098 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4100 /* if we plan to read and parse this element, we need prefix (id + length)
4101 * and the contents */
4102 /* mind about overflow wrap-around when dealing with undefined size */
4104 if (G_LIKELY (length != G_MAXUINT64))
4107 switch (demux->common.state) {
4108 case GST_MATROSKA_READ_STATE_START:
4110 case GST_EBML_ID_HEADER:
4111 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4112 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4113 if (ret != GST_FLOW_OK)
4115 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4116 gst_matroska_demux_check_seekability (demux);
4119 goto invalid_header;
4123 case GST_MATROSKA_READ_STATE_SEGMENT:
4125 case GST_MATROSKA_ID_SEGMENT:
4126 /* eat segment prefix */
4127 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4128 GST_DEBUG_OBJECT (demux,
4129 "Found Segment start at offset %" G_GUINT64_FORMAT,
4130 demux->common.offset);
4131 /* seeks are from the beginning of the segment,
4132 * after the segment ID/length */
4133 demux->common.ebml_segment_start = demux->common.offset;
4134 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4137 GST_WARNING_OBJECT (demux,
4138 "Expected a Segment ID (0x%x), but received 0x%x!",
4139 GST_MATROSKA_ID_SEGMENT, id);
4140 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4144 case GST_MATROSKA_READ_STATE_SCANNING:
4145 if (id != GST_MATROSKA_ID_CLUSTER &&
4146 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4149 case GST_MATROSKA_READ_STATE_HEADER:
4150 case GST_MATROSKA_READ_STATE_DATA:
4151 case GST_MATROSKA_READ_STATE_SEEK:
4153 case GST_MATROSKA_ID_SEGMENTINFO:
4154 if (!demux->common.segmentinfo_parsed) {
4155 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4156 ret = gst_matroska_read_common_parse_info (&demux->common,
4157 GST_ELEMENT_CAST (demux), &ebml);
4159 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4162 case GST_MATROSKA_ID_TRACKS:
4163 if (!demux->tracks_parsed) {
4164 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4165 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4167 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4170 case GST_MATROSKA_ID_CLUSTER:
4171 if (G_UNLIKELY (!demux->tracks_parsed)) {
4172 if (demux->streaming) {
4173 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4174 goto not_streamable;
4176 ret = gst_matroska_demux_find_tracks (demux);
4177 if (!demux->tracks_parsed)
4181 if (G_UNLIKELY (demux->common.state
4182 == GST_MATROSKA_READ_STATE_HEADER)) {
4183 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4184 demux->first_cluster_offset = demux->common.offset;
4185 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4186 gst_element_no_more_pads (GST_ELEMENT (demux));
4187 /* send initial segment - we wait till we know the first
4188 incoming timestamp, so we can properly set the start of
4190 demux->need_segment = TRUE;
4192 demux->cluster_time = GST_CLOCK_TIME_NONE;
4193 demux->cluster_offset = demux->common.offset;
4194 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4195 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4196 " not found in Cluster, trying next Cluster's first block instead",
4198 demux->seek_block = 0;
4200 demux->seek_first = FALSE;
4201 /* record next cluster for recovery */
4202 if (read != G_MAXUINT64)
4203 demux->next_cluster_offset = demux->cluster_offset + read;
4204 /* eat cluster prefix */
4205 gst_matroska_demux_flush (demux, needed);
4207 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4211 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4212 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4214 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4215 demux->cluster_time = num;
4217 if (demux->common.element_index) {
4218 if (demux->common.element_index_writer_id == -1)
4219 gst_index_get_writer_id (demux->common.element_index,
4220 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4221 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4222 G_GUINT64_FORMAT " for writer id %d",
4223 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4224 demux->common.element_index_writer_id);
4225 gst_index_add_association (demux->common.element_index,
4226 demux->common.element_index_writer_id,
4227 GST_ASSOCIATION_FLAG_KEY_UNIT,
4228 GST_FORMAT_TIME, demux->cluster_time,
4229 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4234 case GST_MATROSKA_ID_BLOCKGROUP:
4235 if (!gst_matroska_demux_seek_block (demux))
4237 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4238 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4239 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4240 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4241 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4243 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4245 case GST_MATROSKA_ID_SIMPLEBLOCK:
4246 if (!gst_matroska_demux_seek_block (demux))
4248 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4249 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4250 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4251 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4252 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4254 case GST_MATROSKA_ID_ATTACHMENTS:
4255 if (!demux->common.attachments_parsed) {
4256 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4257 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4258 GST_ELEMENT_CAST (demux), &ebml);
4260 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4263 case GST_MATROSKA_ID_TAGS:
4264 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4265 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4266 GST_ELEMENT_CAST (demux), &ebml);
4268 case GST_MATROSKA_ID_CHAPTERS:
4269 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4270 ret = gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4272 case GST_MATROSKA_ID_SEEKHEAD:
4273 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4274 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4276 case GST_MATROSKA_ID_CUES:
4277 if (demux->common.index_parsed) {
4278 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4281 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4282 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4283 /* only push based; delayed index building */
4284 if (ret == GST_FLOW_OK
4285 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4288 GST_OBJECT_LOCK (demux);
4289 event = demux->seek_event;
4290 demux->seek_event = NULL;
4291 GST_OBJECT_UNLOCK (demux);
4294 /* unlikely to fail, since we managed to seek to this point */
4295 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4297 /* resume data handling, main thread clear to seek again */
4298 GST_OBJECT_LOCK (demux);
4299 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4300 GST_OBJECT_UNLOCK (demux);
4303 case GST_MATROSKA_ID_POSITION:
4304 case GST_MATROSKA_ID_PREVSIZE:
4305 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4306 case GST_MATROSKA_ID_SILENTTRACKS:
4307 GST_DEBUG_OBJECT (demux,
4308 "Skipping Cluster subelement 0x%x - ignoring", id);
4312 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4313 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4319 if (ret == GST_FLOW_PARSE)
4323 gst_ebml_read_clear (&ebml);
4329 /* simply exit, maybe not enough data yet */
4330 /* no ebml to clear if read error */
4335 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4336 ("Failed to parse Element 0x%x", id));
4337 ret = GST_FLOW_ERROR;
4342 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4343 ("File layout does not permit streaming"));
4344 ret = GST_FLOW_ERROR;
4349 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4350 ("No Tracks element found"));
4351 ret = GST_FLOW_ERROR;
4356 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4357 ret = GST_FLOW_ERROR;
4362 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4363 ret = GST_FLOW_ERROR;
4369 gst_matroska_demux_loop (GstPad * pad)
4371 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4377 /* If we have to close a segment, send a new segment to do this now */
4378 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4379 if (G_UNLIKELY (demux->close_segment)) {
4380 gst_matroska_demux_send_event (demux, demux->close_segment);
4381 demux->close_segment = NULL;
4383 if (G_UNLIKELY (demux->new_segment)) {
4384 gst_matroska_demux_send_event (demux, demux->new_segment);
4385 demux->new_segment = NULL;
4389 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4390 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4391 if (ret == GST_FLOW_EOS)
4393 if (ret != GST_FLOW_OK) {
4394 if (gst_matroska_demux_check_parse_error (demux))
4400 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4401 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4404 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4405 if (ret == GST_FLOW_EOS)
4407 if (ret != GST_FLOW_OK)
4410 /* check if we're at the end of a configured segment */
4411 if (G_LIKELY (demux->common.src->len)) {
4414 g_assert (demux->common.num_streams == demux->common.src->len);
4415 for (i = 0; i < demux->common.src->len; i++) {
4416 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4418 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4419 GST_TIME_ARGS (context->pos));
4420 if (context->eos == FALSE)
4424 GST_INFO_OBJECT (demux, "All streams are EOS");
4430 if (G_UNLIKELY (demux->common.offset ==
4431 gst_matroska_read_common_get_length (&demux->common))) {
4432 GST_LOG_OBJECT (demux, "Reached end of stream");
4442 if (demux->common.segment.rate < 0.0) {
4443 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4444 if (ret == GST_FLOW_OK)
4451 const gchar *reason = gst_flow_get_name (ret);
4452 gboolean push_eos = FALSE;
4454 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4455 demux->segment_running = FALSE;
4456 gst_pad_pause_task (demux->common.sinkpad);
4458 if (ret == GST_FLOW_EOS) {
4459 /* perform EOS logic */
4461 /* If we were in the headers, make sure we send no-more-pads.
4462 This will ensure decodebin2 does not get stuck thinking
4463 the chain is not complete yet, and waiting indefinitely. */
4464 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4465 if (demux->common.src->len == 0) {
4466 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4467 ("No pads created"));
4469 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4470 ("Failed to finish reading headers"));
4472 gst_element_no_more_pads (GST_ELEMENT (demux));
4475 /* Close the segment, i.e. update segment stop with the duration
4476 * if no stop was set */
4477 if (GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
4478 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)) {
4479 GstSegment segment = demux->common.segment;
4482 segment.stop = MAX (demux->last_stop_end, segment.start);
4483 event = gst_event_new_segment (&segment);
4484 gst_matroska_demux_send_event (demux, event);
4487 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4490 /* for segment playback we need to post when (in stream time)
4491 * we stopped, this is either stop (when set) or the duration. */
4492 if ((stop = demux->common.segment.stop) == -1)
4493 stop = demux->last_stop_end;
4495 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4496 gst_element_post_message (GST_ELEMENT (demux),
4497 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4502 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4503 /* for fatal errors we post an error message */
4504 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4505 ("stream stopped, reason %s", reason));
4509 /* send EOS, and prevent hanging if no streams yet */
4510 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4511 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4512 (ret == GST_FLOW_EOS)) {
4513 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4514 (NULL), ("got eos but no streams (yet)"));
4522 * Create and push a flushing seek event upstream
4525 perform_seek_to_offset (GstMatroskaDemux * demux, guint64 offset)
4530 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4533 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
4534 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4535 GST_SEEK_TYPE_NONE, -1);
4537 res = gst_pad_push_event (demux->common.sinkpad, event);
4539 /* segment event will update offset */
4543 static GstFlowReturn
4544 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4546 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4548 GstFlowReturn ret = GST_FLOW_OK;
4553 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4554 GST_DEBUG_OBJECT (demux, "got DISCONT");
4555 gst_adapter_clear (demux->common.adapter);
4556 GST_OBJECT_LOCK (demux);
4557 gst_matroska_read_common_reset_streams (&demux->common,
4558 GST_CLOCK_TIME_NONE, FALSE);
4559 GST_OBJECT_UNLOCK (demux);
4562 gst_adapter_push (demux->common.adapter, buffer);
4566 available = gst_adapter_available (demux->common.adapter);
4568 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4569 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4570 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS))
4573 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4574 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4575 demux->common.offset, id, length, needed, available);
4577 if (needed > available)
4580 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4581 if (ret == GST_FLOW_EOS) {
4582 /* need more data */
4584 } else if (ret != GST_FLOW_OK) {
4591 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4594 gboolean res = TRUE;
4595 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4597 GST_DEBUG_OBJECT (demux,
4598 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4600 switch (GST_EVENT_TYPE (event)) {
4601 case GST_EVENT_SEGMENT:
4603 const GstSegment *segment;
4605 /* some debug output */
4606 gst_event_parse_segment (event, &segment);
4607 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4608 GST_DEBUG_OBJECT (demux,
4609 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4612 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4613 GST_DEBUG_OBJECT (demux, "still starting");
4617 /* we only expect a BYTE segment, e.g. following a seek */
4618 if (segment->format != GST_FORMAT_BYTES) {
4619 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4623 GST_DEBUG_OBJECT (demux, "clearing segment state");
4624 GST_OBJECT_LOCK (demux);
4625 /* clear current segment leftover */
4626 gst_adapter_clear (demux->common.adapter);
4627 /* and some streaming setup */
4628 demux->common.offset = segment->start;
4629 /* do not know where we are;
4630 * need to come across a cluster and generate segment */
4631 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4632 demux->cluster_time = GST_CLOCK_TIME_NONE;
4633 demux->cluster_offset = 0;
4634 demux->need_segment = TRUE;
4635 /* but keep some of the upstream segment */
4636 demux->common.segment.rate = segment->rate;
4637 GST_OBJECT_UNLOCK (demux);
4639 /* chain will send initial segment after pads have been added,
4640 * or otherwise come up with one */
4641 GST_DEBUG_OBJECT (demux, "eating event");
4642 gst_event_unref (event);
4648 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4649 gst_event_unref (event);
4650 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4651 (NULL), ("got eos and didn't receive a complete header object"));
4652 } else if (demux->common.num_streams == 0) {
4653 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4654 (NULL), ("got eos but no streams (yet)"));
4656 gst_matroska_demux_send_event (demux, event);
4660 case GST_EVENT_FLUSH_STOP:
4662 gst_adapter_clear (demux->common.adapter);
4663 GST_OBJECT_LOCK (demux);
4664 gst_matroska_read_common_reset_streams (&demux->common,
4665 GST_CLOCK_TIME_NONE, TRUE);
4666 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4667 demux->cluster_time = GST_CLOCK_TIME_NONE;
4668 demux->cluster_offset = 0;
4669 GST_OBJECT_UNLOCK (demux);
4673 res = gst_pad_event_default (pad, parent, event);
4681 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4683 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4685 gboolean pull_mode = FALSE;
4687 query = gst_query_new_scheduling ();
4689 if (gst_pad_peer_query (sinkpad, query))
4690 pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL);
4692 gst_query_unref (query);
4695 GST_DEBUG ("going to pull mode");
4696 demux->streaming = FALSE;
4697 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4699 GST_DEBUG ("going to push (streaming) mode");
4700 demux->streaming = TRUE;
4701 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4706 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4707 GstPadMode mode, gboolean active)
4709 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4712 case GST_PAD_MODE_PULL:
4714 /* if we have a scheduler we can start the task */
4715 demux->segment_running = TRUE;
4716 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4719 demux->segment_running = FALSE;
4720 gst_pad_stop_task (sinkpad);
4723 case GST_PAD_MODE_PUSH:
4731 gst_duration_to_fraction (guint64 duration, gint * dest_n, gint * dest_d)
4733 static const int common_den[] = { 1, 2, 3, 4, 1001 };
4738 for (i = 0; i < G_N_ELEMENTS (common_den); i++) {
4740 n = floor (0.5 + (d * 1e9) / duration);
4741 a = gst_util_uint64_scale_int (1000000000, d, n);
4742 if (duration >= a - 1 && duration <= a + 1) {
4747 gst_util_double_to_fraction (1e9 / duration, &n, &d);
4756 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4757 videocontext, const gchar * codec_id, guint8 * data, guint size,
4758 gchar ** codec_name, guint32 * riff_fourcc)
4760 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4761 GstCaps *caps = NULL;
4763 g_assert (videocontext != NULL);
4764 g_assert (codec_name != NULL);
4766 context->send_xiph_headers = FALSE;
4767 context->send_flac_headers = FALSE;
4768 context->send_speex_headers = FALSE;
4773 /* TODO: check if we have all codec types from matroska-ids.h
4774 * check if we have to do more special things with codec_private
4777 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4778 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4781 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4782 gst_riff_strf_vids *vids = NULL;
4785 GstBuffer *buf = NULL;
4787 vids = (gst_riff_strf_vids *) data;
4789 /* assure size is big enough */
4791 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4794 if (size < sizeof (gst_riff_strf_vids)) {
4795 vids = g_new (gst_riff_strf_vids, 1);
4796 memcpy (vids, data, size);
4799 /* little-endian -> byte-order */
4800 vids->size = GUINT32_FROM_LE (vids->size);
4801 vids->width = GUINT32_FROM_LE (vids->width);
4802 vids->height = GUINT32_FROM_LE (vids->height);
4803 vids->planes = GUINT16_FROM_LE (vids->planes);
4804 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4805 vids->compression = GUINT32_FROM_LE (vids->compression);
4806 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4807 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4808 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4809 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4810 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4812 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4813 gsize offset = sizeof (gst_riff_strf_vids);
4816 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
4817 size - offset), size - offset);
4821 *riff_fourcc = vids->compression;
4823 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4824 buf, NULL, codec_name);
4827 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4828 GST_FOURCC_ARGS (vids->compression));
4832 gst_buffer_unref (buf);
4834 if (vids != (gst_riff_strf_vids *) data)
4837 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4838 const gchar *format = NULL;
4840 switch (videocontext->fourcc) {
4841 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4842 *codec_name = g_strdup ("Raw planar YUV 4:2:0");
4845 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4846 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
4849 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4850 *codec_name = g_strdup ("Raw packed YUV 4:2:0");
4853 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4854 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
4857 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4858 *codec_name = g_strdup ("Raw packed YUV 4:4:4 with alpha channel");
4863 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
4864 GST_FOURCC_ARGS (videocontext->fourcc));
4868 caps = gst_caps_new_simple ("video/x-raw",
4869 "format", G_TYPE_STRING, format, NULL);
4870 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
4871 caps = gst_caps_new_simple ("video/x-divx",
4872 "divxversion", G_TYPE_INT, 4, NULL);
4873 *codec_name = g_strdup ("MPEG-4 simple profile");
4874 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
4875 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
4877 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4878 "divxversion", G_TYPE_INT, 5, NULL),
4879 gst_structure_new ("video/x-xvid", NULL),
4880 gst_structure_new ("video/mpeg",
4881 "mpegversion", G_TYPE_INT, 4,
4882 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
4884 caps = gst_caps_new_simple ("video/mpeg",
4885 "mpegversion", G_TYPE_INT, 4,
4886 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
4890 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4891 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4892 gst_buffer_unref (priv);
4894 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
4895 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
4897 *codec_name = g_strdup ("MPEG-4 advanced profile");
4898 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
4900 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4901 "divxversion", G_TYPE_INT, 3, NULL),
4902 gst_structure_new ("video/x-msmpeg",
4903 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
4905 caps = gst_caps_new_simple ("video/x-msmpeg",
4906 "msmpegversion", G_TYPE_INT, 43, NULL);
4907 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
4908 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
4909 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
4912 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
4917 caps = gst_caps_new_simple ("video/mpeg",
4918 "systemstream", G_TYPE_BOOLEAN, FALSE,
4919 "mpegversion", G_TYPE_INT, mpegversion, NULL);
4920 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
4921 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
4922 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
4923 caps = gst_caps_new_empty_simple ("image/jpeg");
4924 *codec_name = g_strdup ("Motion-JPEG");
4925 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
4926 caps = gst_caps_new_empty_simple ("video/x-h264");
4930 /* First byte is the version, second is the profile indication, and third
4931 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
4932 * level indication. */
4933 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
4936 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4937 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4938 gst_buffer_unref (priv);
4940 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
4941 "alignment", G_TYPE_STRING, "au", NULL);
4943 GST_WARNING ("No codec data found, assuming output is byte-stream");
4944 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
4947 *codec_name = g_strdup ("H264");
4948 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
4949 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
4950 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
4951 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
4952 gint rmversion = -1;
4954 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
4956 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
4958 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
4960 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
4963 caps = gst_caps_new_simple ("video/x-pn-realvideo",
4964 "rmversion", G_TYPE_INT, rmversion, NULL);
4965 GST_DEBUG ("data:%p, size:0x%x", data, size);
4966 /* We need to extract the extradata ! */
4967 if (data && (size >= 0x22)) {
4972 subformat = GST_READ_UINT32_BE (data + 0x1a);
4973 rformat = GST_READ_UINT32_BE (data + 0x1e);
4976 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
4978 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
4979 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
4980 gst_buffer_unref (priv);
4983 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
4984 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
4985 caps = gst_caps_new_empty_simple ("video/x-theora");
4986 context->send_xiph_headers = TRUE;
4987 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
4988 caps = gst_caps_new_empty_simple ("video/x-dirac");
4989 *codec_name = g_strdup_printf ("Dirac");
4990 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
4991 caps = gst_caps_new_empty_simple ("video/x-vp8");
4992 *codec_name = g_strdup_printf ("On2 VP8");
4994 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5000 GstStructure *structure;
5002 for (i = 0; i < gst_caps_get_size (caps); i++) {
5003 structure = gst_caps_get_structure (caps, i);
5005 /* FIXME: use the real unit here! */
5006 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5007 videocontext->pixel_width,
5008 videocontext->pixel_height,
5009 videocontext->display_width, videocontext->display_height);
5011 /* pixel width and height are the w and h of the video in pixels */
5012 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5013 gint w = videocontext->pixel_width;
5014 gint h = videocontext->pixel_height;
5016 gst_structure_set (structure,
5017 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5020 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5023 if (videocontext->display_width <= 0)
5024 videocontext->display_width = videocontext->pixel_width;
5025 if (videocontext->display_height <= 0)
5026 videocontext->display_height = videocontext->pixel_height;
5028 /* calculate the pixel aspect ratio using the display and pixel w/h */
5029 n = videocontext->display_width * videocontext->pixel_height;
5030 d = videocontext->display_height * videocontext->pixel_width;
5031 GST_DEBUG ("setting PAR to %d/%d", n, d);
5032 gst_structure_set (structure, "pixel-aspect-ratio",
5034 videocontext->display_width * videocontext->pixel_height,
5035 videocontext->display_height * videocontext->pixel_width, NULL);
5038 if (videocontext->default_fps > 0.0) {
5039 GValue fps_double = { 0, };
5040 GValue fps_fraction = { 0, };
5042 g_value_init (&fps_double, G_TYPE_DOUBLE);
5043 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
5044 g_value_set_double (&fps_double, videocontext->default_fps);
5045 g_value_transform (&fps_double, &fps_fraction);
5047 GST_DEBUG ("using default fps %f", videocontext->default_fps);
5049 gst_structure_set_value (structure, "framerate", &fps_fraction);
5050 g_value_unset (&fps_double);
5051 g_value_unset (&fps_fraction);
5052 } else if (context->default_duration > 0) {
5055 gst_duration_to_fraction (context->default_duration, &fps_n, &fps_d);
5057 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5058 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5060 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5061 fps_n, fps_d, NULL);
5063 /* sort of a hack to get most codecs to support,
5064 * even if the default_duration is missing */
5065 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5069 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5070 gst_structure_set (structure, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
5073 gst_caps_do_simplify (caps);
5080 * Some AAC specific code... *sigh*
5081 * FIXME: maybe we should use '15' and code the sample rate explicitly
5082 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5086 aac_rate_idx (gint rate)
5090 else if (75132 <= rate)
5092 else if (55426 <= rate)
5094 else if (46009 <= rate)
5096 else if (37566 <= rate)
5098 else if (27713 <= rate)
5100 else if (23004 <= rate)
5102 else if (18783 <= rate)
5104 else if (13856 <= rate)
5106 else if (11502 <= rate)
5108 else if (9391 <= rate)
5115 aac_profile_idx (const gchar * codec_id)
5119 if (strlen (codec_id) <= 12)
5121 else if (!strncmp (&codec_id[12], "MAIN", 4))
5123 else if (!strncmp (&codec_id[12], "LC", 2))
5125 else if (!strncmp (&codec_id[12], "SSR", 3))
5133 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5136 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5137 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5138 gchar ** codec_name, guint16 * riff_audio_fmt)
5140 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5141 GstCaps *caps = NULL;
5143 g_assert (audiocontext != NULL);
5144 g_assert (codec_name != NULL);
5147 *riff_audio_fmt = 0;
5149 context->send_xiph_headers = FALSE;
5150 context->send_flac_headers = FALSE;
5151 context->send_speex_headers = FALSE;
5153 /* TODO: check if we have all codec types from matroska-ids.h
5154 * check if we have to do more special things with codec_private
5155 * check if we need bitdepth in different places too
5156 * implement channel position magic
5158 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5159 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5160 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5161 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5164 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5165 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5166 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5169 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5171 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5176 caps = gst_caps_new_simple ("audio/mpeg",
5177 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5178 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5179 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5180 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5183 GstAudioFormat format;
5185 sign = (audiocontext->bitdepth != 8);
5186 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5187 endianness = G_BIG_ENDIAN;
5189 endianness = G_LITTLE_ENDIAN;
5191 format = gst_audio_format_build_integer (sign, endianness,
5192 audiocontext->bitdepth, audiocontext->bitdepth);
5194 /* FIXME: Channel mask and reordering */
5195 caps = gst_caps_new_simple ("audio/x-raw",
5196 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5197 "layout", G_TYPE_STRING, "interleaved", NULL);
5199 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5200 audiocontext->bitdepth);
5201 context->alignment = audiocontext->bitdepth / 8;
5202 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5203 const gchar *format;
5204 if (audiocontext->bitdepth == 32)
5208 /* FIXME: Channel mask and reordering */
5209 caps = gst_caps_new_simple ("audio/x-raw",
5210 "format", G_TYPE_STRING, format,
5211 "layout", G_TYPE_STRING, "interleaved", NULL);
5212 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5213 audiocontext->bitdepth);
5214 context->alignment = audiocontext->bitdepth / 8;
5215 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5216 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5217 caps = gst_caps_new_simple ("audio/x-ac3",
5218 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5219 *codec_name = g_strdup ("AC-3 audio");
5220 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5221 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5222 caps = gst_caps_new_simple ("audio/x-eac3",
5223 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5224 *codec_name = g_strdup ("E-AC-3 audio");
5225 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5226 caps = gst_caps_new_empty_simple ("audio/x-dts");
5227 *codec_name = g_strdup ("DTS audio");
5228 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5229 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5230 context->send_xiph_headers = TRUE;
5231 /* vorbis decoder does tags */
5232 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5233 caps = gst_caps_new_empty_simple ("audio/x-flac");
5234 context->send_flac_headers = TRUE;
5235 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5236 caps = gst_caps_new_empty_simple ("audio/x-speex");
5237 context->send_speex_headers = TRUE;
5238 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5239 gst_riff_strf_auds auds;
5242 GstBuffer *codec_data;
5244 /* little-endian -> byte-order */
5245 auds.format = GST_READ_UINT16_LE (data);
5246 auds.channels = GST_READ_UINT16_LE (data + 2);
5247 auds.rate = GST_READ_UINT32_LE (data + 4);
5248 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5249 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5250 auds.size = GST_READ_UINT16_LE (data + 16);
5252 /* 18 is the waveformatex size */
5253 codec_data = gst_buffer_new_wrapped_full (data + 18, NULL, 0, auds.size);
5256 *riff_audio_fmt = auds.format;
5258 /* FIXME: Handle reorder map */
5259 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5260 codec_data, codec_name, NULL);
5261 gst_buffer_unref (codec_data);
5264 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5267 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5268 GstBuffer *priv = NULL;
5270 gint rate_idx, profile;
5271 guint8 *data = NULL;
5273 /* unspecified AAC profile with opaque private codec data */
5274 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5275 if (context->codec_priv_size >= 2) {
5276 guint obj_type, freq_index, explicit_freq_bytes = 0;
5278 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5280 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5281 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5282 if (freq_index == 15)
5283 explicit_freq_bytes = 3;
5284 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5285 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5286 context->codec_priv_size), context->codec_priv_size);
5287 /* assume SBR if samplerate <= 24kHz */
5288 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5289 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5290 audiocontext->samplerate *= 2;
5293 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5294 /* this is pretty broken;
5295 * maybe we need to make up some default private,
5296 * or maybe ADTS data got dumped in.
5297 * Let's set up some private data now, and check actual data later */
5298 /* just try this and see what happens ... */
5299 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5300 context->postprocess_frame = gst_matroska_demux_check_aac;
5304 /* make up decoder-specific data if it is not supplied */
5306 priv = gst_buffer_new_allocate (NULL, 5, 0);
5307 data = gst_buffer_map (priv, NULL, NULL, GST_MAP_WRITE);
5308 rate_idx = aac_rate_idx (audiocontext->samplerate);
5309 profile = aac_profile_idx (codec_id);
5311 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5312 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5314 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5315 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5317 gst_buffer_unmap (priv, data, 5);
5318 gst_buffer_set_size (priv, 2);
5319 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5320 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5323 if (g_strrstr (codec_id, "SBR")) {
5324 /* HE-AAC (aka SBR AAC) */
5325 audiocontext->samplerate *= 2;
5326 rate_idx = aac_rate_idx (audiocontext->samplerate);
5327 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5328 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5329 data[4] = (1 << 7) | (rate_idx << 3);
5330 gst_buffer_unmap (priv, data, 5);
5332 gst_buffer_unmap (priv, data, 5);
5333 gst_buffer_set_size (priv, 2);
5336 gst_buffer_unmap (priv, data, 5);
5337 gst_buffer_unref (priv);
5339 GST_ERROR ("Unknown AAC profile and no codec private data");
5344 caps = gst_caps_new_simple ("audio/mpeg",
5345 "mpegversion", G_TYPE_INT, mpegversion,
5346 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5347 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5348 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5349 gst_buffer_unref (priv);
5351 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5352 caps = gst_caps_new_simple ("audio/x-tta",
5353 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5354 *codec_name = g_strdup ("TTA audio");
5355 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5356 caps = gst_caps_new_simple ("audio/x-wavpack",
5357 "width", G_TYPE_INT, audiocontext->bitdepth,
5358 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5359 *codec_name = g_strdup ("Wavpack audio");
5360 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5361 audiocontext->wvpk_block_index = 0;
5362 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5363 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5364 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5365 gint raversion = -1;
5367 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5369 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5374 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5375 "raversion", G_TYPE_INT, raversion, NULL);
5376 /* Extract extra information from caps, mapping varies based on codec */
5377 if (data && (size >= 0x50)) {
5384 guint extra_data_size;
5386 GST_ERROR ("real audio raversion:%d", raversion);
5387 if (raversion == 8) {
5389 flavor = GST_READ_UINT16_BE (data + 22);
5390 packet_size = GST_READ_UINT32_BE (data + 24);
5391 height = GST_READ_UINT16_BE (data + 40);
5392 leaf_size = GST_READ_UINT16_BE (data + 44);
5393 sample_width = GST_READ_UINT16_BE (data + 58);
5394 extra_data_size = GST_READ_UINT32_BE (data + 74);
5397 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5398 flavor, packet_size, height, leaf_size, sample_width,
5400 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5401 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5402 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5404 if ((size - 78) >= extra_data_size) {
5405 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5407 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5408 gst_buffer_unref (priv);
5413 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5414 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5415 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5416 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5417 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5418 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5419 *codec_name = g_strdup ("Real Audio Lossless");
5420 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5421 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5422 *codec_name = g_strdup ("Sony ATRAC3");
5424 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5429 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5432 for (i = 0; i < gst_caps_get_size (caps); i++) {
5433 gst_structure_set (gst_caps_get_structure (caps, i),
5434 "channels", G_TYPE_INT, audiocontext->channels,
5435 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5439 gst_caps_do_simplify (caps);
5446 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5447 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5449 GstCaps *caps = NULL;
5450 GstMatroskaTrackContext *context =
5451 (GstMatroskaTrackContext *) subtitlecontext;
5453 /* for backwards compatibility */
5454 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5455 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5456 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5457 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5458 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5459 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5460 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5461 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5463 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5464 * Check if we have to do something with codec_private */
5465 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5466 /* well, plain text simply does not have a lot of markup ... */
5467 caps = gst_caps_new_empty_simple ("text/x-pango-markup");
5468 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5469 subtitlecontext->check_markup = TRUE;
5470 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5471 caps = gst_caps_new_empty_simple ("application/x-ssa");
5472 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5473 subtitlecontext->check_markup = FALSE;
5474 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5475 caps = gst_caps_new_empty_simple ("application/x-ass");
5476 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5477 subtitlecontext->check_markup = FALSE;
5478 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5479 caps = gst_caps_new_empty_simple ("application/x-usf");
5480 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5481 subtitlecontext->check_markup = FALSE;
5482 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5483 caps = gst_caps_new_empty_simple ("video/x-dvd-subpicture");
5484 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5485 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5486 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5487 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5488 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5489 context->send_xiph_headers = TRUE;
5491 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5492 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5495 if (data != NULL && size > 0) {
5498 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5499 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5500 gst_buffer_unref (buf);
5508 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5510 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5512 GST_OBJECT_LOCK (demux);
5513 if (demux->common.element_index)
5514 gst_object_unref (demux->common.element_index);
5515 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5516 GST_OBJECT_UNLOCK (demux);
5517 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5518 demux->common.element_index);
5522 gst_matroska_demux_get_index (GstElement * element)
5524 GstIndex *result = NULL;
5525 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5527 GST_OBJECT_LOCK (demux);
5528 if (demux->common.element_index)
5529 result = gst_object_ref (demux->common.element_index);
5530 GST_OBJECT_UNLOCK (demux);
5532 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5538 static GstStateChangeReturn
5539 gst_matroska_demux_change_state (GstElement * element,
5540 GstStateChange transition)
5542 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5543 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5545 /* handle upwards state changes here */
5546 switch (transition) {
5551 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5553 /* handle downwards state changes */
5554 switch (transition) {
5555 case GST_STATE_CHANGE_PAUSED_TO_READY:
5556 gst_matroska_demux_reset (GST_ELEMENT (demux));
5566 gst_matroska_demux_set_property (GObject * object,
5567 guint prop_id, const GValue * value, GParamSpec * pspec)
5569 GstMatroskaDemux *demux;
5571 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5572 demux = GST_MATROSKA_DEMUX (object);
5575 case ARG_MAX_GAP_TIME:
5576 GST_OBJECT_LOCK (demux);
5577 demux->max_gap_time = g_value_get_uint64 (value);
5578 GST_OBJECT_UNLOCK (demux);
5581 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5587 gst_matroska_demux_get_property (GObject * object,
5588 guint prop_id, GValue * value, GParamSpec * pspec)
5590 GstMatroskaDemux *demux;
5592 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5593 demux = GST_MATROSKA_DEMUX (object);
5596 case ARG_MAX_GAP_TIME:
5597 GST_OBJECT_LOCK (demux);
5598 g_value_set_uint64 (value, demux->max_gap_time);
5599 GST_OBJECT_UNLOCK (demux);
5602 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5608 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5612 /* parser helper separate debug */
5613 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5614 0, "EBML stream helper class");
5616 /* create an elementfactory for the matroska_demux element */
5617 if (!gst_element_register (plugin, "matroskademux",
5618 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))