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.
52 /* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex
53 * with newer GLib versions (>= 2.31.0) */
54 #define GLIB_DISABLE_DEPRECATION_WARNINGS
58 #include <glib/gprintf.h>
60 /* For AVI compatibility mode
61 and for fourcc stuff */
62 #include <gst/riff/riff-read.h>
63 #include <gst/riff/riff-ids.h>
64 #include <gst/riff/riff-media.h>
66 #include <gst/tag/tag.h>
68 #include <gst/pbutils/pbutils.h>
70 #include "matroska-demux.h"
71 #include "matroska-ids.h"
73 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
74 #define GST_CAT_DEFAULT matroskademux_debug
76 #define DEBUG_ELEMENT_START(demux, ebml, element) \
77 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
78 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
80 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
81 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
82 " finished with '%s'", gst_flow_get_name (ret))
92 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
94 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
97 GST_STATIC_CAPS ("video/x-matroska; video/webm")
100 /* TODO: fill in caps! */
102 static GstStaticPadTemplate audio_src_templ =
103 GST_STATIC_PAD_TEMPLATE ("audio_%02d",
106 GST_STATIC_CAPS ("ANY")
109 static GstStaticPadTemplate video_src_templ =
110 GST_STATIC_PAD_TEMPLATE ("video_%02d",
113 GST_STATIC_CAPS ("ANY")
116 static GstStaticPadTemplate subtitle_src_templ =
117 GST_STATIC_PAD_TEMPLATE ("subtitle_%02d",
120 GST_STATIC_CAPS ("text/x-pango-markup; application/x-ssa; "
121 "application/x-ass;application/x-usf; video/x-dvd-subpicture; "
122 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
125 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
126 guint32 id, guint64 length, guint needed);
128 /* element functions */
129 static void gst_matroska_demux_loop (GstPad * pad);
131 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
133 static gboolean gst_matroska_demux_element_query (GstElement * element,
137 static gboolean gst_matroska_demux_sink_activate_pull (GstPad * sinkpad,
139 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad);
141 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
142 GstPad * pad, GstEvent * event);
143 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
145 static const GstQueryType *gst_matroska_demux_get_src_query_types (GstPad *
147 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
150 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
152 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
155 static GstStateChangeReturn
156 gst_matroska_demux_change_state (GstElement * element,
157 GstStateChange transition);
159 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
160 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
163 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
164 * videocontext, const gchar * codec_id, guint8 * data, guint size,
165 gchar ** codec_name, guint32 * riff_fourcc);
166 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
167 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
168 gchar ** codec_name, guint16 * riff_audio_fmt);
170 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
171 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
174 static void gst_matroska_demux_reset (GstElement * element);
175 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
178 /* gobject functions */
179 static void gst_matroska_demux_set_property (GObject * object,
180 guint prop_id, const GValue * value, GParamSpec * pspec);
181 static void gst_matroska_demux_get_property (GObject * object,
182 guint prop_id, GValue * value, GParamSpec * pspec);
184 GType gst_matroska_demux_get_type (void);
185 GST_BOILERPLATE (GstMatroskaDemux, gst_matroska_demux, GstElement,
189 gst_matroska_demux_base_init (gpointer klass)
191 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
193 gst_element_class_add_static_pad_template (element_class, &video_src_templ);
194 gst_element_class_add_static_pad_template (element_class, &audio_src_templ);
195 gst_element_class_add_static_pad_template (element_class,
196 &subtitle_src_templ);
197 gst_element_class_add_static_pad_template (element_class, &sink_templ);
199 gst_element_class_set_details_simple (element_class, "Matroska demuxer",
201 "Demuxes Matroska/WebM streams into video/audio/subtitles",
202 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
206 gst_matroska_demux_finalize (GObject * object)
208 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
210 if (demux->common.src) {
211 g_ptr_array_free (demux->common.src, TRUE);
212 demux->common.src = NULL;
215 if (demux->common.global_tags) {
216 gst_tag_list_free (demux->common.global_tags);
217 demux->common.global_tags = NULL;
220 g_object_unref (demux->common.adapter);
222 G_OBJECT_CLASS (parent_class)->finalize (object);
226 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
228 GObjectClass *gobject_class = (GObjectClass *) klass;
229 GstElementClass *gstelement_class = (GstElementClass *) klass;
231 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
234 gobject_class->finalize = gst_matroska_demux_finalize;
236 gobject_class->get_property = gst_matroska_demux_get_property;
237 gobject_class->set_property = gst_matroska_demux_set_property;
239 g_object_class_install_property (gobject_class, ARG_MAX_GAP_TIME,
240 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
241 "The demuxer sends out newsegment events for skipping "
242 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
243 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
245 gstelement_class->change_state =
246 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
247 gstelement_class->send_event =
248 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
249 gstelement_class->query =
250 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
252 gstelement_class->set_index =
253 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
254 gstelement_class->get_index =
255 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
259 gst_matroska_demux_init (GstMatroskaDemux * demux,
260 GstMatroskaDemuxClass * klass)
262 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
264 gst_pad_set_activate_function (demux->common.sinkpad,
265 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
266 gst_pad_set_activatepull_function (demux->common.sinkpad,
267 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_pull));
268 gst_pad_set_chain_function (demux->common.sinkpad,
269 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
270 gst_pad_set_event_function (demux->common.sinkpad,
271 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
272 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
274 /* initial stream no. */
275 demux->common.src = NULL;
277 demux->common.writing_app = NULL;
278 demux->common.muxing_app = NULL;
279 demux->common.index = NULL;
280 demux->common.global_tags = NULL;
282 demux->common.adapter = gst_adapter_new ();
284 /* property defaults */
285 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
288 gst_matroska_demux_reset (GST_ELEMENT (demux));
292 gst_matroska_track_free (GstMatroskaTrackContext * track)
294 g_free (track->codec_id);
295 g_free (track->codec_name);
296 g_free (track->name);
297 g_free (track->language);
298 g_free (track->codec_priv);
299 g_free (track->codec_state);
301 if (track->encodings != NULL) {
304 for (i = 0; i < track->encodings->len; ++i) {
305 GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
306 GstMatroskaTrackEncoding,
309 g_free (enc->comp_settings);
311 g_array_free (track->encodings, TRUE);
314 if (track->pending_tags)
315 gst_tag_list_free (track->pending_tags);
317 if (track->index_table)
318 g_array_free (track->index_table, TRUE);
324 * Returns the aggregated GstFlowReturn.
327 gst_matroska_demux_combine_flows (GstMatroskaDemux * demux,
328 GstMatroskaTrackContext * track, GstFlowReturn ret)
332 /* store the value */
333 track->last_flow = ret;
335 /* any other error that is not-linked can be returned right away */
336 if (ret != GST_FLOW_NOT_LINKED)
339 /* only return NOT_LINKED if all other pads returned NOT_LINKED */
340 g_assert (demux->common.src->len == demux->common.num_streams);
341 for (i = 0; i < demux->common.src->len; i++) {
342 GstMatroskaTrackContext *ostream = g_ptr_array_index (demux->common.src,
348 ret = ostream->last_flow;
349 /* some other return value (must be SUCCESS but we can return
350 * other values as well) */
351 if (ret != GST_FLOW_NOT_LINKED)
354 /* if we get here, all other pads were unlinked and we return
357 GST_LOG_OBJECT (demux, "combined return %s", gst_flow_get_name (ret));
362 gst_matroska_demux_free_parsed_el (gpointer mem, gpointer user_data)
364 g_slice_free (guint64, mem);
368 gst_matroska_demux_reset (GstElement * element)
370 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
373 GST_DEBUG_OBJECT (demux, "Resetting state");
376 demux->common.state = GST_MATROSKA_READ_STATE_START;
378 /* clean up existing streams */
379 if (demux->common.src) {
380 g_assert (demux->common.src->len == demux->common.num_streams);
381 for (i = 0; i < demux->common.src->len; i++) {
382 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
385 if (context->pad != NULL)
386 gst_element_remove_pad (GST_ELEMENT (demux), context->pad);
388 gst_caps_replace (&context->caps, NULL);
389 gst_matroska_track_free (context);
391 g_ptr_array_free (demux->common.src, TRUE);
393 demux->common.src = g_ptr_array_new ();
395 demux->common.num_streams = 0;
396 demux->num_a_streams = 0;
397 demux->num_t_streams = 0;
398 demux->num_v_streams = 0;
400 /* reset media info */
401 g_free (demux->common.writing_app);
402 demux->common.writing_app = NULL;
403 g_free (demux->common.muxing_app);
404 demux->common.muxing_app = NULL;
407 if (demux->common.index) {
408 g_array_free (demux->common.index, TRUE);
409 demux->common.index = NULL;
412 if (demux->clusters) {
413 g_array_free (demux->clusters, TRUE);
414 demux->clusters = NULL;
419 demux->common.time_scale = 1000000;
420 demux->common.created = G_MININT64;
422 demux->common.index_parsed = FALSE;
423 demux->tracks_parsed = FALSE;
424 demux->common.segmentinfo_parsed = FALSE;
425 demux->common.attachments_parsed = FALSE;
427 g_list_foreach (demux->common.tags_parsed,
428 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
429 g_list_free (demux->common.tags_parsed);
430 demux->common.tags_parsed = NULL;
432 g_list_foreach (demux->seek_parsed,
433 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
434 g_list_free (demux->seek_parsed);
435 demux->seek_parsed = NULL;
437 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
438 demux->last_stop_end = GST_CLOCK_TIME_NONE;
439 demux->seek_block = 0;
440 demux->stream_start_time = GST_CLOCK_TIME_NONE;
442 demux->common.offset = 0;
443 demux->cluster_time = GST_CLOCK_TIME_NONE;
444 demux->cluster_offset = 0;
445 demux->next_cluster_offset = 0;
446 demux->index_offset = 0;
447 demux->seekable = FALSE;
448 demux->need_newsegment = FALSE;
449 demux->building_index = FALSE;
450 if (demux->seek_event) {
451 gst_event_unref (demux->seek_event);
452 demux->seek_event = NULL;
455 demux->seek_index = NULL;
456 demux->seek_entry = 0;
458 if (demux->close_segment) {
459 gst_event_unref (demux->close_segment);
460 demux->close_segment = NULL;
463 if (demux->new_segment) {
464 gst_event_unref (demux->new_segment);
465 demux->new_segment = NULL;
468 if (demux->common.element_index) {
469 gst_object_unref (demux->common.element_index);
470 demux->common.element_index = NULL;
472 demux->common.element_index_writer_id = -1;
474 if (demux->common.global_tags) {
475 gst_tag_list_free (demux->common.global_tags);
477 demux->common.global_tags = gst_tag_list_new ();
479 if (demux->common.cached_buffer) {
480 gst_buffer_unref (demux->common.cached_buffer);
481 demux->common.cached_buffer = NULL;
484 demux->invalid_duration = FALSE;
488 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
494 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
496 GST_DEBUG ("decoding buffer %p", buf);
498 data = GST_BUFFER_DATA (buf);
499 size = GST_BUFFER_SIZE (buf);
501 g_return_val_if_fail (data != NULL && size > 0, buf);
503 if (gst_matroska_decode_data (context->encodings, &data, &size,
504 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
505 new_buf = gst_buffer_new ();
506 GST_BUFFER_MALLOCDATA (new_buf) = (guint8 *) data;
507 GST_BUFFER_DATA (new_buf) = (guint8 *) data;
508 GST_BUFFER_SIZE (new_buf) = size;
510 gst_buffer_unref (buf);
515 GST_DEBUG ("decode data failed");
516 gst_buffer_unref (buf);
522 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
524 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
525 GstMatroskaTrackContext *context;
526 GstPadTemplate *templ = NULL;
527 GstCaps *caps = NULL;
528 gchar *padname = NULL;
530 guint32 id, riff_fourcc = 0;
531 guint16 riff_audio_fmt = 0;
532 GstTagList *list = NULL;
535 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
537 /* start with the master */
538 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
539 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
543 /* allocate generic... if we know the type, we'll g_renew()
544 * with the precise type */
545 context = g_new0 (GstMatroskaTrackContext, 1);
546 g_ptr_array_add (demux->common.src, context);
547 context->index = demux->common.num_streams;
548 context->index_writer_id = -1;
549 context->type = 0; /* no type yet */
550 context->default_duration = 0;
552 context->set_discont = TRUE;
553 context->timecodescale = 1.0;
555 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
556 GST_MATROSKA_TRACK_LACING;
557 context->last_flow = GST_FLOW_OK;
558 context->to_offset = G_MAXINT64;
559 context->alignment = 1;
560 demux->common.num_streams++;
561 g_assert (demux->common.src->len == demux->common.num_streams);
563 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
565 /* try reading the trackentry headers */
566 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
567 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
571 /* track number (unique stream ID) */
572 case GST_MATROSKA_ID_TRACKNUMBER:{
575 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
579 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
580 ret = GST_FLOW_ERROR;
582 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
584 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
585 " is not unique", num);
586 ret = GST_FLOW_ERROR;
590 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
594 /* track UID (unique identifier) */
595 case GST_MATROSKA_ID_TRACKUID:{
598 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
602 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
603 ret = GST_FLOW_ERROR;
607 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
612 /* track type (video, audio, combined, subtitle, etc.) */
613 case GST_MATROSKA_ID_TRACKTYPE:{
616 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
620 if (context->type != 0 && context->type != track_type) {
621 GST_WARNING_OBJECT (demux,
622 "More than one tracktype defined in a TrackEntry - skipping");
624 } else if (track_type < 1 || track_type > 254) {
625 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
630 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
632 /* ok, so we're actually going to reallocate this thing */
633 switch (track_type) {
634 case GST_MATROSKA_TRACK_TYPE_VIDEO:
635 gst_matroska_track_init_video_context (&context);
637 case GST_MATROSKA_TRACK_TYPE_AUDIO:
638 gst_matroska_track_init_audio_context (&context);
640 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
641 gst_matroska_track_init_subtitle_context (&context);
643 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
644 case GST_MATROSKA_TRACK_TYPE_LOGO:
645 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
646 case GST_MATROSKA_TRACK_TYPE_CONTROL:
648 GST_WARNING_OBJECT (demux,
649 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
654 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
659 /* tracktype specific stuff for video */
660 case GST_MATROSKA_ID_TRACKVIDEO:{
661 GstMatroskaTrackVideoContext *videocontext;
663 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
665 if (!gst_matroska_track_init_video_context (&context)) {
666 GST_WARNING_OBJECT (demux,
667 "TrackVideo element in non-video track - ignoring track");
668 ret = GST_FLOW_ERROR;
670 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
673 videocontext = (GstMatroskaTrackVideoContext *) context;
674 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
677 while (ret == GST_FLOW_OK &&
678 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
679 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
683 /* Should be one level up but some broken muxers write it here. */
684 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
687 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
691 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
695 GST_DEBUG_OBJECT (demux,
696 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
697 context->default_duration = num;
701 /* video framerate */
702 /* NOTE: This one is here only for backward compatibility.
703 * Use _TRACKDEFAULDURATION one level up. */
704 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
707 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
711 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
715 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
716 if (context->default_duration == 0)
717 context->default_duration =
718 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
719 videocontext->default_fps = num;
723 /* width of the size to display the video at */
724 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
727 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
731 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
735 GST_DEBUG_OBJECT (demux,
736 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
737 videocontext->display_width = num;
741 /* height of the size to display the video at */
742 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
745 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
749 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
753 GST_DEBUG_OBJECT (demux,
754 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
755 videocontext->display_height = num;
759 /* width of the video in the file */
760 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
763 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
767 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
771 GST_DEBUG_OBJECT (demux,
772 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
773 videocontext->pixel_width = num;
777 /* height of the video in the file */
778 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
781 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
785 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
789 GST_DEBUG_OBJECT (demux,
790 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
791 videocontext->pixel_height = num;
795 /* whether the video is interlaced */
796 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
799 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
803 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
805 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
806 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
807 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
812 /* aspect ratio behaviour */
813 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
816 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
819 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
820 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
821 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
822 GST_WARNING_OBJECT (demux,
823 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
826 GST_DEBUG_OBJECT (demux,
827 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
828 videocontext->asr_mode = num;
832 /* colourspace (only matters for raw video) fourcc */
833 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
838 gst_ebml_read_binary (ebml, &id, &data,
839 &datalen)) != GST_FLOW_OK)
844 GST_WARNING_OBJECT (demux,
845 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
850 memcpy (&videocontext->fourcc, data, 4);
851 GST_DEBUG_OBJECT (demux,
852 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
853 GST_FOURCC_ARGS (videocontext->fourcc));
859 GST_WARNING_OBJECT (demux,
860 "Unknown TrackVideo subelement 0x%x - ignoring", id);
862 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
863 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
864 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
865 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
866 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
867 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
868 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
869 ret = gst_ebml_read_skip (ebml);
874 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
878 /* tracktype specific stuff for audio */
879 case GST_MATROSKA_ID_TRACKAUDIO:{
880 GstMatroskaTrackAudioContext *audiocontext;
882 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
884 if (!gst_matroska_track_init_audio_context (&context)) {
885 GST_WARNING_OBJECT (demux,
886 "TrackAudio element in non-audio track - ignoring track");
887 ret = GST_FLOW_ERROR;
891 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
894 audiocontext = (GstMatroskaTrackAudioContext *) context;
895 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
898 while (ret == GST_FLOW_OK &&
899 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
900 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
905 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
908 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
913 GST_WARNING_OBJECT (demux,
914 "Invalid TrackAudioSamplingFrequency %lf", num);
918 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
919 audiocontext->samplerate = num;
924 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
927 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
931 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
935 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
937 audiocontext->bitdepth = num;
942 case GST_MATROSKA_ID_AUDIOCHANNELS:{
945 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
949 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
953 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
955 audiocontext->channels = num;
960 GST_WARNING_OBJECT (demux,
961 "Unknown TrackAudio subelement 0x%x - ignoring", id);
963 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
964 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
965 ret = gst_ebml_read_skip (ebml);
970 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
975 /* codec identifier */
976 case GST_MATROSKA_ID_CODECID:{
979 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
982 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
983 context->codec_id = text;
987 /* codec private data */
988 case GST_MATROSKA_ID_CODECPRIVATE:{
993 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
996 context->codec_priv = data;
997 context->codec_priv_size = size;
999 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1004 /* name of the codec */
1005 case GST_MATROSKA_ID_CODECNAME:{
1008 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1011 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1012 context->codec_name = text;
1016 /* name of this track */
1017 case GST_MATROSKA_ID_TRACKNAME:{
1020 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1023 context->name = text;
1024 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1028 /* language (matters for audio/subtitles, mostly) */
1029 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1032 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1036 context->language = text;
1039 if (strlen (context->language) >= 4 && context->language[3] == '-')
1040 context->language[3] = '\0';
1042 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1043 GST_STR_NULL (context->language));
1047 /* whether this is actually used */
1048 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1051 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1055 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1057 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1059 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1060 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1064 /* whether it's the default for this track type */
1065 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1068 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1072 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1074 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1076 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1077 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1081 /* whether the track must be used during playback */
1082 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1085 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1089 context->flags |= GST_MATROSKA_TRACK_FORCED;
1091 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1093 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1094 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1098 /* lacing (like MPEG, where blocks don't end/start on frame
1100 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1103 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1107 context->flags |= GST_MATROSKA_TRACK_LACING;
1109 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1111 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1112 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1116 /* default length (in time) of one data block in this track */
1117 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1120 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1125 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1129 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1131 context->default_duration = num;
1135 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1136 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1141 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1144 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1148 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1152 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1153 context->timecodescale = num;
1158 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1161 /* we ignore these because they're nothing useful (i.e. crap)
1162 * or simply not implemented yet. */
1163 case GST_MATROSKA_ID_TRACKMINCACHE:
1164 case GST_MATROSKA_ID_TRACKMAXCACHE:
1165 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1166 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1167 case GST_MATROSKA_ID_TRACKOVERLAY:
1168 case GST_MATROSKA_ID_TRACKTRANSLATE:
1169 case GST_MATROSKA_ID_TRACKOFFSET:
1170 case GST_MATROSKA_ID_CODECSETTINGS:
1171 case GST_MATROSKA_ID_CODECINFOURL:
1172 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1173 case GST_MATROSKA_ID_CODECDECODEALL:
1174 ret = gst_ebml_read_skip (ebml);
1179 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1181 /* Decode codec private data if necessary */
1182 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1183 && context->codec_priv_size > 0) {
1184 if (!gst_matroska_decode_data (context->encodings,
1185 &context->codec_priv, &context->codec_priv_size,
1186 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1187 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1188 ret = GST_FLOW_ERROR;
1192 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1193 && ret != GST_FLOW_UNEXPECTED)) {
1194 if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
1195 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1197 demux->common.num_streams--;
1198 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1199 g_assert (demux->common.src->len == demux->common.num_streams);
1201 gst_matroska_track_free (context);
1207 /* now create the GStreamer connectivity */
1208 switch (context->type) {
1209 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1210 GstMatroskaTrackVideoContext *videocontext =
1211 (GstMatroskaTrackVideoContext *) context;
1213 padname = g_strdup_printf ("video_%02d", demux->num_v_streams++);
1214 templ = gst_element_class_get_pad_template (klass, "video_%02d");
1215 caps = gst_matroska_demux_video_caps (videocontext,
1216 context->codec_id, (guint8 *) context->codec_priv,
1217 context->codec_priv_size, &codec, &riff_fourcc);
1220 list = gst_tag_list_new ();
1221 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1222 GST_TAG_VIDEO_CODEC, codec, NULL);
1228 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1229 GstMatroskaTrackAudioContext *audiocontext =
1230 (GstMatroskaTrackAudioContext *) context;
1232 padname = g_strdup_printf ("audio_%02d", demux->num_a_streams++);
1233 templ = gst_element_class_get_pad_template (klass, "audio_%02d");
1234 caps = gst_matroska_demux_audio_caps (audiocontext,
1235 context->codec_id, context->codec_priv, context->codec_priv_size,
1236 &codec, &riff_audio_fmt);
1239 list = gst_tag_list_new ();
1240 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1241 GST_TAG_AUDIO_CODEC, codec, NULL);
1247 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1248 GstMatroskaTrackSubtitleContext *subtitlecontext =
1249 (GstMatroskaTrackSubtitleContext *) context;
1251 padname = g_strdup_printf ("subtitle_%02d", demux->num_t_streams++);
1252 templ = gst_element_class_get_pad_template (klass, "subtitle_%02d");
1253 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1254 context->codec_id, context->codec_priv, context->codec_priv_size);
1258 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1259 case GST_MATROSKA_TRACK_TYPE_LOGO:
1260 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1261 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1263 /* we should already have quit by now */
1264 g_assert_not_reached ();
1267 if ((context->language == NULL || *context->language == '\0') &&
1268 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1269 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1270 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1271 context->language = g_strdup ("eng");
1274 if (context->language) {
1278 list = gst_tag_list_new ();
1280 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1281 lang = gst_tag_get_language_code (context->language);
1282 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1283 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1287 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1288 "codec_id='%s'", context->codec_id);
1289 switch (context->type) {
1290 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1291 caps = gst_caps_new_simple ("video/x-unknown", NULL);
1293 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1294 caps = gst_caps_new_simple ("audio/x-unknown", NULL);
1296 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1297 caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
1299 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1301 caps = gst_caps_new_simple ("application/x-matroska-unknown", NULL);
1304 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1307 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1308 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1309 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1310 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0)
1311 gst_caps_set_simple (caps, "fourcc", GST_TYPE_FOURCC, riff_fourcc, NULL);
1314 /* the pad in here */
1315 context->pad = gst_pad_new_from_template (templ, padname);
1316 context->caps = caps;
1318 gst_pad_set_event_function (context->pad,
1319 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1320 gst_pad_set_query_type_function (context->pad,
1321 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_src_query_types));
1322 gst_pad_set_query_function (context->pad,
1323 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1325 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1328 context->pending_tags = list;
1330 gst_pad_set_element_private (context->pad, context);
1332 gst_pad_use_fixed_caps (context->pad);
1333 gst_pad_set_caps (context->pad, context->caps);
1334 gst_pad_set_active (context->pad, TRUE);
1335 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1343 static const GstQueryType *
1344 gst_matroska_demux_get_src_query_types (GstPad * pad)
1346 static const GstQueryType query_types[] = {
1357 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1360 gboolean res = FALSE;
1361 GstMatroskaTrackContext *context = NULL;
1364 context = gst_pad_get_element_private (pad);
1367 switch (GST_QUERY_TYPE (query)) {
1368 case GST_QUERY_POSITION:
1372 gst_query_parse_position (query, &format, NULL);
1374 if (format == GST_FORMAT_TIME) {
1375 GST_OBJECT_LOCK (demux);
1377 gst_query_set_position (query, GST_FORMAT_TIME,
1378 MAX (context->pos, demux->stream_start_time) -
1379 demux->stream_start_time);
1381 gst_query_set_position (query, GST_FORMAT_TIME,
1382 MAX (demux->common.segment.last_stop, demux->stream_start_time) -
1383 demux->stream_start_time);
1384 GST_OBJECT_UNLOCK (demux);
1385 } else if (format == GST_FORMAT_DEFAULT && context
1386 && context->default_duration) {
1387 GST_OBJECT_LOCK (demux);
1388 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1389 context->pos / context->default_duration);
1390 GST_OBJECT_UNLOCK (demux);
1392 GST_DEBUG_OBJECT (demux,
1393 "only position query in TIME and DEFAULT format is supported");
1399 case GST_QUERY_DURATION:
1403 gst_query_parse_duration (query, &format, NULL);
1405 if (format == GST_FORMAT_TIME) {
1406 GST_OBJECT_LOCK (demux);
1407 gst_query_set_duration (query, GST_FORMAT_TIME,
1408 demux->common.segment.duration);
1409 GST_OBJECT_UNLOCK (demux);
1410 } else if (format == GST_FORMAT_DEFAULT && context
1411 && context->default_duration) {
1412 GST_OBJECT_LOCK (demux);
1413 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1414 demux->common.segment.duration / context->default_duration);
1415 GST_OBJECT_UNLOCK (demux);
1417 GST_DEBUG_OBJECT (demux,
1418 "only duration query in TIME and DEFAULT format is supported");
1425 case GST_QUERY_SEEKING:
1429 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1430 GST_OBJECT_LOCK (demux);
1431 if (fmt == GST_FORMAT_TIME) {
1434 if (demux->streaming) {
1435 /* assuming we'll be able to get an index ... */
1436 seekable = demux->seekable;
1441 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1442 0, demux->common.segment.duration);
1445 GST_OBJECT_UNLOCK (demux);
1449 res = gst_pad_query_default (pad, query);
1457 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1459 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1463 gst_matroska_demux_handle_src_query (GstPad * pad, GstQuery * query)
1466 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
1468 ret = gst_matroska_demux_query (demux, pad, query);
1470 gst_object_unref (demux);
1475 /* returns FALSE if there are no pads to deliver event to,
1476 * otherwise TRUE (whatever the outcome of event sending),
1477 * takes ownership of the passed event! */
1479 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1481 gboolean is_newsegment;
1482 gboolean ret = FALSE;
1485 g_return_val_if_fail (event != NULL, FALSE);
1487 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1488 GST_EVENT_TYPE_NAME (event));
1490 is_newsegment = (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
1492 g_assert (demux->common.src->len == demux->common.num_streams);
1493 for (i = 0; i < demux->common.src->len; i++) {
1494 GstMatroskaTrackContext *stream;
1496 stream = g_ptr_array_index (demux->common.src, i);
1497 gst_event_ref (event);
1498 gst_pad_push_event (stream->pad, event);
1501 /* FIXME: send global tags before stream tags */
1502 if (G_UNLIKELY (is_newsegment && stream->pending_tags != NULL)) {
1503 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
1504 GST_PTR_FORMAT, stream->pending_tags,
1505 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
1506 gst_element_found_tags_for_pad (GST_ELEMENT (demux), stream->pad,
1507 stream->pending_tags);
1508 stream->pending_tags = NULL;
1512 if (G_UNLIKELY (is_newsegment && demux->common.global_tags != NULL)) {
1513 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1514 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1515 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1516 demux->common.global_tags, demux->common.global_tags);
1517 gst_element_found_tags (GST_ELEMENT (demux), demux->common.global_tags);
1518 demux->common.global_tags = NULL;
1521 gst_event_unref (event);
1526 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1528 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1531 g_return_val_if_fail (event != NULL, FALSE);
1533 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1534 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1536 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1537 GST_EVENT_TYPE_NAME (event));
1540 gst_event_unref (event);
1545 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1546 GstMatroskaIndex * entry, gboolean reset)
1550 GST_OBJECT_LOCK (demux);
1552 /* seek (relative to matroska segment) */
1553 /* position might be invalid; will error when streaming resumes ... */
1554 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1556 GST_DEBUG_OBJECT (demux, "Seeked to offset %" G_GUINT64_FORMAT ", block %d, "
1557 "time %" GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1558 entry->block, GST_TIME_ARGS (entry->time));
1560 /* update the time */
1561 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1562 demux->common.segment.last_stop = entry->time;
1563 demux->seek_block = entry->block;
1564 demux->seek_first = TRUE;
1565 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1567 for (i = 0; i < demux->common.src->len; i++) {
1568 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1571 stream->to_offset = G_MAXINT64;
1573 if (stream->from_offset != -1)
1574 stream->to_offset = stream->from_offset;
1576 stream->from_offset = -1;
1579 GST_OBJECT_UNLOCK (demux);
1585 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1595 /* searches for a cluster start from @pos,
1596 * return GST_FLOW_OK and cluster position in @pos if found */
1597 static GstFlowReturn
1598 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1600 gint64 newpos = *pos;
1602 GstFlowReturn ret = GST_FLOW_OK;
1603 const guint chunk = 64 * 1024;
1604 GstBuffer *buf = NULL;
1609 orig_offset = demux->common.offset;
1611 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1614 if (demux->clusters) {
1617 cpos = gst_util_array_binary_search (demux->clusters->data,
1618 demux->clusters->len, sizeof (gint64),
1619 (GCompareDataFunc) gst_matroska_cluster_compare,
1620 GST_SEARCH_MODE_AFTER, pos, NULL);
1623 GST_DEBUG_OBJECT (demux,
1624 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1625 demux->common.offset = *cpos;
1626 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1627 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1628 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1635 /* read in at newpos and scan for ebml cluster id */
1637 GstByteReader reader;
1641 gst_buffer_unref (buf);
1644 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1645 if (ret != GST_FLOW_OK)
1647 GST_DEBUG_OBJECT (demux, "read buffer size %d at offset %" G_GINT64_FORMAT,
1648 GST_BUFFER_SIZE (buf), newpos);
1649 gst_byte_reader_init_from_buffer (&reader, buf);
1651 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1652 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1653 if (cluster_pos >= 0) {
1654 newpos += cluster_pos;
1655 /* prepare resuming at next byte */
1656 gst_byte_reader_skip (&reader, cluster_pos + 1);
1657 GST_DEBUG_OBJECT (demux,
1658 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1659 /* extra checks whether we really sync'ed to a cluster:
1660 * - either it is the first and only cluster
1661 * - either there is a cluster after this one
1662 * - either cluster length is undefined
1664 /* ok if first cluster (there may not a subsequent one) */
1665 if (newpos == demux->first_cluster_offset) {
1666 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1669 demux->common.offset = newpos;
1670 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1671 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1672 if (ret != GST_FLOW_OK) {
1673 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1676 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1677 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1679 /* ok if undefined length or first cluster */
1680 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1681 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1685 demux->common.offset += length + needed;
1686 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1687 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1688 if (ret != GST_FLOW_OK)
1690 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1691 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1692 if (id == GST_MATROSKA_ID_CLUSTER)
1694 /* not ok, resume */
1697 /* partial cluster id may have been in tail of buffer */
1698 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1703 gst_buffer_unref (buf);
1708 demux->common.offset = orig_offset;
1713 /* bisect and scan through file for cluster starting before @time,
1714 * returns fake index entry with corresponding info on cluster */
1715 static GstMatroskaIndex *
1716 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1718 GstMatroskaIndex *entry = NULL;
1719 GstMatroskaReadState current_state;
1720 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1721 gint64 opos, newpos, startpos = 0, current_offset;
1722 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1723 const guint chunk = 64 * 1024;
1724 GstBuffer *buf = NULL;
1730 /* (under)estimate new position, resync using cluster ebml id,
1731 * and scan forward to appropriate cluster
1732 * (and re-estimate if need to go backward) */
1734 prev_cluster_time = GST_CLOCK_TIME_NONE;
1736 /* store some current state */
1737 current_state = demux->common.state;
1738 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1740 current_cluster_offset = demux->cluster_offset;
1741 current_cluster_time = demux->cluster_time;
1742 current_offset = demux->common.offset;
1744 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1746 /* estimate using start and current position */
1747 GST_OBJECT_LOCK (demux);
1748 opos = demux->common.offset - demux->common.ebml_segment_start;
1749 otime = demux->common.segment.last_stop;
1750 GST_OBJECT_UNLOCK (demux);
1753 time = MAX (time, demux->stream_start_time);
1755 /* avoid division by zero in first estimation below */
1756 if (otime <= demux->stream_start_time)
1760 GST_LOG_OBJECT (demux,
1761 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1762 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1763 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1764 GST_TIME_ARGS (otime - demux->stream_start_time),
1765 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1767 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1768 time - demux->stream_start_time,
1769 otime - demux->stream_start_time) - chunk;
1772 /* favour undershoot */
1773 newpos = newpos * 90 / 100;
1774 newpos += demux->common.ebml_segment_start;
1776 GST_DEBUG_OBJECT (demux,
1777 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1778 GST_TIME_ARGS (time), newpos);
1780 /* and at least start scanning before previous scan start to avoid looping */
1781 startpos = startpos * 90 / 100;
1782 if (startpos && startpos < newpos)
1785 /* read in at newpos and scan for ebml cluster id */
1789 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1790 if (ret == GST_FLOW_UNEXPECTED) {
1791 /* heuristic HACK */
1792 newpos = startpos * 80 / 100;
1793 GST_DEBUG_OBJECT (demux, "EOS; "
1794 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1795 GST_TIME_ARGS (time), newpos);
1798 } else if (ret != GST_FLOW_OK) {
1805 /* then start scanning and parsing for cluster time,
1806 * re-estimate if overshoot, otherwise next cluster and so on */
1807 demux->common.offset = newpos;
1808 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1810 guint64 cluster_size = 0;
1812 /* peek and parse some elements */
1813 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1814 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1815 if (ret != GST_FLOW_OK)
1817 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1818 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1820 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1821 if (ret != GST_FLOW_OK)
1824 if (id == GST_MATROSKA_ID_CLUSTER) {
1825 cluster_time = GST_CLOCK_TIME_NONE;
1826 if (length == G_MAXUINT64)
1829 cluster_size = length + needed;
1831 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1832 cluster_time == GST_CLOCK_TIME_NONE) {
1833 cluster_time = demux->cluster_time * demux->common.time_scale;
1834 cluster_offset = demux->cluster_offset;
1835 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1836 " with time %" GST_TIME_FORMAT, cluster_offset,
1837 GST_TIME_ARGS (cluster_time));
1838 if (cluster_time > time) {
1839 GST_DEBUG_OBJECT (demux, "overshot target");
1840 /* cluster overshoots */
1841 if (cluster_offset == demux->first_cluster_offset) {
1842 /* but no prev one */
1843 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1844 prev_cluster_time = cluster_time;
1845 prev_cluster_offset = cluster_offset;
1848 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1849 /* prev cluster did not overshoot, so prev cluster is target */
1852 /* re-estimate using this new position info */
1853 opos = cluster_offset;
1854 otime = cluster_time;
1858 /* cluster undershoots, goto next one */
1859 prev_cluster_time = cluster_time;
1860 prev_cluster_offset = cluster_offset;
1861 /* skip cluster if length is defined,
1862 * otherwise will be skippingly parsed into */
1864 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1865 demux->common.offset = cluster_offset + cluster_size;
1866 demux->cluster_time = GST_CLOCK_TIME_NONE;
1868 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1875 if (ret == GST_FLOW_UNEXPECTED) {
1876 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1882 entry = g_new0 (GstMatroskaIndex, 1);
1883 entry->time = prev_cluster_time;
1884 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1885 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1886 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1890 gst_buffer_unref (buf);
1892 /* restore some state */
1893 demux->cluster_offset = current_cluster_offset;
1894 demux->cluster_time = current_cluster_time;
1895 demux->common.offset = current_offset;
1896 demux->common.state = current_state;
1902 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1903 GstPad * pad, GstEvent * event)
1905 GstMatroskaIndex *entry = NULL;
1906 GstMatroskaIndex scan_entry;
1908 GstSeekType cur_type, stop_type;
1910 gboolean flush, keyunit;
1913 GstMatroskaTrackContext *track = NULL;
1914 GstSegment seeksegment = { 0, };
1915 gboolean update = TRUE;
1918 track = gst_pad_get_element_private (pad);
1920 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1923 /* we can only seek on time */
1924 if (format != GST_FORMAT_TIME) {
1925 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1929 /* copy segment, we need this because we still need the old
1930 * segment when we close the current segment. */
1931 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1933 /* pull mode without index means that the actual duration is not known,
1934 * we might be playing a file that's still being recorded
1935 * so, invalidate our current duration, which is only a moving target,
1936 * and should not be used to clamp anything */
1937 if (!demux->streaming && !demux->common.index &&
1938 demux->invalid_duration) {
1939 gst_segment_set_duration (&seeksegment, GST_FORMAT_TIME,
1940 GST_CLOCK_TIME_NONE);
1944 GST_DEBUG_OBJECT (demux, "configuring seek");
1945 gst_segment_set_seek (&seeksegment, rate, format, flags,
1946 cur_type, cur, stop_type, stop, &update);
1947 /* compensate for clip start time */
1948 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1949 seeksegment.last_stop += demux->stream_start_time;
1950 seeksegment.start += demux->stream_start_time;
1951 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1952 seeksegment.stop += demux->stream_start_time;
1953 /* note that time should stay at indicated position */
1957 /* restore segment duration (if any effect),
1958 * would be determined again when parsing, but anyway ... */
1959 gst_segment_set_duration (&seeksegment, GST_FORMAT_TIME,
1960 demux->common.segment.duration);
1962 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
1963 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
1965 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1968 /* only have to update some segment,
1969 * but also still have to honour flush and so on */
1970 GST_DEBUG_OBJECT (demux, "... no update");
1971 /* bad goto, bad ... */
1975 /* check sanity before we start flushing and all that */
1976 GST_OBJECT_LOCK (demux);
1977 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
1978 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
1979 seeksegment.last_stop, &demux->seek_index, &demux->seek_entry)) ==
1981 /* pull mode without index can scan later on */
1982 if (demux->streaming) {
1983 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
1984 GST_OBJECT_UNLOCK (demux);
1988 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
1989 GST_OBJECT_UNLOCK (demux);
1991 if (demux->streaming) {
1992 /* need to seek to cluster start to pick up cluster time */
1993 /* upstream takes care of flushing and all that
1994 * ... and newsegment event handling takes care of the rest */
1995 return perform_seek_to_offset (demux,
1996 entry->pos + demux->common.ebml_segment_start);
2001 GST_DEBUG_OBJECT (demux, "Starting flush");
2002 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_start ());
2003 gst_matroska_demux_send_event (demux, gst_event_new_flush_start ());
2005 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2006 gst_pad_pause_task (demux->common.sinkpad);
2012 /* now grab the stream lock so that streaming cannot continue, for
2013 * non flushing seeks when the element is in PAUSED this could block
2015 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2016 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2018 /* pull mode without index can do some scanning */
2019 if (!demux->streaming && !entry) {
2020 /* need to stop flushing upstream as we need it next */
2022 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_stop ());
2023 entry = gst_matroska_demux_search_pos (demux, seeksegment.last_stop);
2024 /* keep local copy */
2026 scan_entry = *entry;
2028 entry = &scan_entry;
2030 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2032 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop ());
2038 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start to %"
2039 GST_TIME_FORMAT, GST_TIME_ARGS (entry->time));
2040 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2041 seeksegment.last_stop = seeksegment.start;
2042 seeksegment.time = seeksegment.start - demux->stream_start_time;
2047 GST_DEBUG_OBJECT (demux, "Stopping flush");
2048 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_stop ());
2049 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop ());
2050 } else if (demux->segment_running && update) {
2051 GST_DEBUG_OBJECT (demux, "Closing currently running segment");
2053 GST_OBJECT_LOCK (demux);
2054 if (demux->close_segment)
2055 gst_event_unref (demux->close_segment);
2057 demux->close_segment = gst_event_new_new_segment (TRUE,
2058 demux->common.segment.rate, GST_FORMAT_TIME,
2059 demux->common.segment.start, demux->common.segment.last_stop,
2060 demux->common.segment.time);
2061 GST_OBJECT_UNLOCK (demux);
2064 GST_OBJECT_LOCK (demux);
2065 /* now update the real segment info */
2066 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2067 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2068 GST_OBJECT_UNLOCK (demux);
2070 /* update some (segment) state */
2071 if (update && !gst_matroska_demux_move_to_entry (demux, entry, TRUE))
2074 /* notify start of new segment */
2075 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2078 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2079 GST_FORMAT_TIME, demux->common.segment.start);
2080 gst_element_post_message (GST_ELEMENT (demux), msg);
2083 GST_OBJECT_LOCK (demux);
2084 if (demux->new_segment)
2085 gst_event_unref (demux->new_segment);
2086 demux->new_segment = gst_event_new_new_segment_full (!update,
2087 demux->common.segment.rate, demux->common.segment.applied_rate,
2088 demux->common.segment.format, demux->common.segment.start,
2089 demux->common.segment.stop, demux->common.segment.time);
2090 GST_OBJECT_UNLOCK (demux);
2092 /* restart our task since it might have been stopped when we did the
2094 demux->segment_running = TRUE;
2095 gst_pad_start_task (demux->common.sinkpad,
2096 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad);
2098 /* streaming can continue now */
2099 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2105 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2106 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2112 * Handle whether we can perform the seek event or if we have to let the chain
2113 * function handle seeks to build the seek indexes first.
2116 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2120 GstSeekType cur_type, stop_type;
2125 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2130 /* we can only seek on time */
2131 if (format != GST_FORMAT_TIME) {
2132 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2136 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2137 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2141 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2142 GST_DEBUG_OBJECT (demux,
2143 "Non-flushing seek not supported in streaming mode");
2147 if (flags & GST_SEEK_FLAG_SEGMENT) {
2148 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2152 /* check for having parsed index already */
2153 if (!demux->common.index_parsed) {
2154 gboolean building_index;
2157 if (!demux->index_offset) {
2158 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2162 GST_OBJECT_LOCK (demux);
2163 /* handle the seek event in the chain function */
2164 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2165 /* no more seek can be issued until state reset to _DATA */
2167 /* copy the event */
2168 if (demux->seek_event)
2169 gst_event_unref (demux->seek_event);
2170 demux->seek_event = gst_event_ref (event);
2172 /* set the building_index flag so that only one thread can setup the
2173 * structures for index seeking. */
2174 building_index = demux->building_index;
2175 if (!building_index) {
2176 demux->building_index = TRUE;
2177 offset = demux->index_offset;
2179 GST_OBJECT_UNLOCK (demux);
2181 if (!building_index) {
2182 /* seek to the first subindex or legacy index */
2183 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2184 return perform_seek_to_offset (demux, offset);
2187 /* well, we are handling it already */
2191 /* delegate to tweaked regular seek */
2192 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2196 gst_matroska_demux_handle_src_event (GstPad * pad, GstEvent * event)
2198 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
2199 gboolean res = TRUE;
2201 switch (GST_EVENT_TYPE (event)) {
2202 case GST_EVENT_SEEK:
2203 /* no seeking until we are (safely) ready */
2204 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2205 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2208 if (!demux->streaming)
2209 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2211 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2212 gst_event_unref (event);
2217 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2218 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2219 GstMatroskaTrackVideoContext *videocontext =
2220 (GstMatroskaTrackVideoContext *) context;
2222 GstClockTimeDiff diff;
2223 GstClockTime timestamp;
2225 gst_event_parse_qos (event, &proportion, &diff, ×tamp);
2227 GST_OBJECT_LOCK (demux);
2228 videocontext->earliest_time = timestamp + diff;
2229 GST_OBJECT_UNLOCK (demux);
2232 gst_event_unref (event);
2236 /* events we don't need to handle */
2237 case GST_EVENT_NAVIGATION:
2238 gst_event_unref (event);
2242 case GST_EVENT_LATENCY:
2244 res = gst_pad_push_event (demux->common.sinkpad, event);
2248 gst_object_unref (demux);
2253 static GstFlowReturn
2254 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2256 GstFlowReturn ret = GST_FLOW_UNEXPECTED;
2257 gboolean done = TRUE;
2260 g_return_val_if_fail (demux->seek_index, GST_FLOW_UNEXPECTED);
2261 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2262 GST_FLOW_UNEXPECTED);
2264 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2266 if (!demux->seek_entry) {
2267 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2271 for (i = 0; i < demux->common.src->len; i++) {
2272 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2274 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2275 ", stream %d at %" GST_TIME_FORMAT,
2276 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2277 GST_TIME_ARGS (stream->from_time));
2278 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2279 if (stream->from_time > demux->common.segment.start) {
2280 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2284 /* nothing pushed for this stream;
2285 * likely seek entry did not start at keyframe, so all was skipped.
2286 * So we need an earlier entry */
2292 GstMatroskaIndex *entry;
2294 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2295 --demux->seek_entry);
2296 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE))
2306 static GstFlowReturn
2307 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2309 GstFlowReturn ret = GST_FLOW_OK;
2312 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2314 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2315 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2319 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2320 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2324 /* one track within the "all-tracks" header */
2325 case GST_MATROSKA_ID_TRACKENTRY:
2326 ret = gst_matroska_demux_add_stream (demux, ebml);
2330 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2335 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2337 demux->tracks_parsed = TRUE;
2343 * Read signed/unsigned "EBML" numbers.
2344 * Return: number of bytes processed.
2348 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2350 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2358 while (read <= 8 && !(total & len_mask)) {
2365 if ((total &= (len_mask - 1)) == len_mask - 1)
2370 if (data[n] == 0xff)
2372 total = (total << 8) | data[n];
2376 if (read == num_ffs && total != 0)
2385 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2390 /* read as unsigned number first */
2391 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2395 if (unum == G_MAXUINT64)
2398 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2404 * Mostly used for subtitles. We add void filler data for each
2405 * lagging stream to make sure we don't deadlock.
2409 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2413 GST_OBJECT_LOCK (demux);
2415 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2416 GST_TIME_ARGS (demux->common.segment.last_stop));
2418 g_assert (demux->common.num_streams == demux->common.src->len);
2419 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2420 GstMatroskaTrackContext *context;
2422 context = g_ptr_array_index (demux->common.src, stream_nr);
2424 GST_LOG_OBJECT (demux,
2425 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2426 GST_TIME_ARGS (context->pos));
2428 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2429 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2433 /* does it lag? 0.5 seconds is a random threshold...
2434 * lag need only be considered if we have advanced into requested segment */
2435 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2436 GST_CLOCK_TIME_IS_VALID (demux->common.segment.last_stop) &&
2437 demux->common.segment.last_stop > demux->common.segment.start &&
2438 context->pos + (GST_SECOND / 2) < demux->common.segment.last_stop) {
2442 new_start = demux->common.segment.last_stop - (GST_SECOND / 2);
2443 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop))
2444 new_start = MIN (new_start, demux->common.segment.stop);
2445 GST_DEBUG_OBJECT (demux,
2446 "Synchronizing stream %d with others by advancing time " "from %"
2447 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2448 GST_TIME_ARGS (context->pos), GST_TIME_ARGS (new_start));
2450 context->pos = new_start;
2452 /* advance stream time */
2453 event = gst_event_new_new_segment (TRUE, demux->common.segment.rate,
2454 demux->common.segment.format, new_start, demux->common.segment.stop,
2456 GST_OBJECT_UNLOCK (demux);
2457 gst_pad_push_event (context->pad, event);
2458 GST_OBJECT_LOCK (demux);
2462 GST_OBJECT_UNLOCK (demux);
2465 static GstFlowReturn
2466 gst_matroska_demux_push_hdr_buf (GstMatroskaDemux * demux,
2467 GstMatroskaTrackContext * stream, guint8 * data, guint len)
2469 GstFlowReturn ret, cret;
2470 GstBuffer *header_buf;
2472 header_buf = gst_buffer_new_and_alloc (len);
2473 gst_buffer_set_caps (header_buf, stream->caps);
2474 memcpy (GST_BUFFER_DATA (header_buf), data, len);
2476 if (stream->set_discont) {
2477 GST_BUFFER_FLAG_SET (header_buf, GST_BUFFER_FLAG_DISCONT);
2478 stream->set_discont = FALSE;
2481 ret = gst_pad_push (stream->pad, header_buf);
2484 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
2489 static GstFlowReturn
2490 gst_matroska_demux_push_flac_codec_priv_data (GstMatroskaDemux * demux,
2491 GstMatroskaTrackContext * stream)
2497 GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
2499 pdata = (guint8 *) stream->codec_priv;
2501 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2502 if (stream->codec_priv_size < ((4) + (4 + 34))) {
2503 GST_WARNING_OBJECT (demux, "not enough codec priv data for flac headers");
2504 return GST_FLOW_ERROR;
2507 if (memcmp (pdata, "fLaC", 4) != 0) {
2508 GST_WARNING_OBJECT (demux, "no flac marker at start of stream headers");
2509 return GST_FLOW_ERROR;
2512 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 4);
2513 if (ret != GST_FLOW_OK)
2516 off = 4; /* skip fLaC marker */
2517 while (off < stream->codec_priv_size) {
2518 len = GST_READ_UINT8 (pdata + off + 1) << 16;
2519 len |= GST_READ_UINT8 (pdata + off + 2) << 8;
2520 len |= GST_READ_UINT8 (pdata + off + 3);
2522 GST_DEBUG_OBJECT (demux, "header packet: len=%u bytes, flags=0x%02x",
2523 len, (guint) pdata[off]);
2525 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata + off, len + 4);
2526 if (ret != GST_FLOW_OK)
2534 static GstFlowReturn
2535 gst_matroska_demux_push_speex_codec_priv_data (GstMatroskaDemux * demux,
2536 GstMatroskaTrackContext * stream)
2541 GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
2543 pdata = (guint8 *) stream->codec_priv;
2545 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2546 if (stream->codec_priv_size < 80) {
2547 GST_WARNING_OBJECT (demux, "not enough codec priv data for speex headers");
2548 return GST_FLOW_ERROR;
2551 if (memcmp (pdata, "Speex ", 8) != 0) {
2552 GST_WARNING_OBJECT (demux, "no Speex marker at start of stream headers");
2553 return GST_FLOW_ERROR;
2556 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 80);
2557 if (ret != GST_FLOW_OK)
2560 if (stream->codec_priv_size == 80)
2563 return gst_matroska_demux_push_hdr_buf (demux, stream, pdata + 80,
2564 stream->codec_priv_size - 80);
2567 static GstFlowReturn
2568 gst_matroska_demux_push_xiph_codec_priv_data (GstMatroskaDemux * demux,
2569 GstMatroskaTrackContext * stream)
2572 guint8 *p = (guint8 *) stream->codec_priv;
2573 gint i, offset, num_packets;
2574 guint *length, last;
2576 if (stream->codec_priv == NULL || stream->codec_priv_size == 0) {
2577 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
2578 ("Missing codec private data for xiph headers, broken file"));
2579 return GST_FLOW_ERROR;
2582 /* start of the stream and vorbis audio or theora video, need to
2583 * send the codec_priv data as first three packets */
2584 num_packets = p[0] + 1;
2585 GST_DEBUG_OBJECT (demux, "%u stream headers, total length=%u bytes",
2586 (guint) num_packets, stream->codec_priv_size);
2588 length = g_alloca (num_packets * sizeof (guint));
2592 /* first packets, read length values */
2593 for (i = 0; i < num_packets - 1; i++) {
2595 while (offset < stream->codec_priv_size) {
2596 length[i] += p[offset];
2597 if (p[offset++] != 0xff)
2602 if (offset + last > stream->codec_priv_size)
2603 return GST_FLOW_ERROR;
2605 /* last packet is the remaining size */
2606 length[i] = stream->codec_priv_size - offset - last;
2608 for (i = 0; i < num_packets; i++) {
2609 GST_DEBUG_OBJECT (demux, "buffer %d: length=%u bytes", i,
2611 if (offset + length[i] > stream->codec_priv_size)
2612 return GST_FLOW_ERROR;
2615 gst_matroska_demux_push_hdr_buf (demux, stream, p + offset, length[i]);
2616 if (ret != GST_FLOW_OK)
2619 offset += length[i];
2625 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2626 GstMatroskaTrackContext * stream)
2630 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2632 if (!stream->codec_priv)
2635 /* ideally, VobSub private data should be parsed and stored more convenient
2636 * elsewhere, but for now, only interested in a small part */
2638 /* make sure we have terminating 0 */
2639 buf = g_strndup ((gchar *) stream->codec_priv, stream->codec_priv_size);
2641 /* just locate and parse palette part */
2642 start = strstr (buf, "palette:");
2647 guint8 r, g, b, y, u, v;
2650 while (g_ascii_isspace (*start))
2652 for (i = 0; i < 16; i++) {
2653 if (sscanf (start, "%06x", &col) != 1)
2656 while ((*start == ',') || g_ascii_isspace (*start))
2658 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2659 r = (col >> 16) & 0xff;
2660 g = (col >> 8) & 0xff;
2662 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2664 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2665 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2666 clut[i] = (y << 16) | (u << 8) | v;
2669 /* got them all without problems; build and send event */
2673 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2674 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2675 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2676 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2677 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2678 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2679 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2680 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2681 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2682 G_TYPE_INT, clut[15], NULL);
2684 gst_pad_push_event (stream->pad,
2685 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
2691 static GstFlowReturn
2692 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2693 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2696 guint seq_header_len;
2699 if (stream->codec_state) {
2700 seq_header = stream->codec_state;
2701 seq_header_len = stream->codec_state_size;
2702 } else if (stream->codec_priv) {
2703 seq_header = stream->codec_priv;
2704 seq_header_len = stream->codec_priv_size;
2709 /* Sequence header only needed for keyframes */
2710 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2713 if (GST_BUFFER_SIZE (*buf) < 4)
2716 header = GST_READ_UINT32_BE (GST_BUFFER_DATA (*buf));
2717 /* Sequence start code, if not found prepend */
2718 if (header != 0x000001b3) {
2721 newbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (*buf) + seq_header_len);
2722 gst_buffer_set_caps (newbuf, stream->caps);
2724 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2725 gst_buffer_copy_metadata (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2726 GST_BUFFER_COPY_FLAGS);
2727 g_memmove (GST_BUFFER_DATA (newbuf), seq_header, seq_header_len);
2728 g_memmove (GST_BUFFER_DATA (newbuf) + seq_header_len,
2729 GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
2730 gst_buffer_unref (*buf);
2737 static GstFlowReturn
2738 gst_matroska_demux_add_wvpk_header (GstElement * element,
2739 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2741 GstMatroskaTrackAudioContext *audiocontext =
2742 (GstMatroskaTrackAudioContext *) stream;
2743 GstBuffer *newbuf = NULL;
2753 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2756 wvh.total_samples = -1;
2757 wvh.block_index = audiocontext->wvpk_block_index;
2759 if (audiocontext->channels <= 2) {
2760 guint32 block_samples;
2762 block_samples = GST_READ_UINT32_LE (GST_BUFFER_DATA (*buf));
2763 /* we need to reconstruct the header of the wavpack block */
2765 /* -20 because ck_size is the size of the wavpack block -8
2766 * and lace_size is the size of the wavpack block + 12
2767 * (the three guint32 of the header that already are in the buffer) */
2768 wvh.ck_size = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 20;
2770 /* block_samples, flags and crc are already in the buffer */
2771 newlen = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 12;
2772 newbuf = gst_buffer_new_and_alloc (newlen);
2773 gst_buffer_set_caps (newbuf, stream->caps);
2775 data = GST_BUFFER_DATA (newbuf);
2780 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2781 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2782 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2783 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2784 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2785 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2786 g_memmove (data + 20, GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
2787 gst_buffer_copy_metadata (newbuf, *buf,
2788 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
2789 gst_buffer_unref (*buf);
2791 audiocontext->wvpk_block_index += block_samples;
2796 guint32 block_samples, flags, crc, blocksize;
2798 data = GST_BUFFER_DATA (*buf);
2799 size = GST_BUFFER_SIZE (*buf);
2802 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2803 return GST_FLOW_ERROR;
2806 block_samples = GST_READ_UINT32_LE (data);
2811 flags = GST_READ_UINT32_LE (data);
2814 crc = GST_READ_UINT32_LE (data);
2817 blocksize = GST_READ_UINT32_LE (data);
2821 if (blocksize == 0 || size < blocksize)
2824 if (newbuf == NULL) {
2825 newbuf = gst_buffer_new_and_alloc (sizeof (Wavpack4Header) + blocksize);
2826 gst_buffer_set_caps (newbuf, stream->caps);
2828 gst_buffer_copy_metadata (newbuf, *buf,
2829 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
2832 outdata = GST_BUFFER_DATA (newbuf);
2834 GST_BUFFER_SIZE (newbuf) += sizeof (Wavpack4Header) + blocksize;
2835 GST_BUFFER_DATA (newbuf) =
2836 g_realloc (GST_BUFFER_DATA (newbuf), GST_BUFFER_SIZE (newbuf));
2837 GST_BUFFER_MALLOCDATA (newbuf) = GST_BUFFER_DATA (newbuf);
2838 outdata = GST_BUFFER_DATA (newbuf);
2841 outdata[outpos] = 'w';
2842 outdata[outpos + 1] = 'v';
2843 outdata[outpos + 2] = 'p';
2844 outdata[outpos + 3] = 'k';
2847 GST_WRITE_UINT32_LE (outdata + outpos,
2848 blocksize + sizeof (Wavpack4Header) - 8);
2849 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2850 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2851 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2852 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2853 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2854 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2855 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2856 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2859 g_memmove (outdata + outpos, data, blocksize);
2860 outpos += blocksize;
2864 gst_buffer_unref (*buf);
2866 audiocontext->wvpk_block_index += block_samples;
2872 /* @text must be null-terminated */
2874 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2879 /* yes, this might all lead to false positives ... */
2880 tag = (gchar *) text;
2881 while ((tag = strchr (tag, '<'))) {
2883 if (*tag != '\0' && *(tag + 1) == '>') {
2884 /* some common convenience ones */
2885 /* maybe any character will do here ? */
2898 if (strstr (text, "<span"))
2904 static GstFlowReturn
2905 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2906 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2908 GstMatroskaTrackSubtitleContext *sub_stream;
2909 const gchar *encoding, *data;
2915 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
2917 data = (const gchar *) GST_BUFFER_DATA (*buf);
2918 size = GST_BUFFER_SIZE (*buf);
2920 if (!sub_stream->invalid_utf8) {
2921 if (g_utf8_validate (data, size, NULL)) {
2924 GST_WARNING_OBJECT (element, "subtitle stream %d is not valid UTF-8, this "
2925 "is broken according to the matroska specification", stream->num);
2926 sub_stream->invalid_utf8 = TRUE;
2929 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
2930 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
2931 if (encoding == NULL || *encoding == '\0') {
2932 /* if local encoding is UTF-8 and no encoding specified
2933 * via the environment variable, assume ISO-8859-15 */
2934 if (g_get_charset (&encoding)) {
2935 encoding = "ISO-8859-15";
2939 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
2943 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
2944 encoding, err->message);
2948 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
2949 encoding = "ISO-8859-15";
2950 utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
2954 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
2955 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
2958 utf8 = g_strdup ("invalid subtitle");
2960 newbuf = gst_buffer_new ();
2961 GST_BUFFER_MALLOCDATA (newbuf) = (guint8 *) utf8;
2962 GST_BUFFER_DATA (newbuf) = (guint8 *) utf8;
2963 GST_BUFFER_SIZE (newbuf) = strlen (utf8);
2964 gst_buffer_copy_metadata (newbuf, *buf, GST_BUFFER_COPY_ALL);
2965 gst_buffer_unref (*buf);
2968 data = (const gchar *) GST_BUFFER_DATA (*buf);
2969 size = GST_BUFFER_SIZE (*buf);
2973 if (sub_stream->check_markup) {
2974 /* caps claim markup text, so we need to escape text,
2975 * except if text is already markup and then needs no further escaping */
2976 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
2977 gst_matroska_demux_subtitle_chunk_has_tag (element, data);
2979 if (!sub_stream->seen_markup_tag) {
2980 utf8 = g_markup_escape_text (data, size);
2982 newbuf = gst_buffer_new ();
2983 GST_BUFFER_MALLOCDATA (newbuf) = (guint8 *) utf8;
2984 GST_BUFFER_DATA (newbuf) = (guint8 *) utf8;
2985 GST_BUFFER_SIZE (newbuf) = strlen (utf8);
2986 gst_buffer_copy_metadata (newbuf, *buf, GST_BUFFER_COPY_ALL);
2987 gst_buffer_unref (*buf);
2996 static GstFlowReturn
2997 gst_matroska_demux_check_aac (GstElement * element,
2998 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3003 data = GST_BUFFER_DATA (*buf);
3004 size = GST_BUFFER_SIZE (*buf);
3006 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3010 /* tss, ADTS data, remove codec_data
3011 * still assume it is at least parsed */
3012 new_caps = gst_caps_copy (stream->caps);
3013 s = gst_caps_get_structure (new_caps, 0);
3015 gst_structure_remove_field (s, "codec_data");
3016 gst_caps_replace (&stream->caps, new_caps);
3017 gst_pad_set_caps (stream->pad, new_caps);
3018 gst_buffer_set_caps (*buf, new_caps);
3019 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3020 "new caps: %" GST_PTR_FORMAT, new_caps);
3021 gst_caps_unref (new_caps);
3024 /* disable subsequent checking */
3025 stream->postprocess_frame = NULL;
3030 static GstFlowReturn
3031 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3032 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3033 gboolean is_simpleblock)
3035 GstMatroskaTrackContext *stream = NULL;
3036 GstFlowReturn ret = GST_FLOW_OK;
3037 gboolean readblock = FALSE;
3039 guint64 block_duration = -1;
3040 GstBuffer *buf = NULL;
3041 gint stream_num = -1, n, laces = 0;
3043 gint *lace_size = NULL;
3046 gint64 referenceblock = 0;
3049 offset = gst_ebml_read_get_offset (ebml);
3051 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3052 if (!is_simpleblock) {
3053 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3057 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3061 /* one block inside the group. Note, block parsing is one
3062 * of the harder things, so this code is a bit complicated.
3063 * See http://www.matroska.org/ for documentation. */
3064 case GST_MATROSKA_ID_SIMPLEBLOCK:
3065 case GST_MATROSKA_ID_BLOCK:
3071 gst_buffer_unref (buf);
3074 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3077 data = GST_BUFFER_DATA (buf);
3078 size = GST_BUFFER_SIZE (buf);
3080 /* first byte(s): blocknum */
3081 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3086 /* fetch stream from num */
3087 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3089 if (G_UNLIKELY (size < 3)) {
3090 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3091 /* non-fatal, try next block(group) */
3094 } else if (G_UNLIKELY (stream_num < 0 ||
3095 stream_num >= demux->common.num_streams)) {
3096 /* let's not give up on a stray invalid track number */
3097 GST_WARNING_OBJECT (demux,
3098 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3099 "; ignoring block", stream_num, num);
3103 stream = g_ptr_array_index (demux->common.src, stream_num);
3105 /* time (relative to cluster time) */
3106 time = ((gint16) GST_READ_UINT16_BE (data));
3109 flags = GST_READ_UINT8 (data);
3113 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3116 switch ((flags & 0x06) >> 1) {
3117 case 0x0: /* no lacing */
3119 lace_size = g_new (gint, 1);
3120 lace_size[0] = size;
3123 case 0x1: /* xiph lacing */
3124 case 0x2: /* fixed-size lacing */
3125 case 0x3: /* EBML lacing */
3127 goto invalid_lacing;
3128 laces = GST_READ_UINT8 (data) + 1;
3131 lace_size = g_new0 (gint, laces);
3133 switch ((flags & 0x06) >> 1) {
3134 case 0x1: /* xiph lacing */ {
3135 guint temp, total = 0;
3137 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3140 goto invalid_lacing;
3141 temp = GST_READ_UINT8 (data);
3142 lace_size[n] += temp;
3148 total += lace_size[n];
3150 lace_size[n] = size - total;
3154 case 0x2: /* fixed-size lacing */
3155 for (n = 0; n < laces; n++)
3156 lace_size[n] = size / laces;
3159 case 0x3: /* EBML lacing */ {
3162 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3166 total = lace_size[0] = num;
3167 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3171 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3175 lace_size[n] = lace_size[n - 1] + snum;
3176 total += lace_size[n];
3179 lace_size[n] = size - total;
3186 if (stream->send_xiph_headers) {
3187 ret = gst_matroska_demux_push_xiph_codec_priv_data (demux, stream);
3188 stream->send_xiph_headers = FALSE;
3191 if (stream->send_flac_headers) {
3192 ret = gst_matroska_demux_push_flac_codec_priv_data (demux, stream);
3193 stream->send_flac_headers = FALSE;
3196 if (stream->send_speex_headers) {
3197 ret = gst_matroska_demux_push_speex_codec_priv_data (demux, stream);
3198 stream->send_speex_headers = FALSE;
3201 if (stream->send_dvd_event) {
3202 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
3203 /* FIXME: should we send this event again after (flushing) seek ? */
3204 stream->send_dvd_event = FALSE;
3207 if (ret != GST_FLOW_OK)
3214 case GST_MATROSKA_ID_BLOCKDURATION:{
3215 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3216 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3221 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3222 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3223 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3228 case GST_MATROSKA_ID_CODECSTATE:{
3230 guint64 data_len = 0;
3233 gst_ebml_read_binary (ebml, &id, &data,
3234 &data_len)) != GST_FLOW_OK)
3237 if (G_UNLIKELY (stream == NULL)) {
3238 GST_WARNING_OBJECT (demux,
3239 "Unexpected CodecState subelement - ignoring");
3243 g_free (stream->codec_state);
3244 stream->codec_state = data;
3245 stream->codec_state_size = data_len;
3247 /* Decode if necessary */
3248 if (stream->encodings && stream->encodings->len > 0
3249 && stream->codec_state && stream->codec_state_size > 0) {
3250 if (!gst_matroska_decode_data (stream->encodings,
3251 &stream->codec_state, &stream->codec_state_size,
3252 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3253 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3257 GST_DEBUG_OBJECT (demux, "CodecState of %u bytes",
3258 stream->codec_state_size);
3263 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3267 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3268 case GST_MATROSKA_ID_BLOCKADDITIONS:
3269 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3270 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3271 case GST_MATROSKA_ID_SLICES:
3272 GST_DEBUG_OBJECT (demux,
3273 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3274 ret = gst_ebml_read_skip (ebml);
3282 /* reading a number or so could have failed */
3283 if (ret != GST_FLOW_OK)
3286 if (ret == GST_FLOW_OK && readblock) {
3287 guint64 duration = 0;
3288 gint64 lace_time = 0;
3289 gboolean delta_unit;
3291 stream = g_ptr_array_index (demux->common.src, stream_num);
3293 if (cluster_time != GST_CLOCK_TIME_NONE) {
3294 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3295 * Drop unless the lace contains timestamp 0? */
3296 if (time < 0 && (-time) > cluster_time) {
3299 if (stream->timecodescale == 1.0)
3300 lace_time = (cluster_time + time) * demux->common.time_scale;
3303 gst_util_guint64_to_gdouble ((cluster_time + time) *
3304 demux->common.time_scale) * stream->timecodescale;
3307 lace_time = GST_CLOCK_TIME_NONE;
3310 /* need to refresh segment info ASAP */
3311 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_newsegment) {
3314 GST_DEBUG_OBJECT (demux,
3315 "generating segment starting at %" GST_TIME_FORMAT,
3316 GST_TIME_ARGS (lace_time));
3317 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3318 demux->stream_start_time = lace_time;
3319 GST_DEBUG_OBJECT (demux,
3320 "Setting stream start time to %" GST_TIME_FORMAT,
3321 GST_TIME_ARGS (lace_time));
3323 clace_time = MAX (lace_time, demux->stream_start_time);
3324 gst_segment_set_newsegment (&demux->common.segment, FALSE,
3325 demux->common.segment.rate, GST_FORMAT_TIME, clace_time,
3326 GST_CLOCK_TIME_NONE, clace_time - demux->stream_start_time);
3327 /* now convey our segment notion downstream */
3328 gst_matroska_demux_send_event (demux, gst_event_new_new_segment (FALSE,
3329 demux->common.segment.rate, demux->common.segment.format,
3330 demux->common.segment.start, demux->common.segment.stop,
3331 demux->common.segment.start));
3332 demux->need_newsegment = FALSE;
3335 if (block_duration != -1) {
3336 if (stream->timecodescale == 1.0)
3337 duration = gst_util_uint64_scale (block_duration,
3338 demux->common.time_scale, 1);
3341 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3342 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3343 1)) * stream->timecodescale);
3344 } else if (stream->default_duration) {
3345 duration = stream->default_duration * laces;
3347 /* else duration is diff between timecode of this and next block */
3349 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3350 a ReferenceBlock implies that this is not a keyframe. In either
3351 case, it only makes sense for video streams. */
3352 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3353 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
3355 if (delta_unit && stream->set_discont) {
3356 /* When doing seeks or such, we need to restart on key frames or
3357 * decoders might choke. */
3358 GST_DEBUG_OBJECT (demux, "skipping delta unit");
3362 for (n = 0; n < laces; n++) {
3365 if (G_UNLIKELY (lace_size[n] > size)) {
3366 GST_WARNING_OBJECT (demux, "Invalid lace size");
3370 /* QoS for video track with an index. the assumption is that
3371 index entries point to keyframes, but if that is not true we
3372 will instad skip until the next keyframe. */
3373 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3374 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3375 stream->index_table && demux->common.segment.rate > 0.0) {
3376 GstMatroskaTrackVideoContext *videocontext =
3377 (GstMatroskaTrackVideoContext *) stream;
3378 GstClockTime earliest_time;
3379 GstClockTime earliest_stream_time;
3381 GST_OBJECT_LOCK (demux);
3382 earliest_time = videocontext->earliest_time;
3383 GST_OBJECT_UNLOCK (demux);
3384 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3385 GST_FORMAT_TIME, earliest_time);
3387 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3388 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3389 lace_time <= earliest_stream_time) {
3390 /* find index entry (keyframe) <= earliest_stream_time */
3391 GstMatroskaIndex *entry =
3392 gst_util_array_binary_search (stream->index_table->data,
3393 stream->index_table->len, sizeof (GstMatroskaIndex),
3394 (GCompareDataFunc) gst_matroska_index_seek_find,
3395 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3397 /* if that entry (keyframe) is after the current the current
3398 buffer, we can skip pushing (and thus decoding) all
3399 buffers until that keyframe. */
3400 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3401 entry->time > lace_time) {
3402 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3403 stream->set_discont = TRUE;
3409 sub = gst_buffer_create_sub (buf,
3410 GST_BUFFER_SIZE (buf) - size, lace_size[n]);
3411 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3414 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3416 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3418 if (stream->encodings != NULL && stream->encodings->len > 0)
3419 sub = gst_matroska_decode_buffer (stream, sub);
3422 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3426 GST_BUFFER_TIMESTAMP (sub) = lace_time;
3428 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3429 GstClockTime last_stop_end;
3431 /* Check if this stream is after segment stop */
3432 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3433 lace_time >= demux->common.segment.stop) {
3434 GST_DEBUG_OBJECT (demux,
3435 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3436 GST_TIME_ARGS (demux->common.segment.stop));
3437 gst_buffer_unref (sub);
3440 if (offset >= stream->to_offset) {
3441 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3443 gst_buffer_unref (sub);
3447 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3448 * that landed us with timestamps not quite intended */
3449 GST_OBJECT_LOCK (demux);
3450 if (demux->max_gap_time &&
3451 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3452 demux->common.segment.rate > 0.0) {
3453 GstClockTimeDiff diff;
3454 GstEvent *event1, *event2;
3456 /* only send newsegments with increasing start times,
3457 * otherwise if these go back and forth downstream (sinks) increase
3458 * accumulated time and running_time */
3459 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3460 if (diff > 0 && diff > demux->max_gap_time
3461 && lace_time > demux->common.segment.start
3462 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3463 || lace_time < demux->common.segment.stop)) {
3464 GST_DEBUG_OBJECT (demux,
3465 "Gap of %" G_GINT64_FORMAT " ns detected in"
3466 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3467 "Sending updated NEWSEGMENT events", diff,
3468 stream->index, GST_TIME_ARGS (stream->pos),
3469 GST_TIME_ARGS (lace_time));
3470 /* send newsegment events such that the gap is not accounted in
3471 * accum time, hence running_time */
3472 /* close ahead of gap */
3473 event1 = gst_event_new_new_segment (TRUE,
3474 demux->common.segment.rate, demux->common.segment.format,
3475 demux->last_stop_end, demux->last_stop_end,
3476 demux->last_stop_end);
3478 event2 = gst_event_new_new_segment (FALSE,
3479 demux->common.segment.rate,
3480 demux->common.segment.format, lace_time,
3481 demux->common.segment.stop, lace_time);
3482 GST_OBJECT_UNLOCK (demux);
3483 gst_matroska_demux_send_event (demux, event1);
3484 gst_matroska_demux_send_event (demux, event2);
3485 GST_OBJECT_LOCK (demux);
3486 /* align segment view with downstream,
3487 * prevents double-counting accum when closing segment */
3488 gst_segment_set_newsegment (&demux->common.segment, FALSE,
3489 demux->common.segment.rate, demux->common.segment.format,
3490 lace_time, demux->common.segment.stop, lace_time);
3491 demux->common.segment.last_stop = lace_time;
3495 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.last_stop)
3496 || demux->common.segment.last_stop < lace_time) {
3497 demux->common.segment.last_stop = lace_time;
3499 GST_OBJECT_UNLOCK (demux);
3501 last_stop_end = lace_time;
3503 GST_BUFFER_DURATION (sub) = duration / laces;
3504 last_stop_end += GST_BUFFER_DURATION (sub);
3507 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3508 demux->last_stop_end < last_stop_end)
3509 demux->last_stop_end = last_stop_end;
3511 GST_OBJECT_LOCK (demux);
3512 if (demux->common.segment.duration == -1 ||
3513 demux->stream_start_time + demux->common.segment.duration <
3515 gst_segment_set_duration (&demux->common.segment, GST_FORMAT_TIME,
3516 last_stop_end - demux->stream_start_time);
3517 GST_OBJECT_UNLOCK (demux);
3518 gst_element_post_message (GST_ELEMENT_CAST (demux),
3519 gst_message_new_duration (GST_OBJECT_CAST (demux),
3520 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
3521 demux->invalid_duration = TRUE;
3523 GST_OBJECT_UNLOCK (demux);
3527 stream->pos = lace_time;
3529 gst_matroska_demux_sync_streams (demux);
3531 if (stream->set_discont) {
3532 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3533 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3534 stream->set_discont = FALSE;
3537 /* reverse playback book-keeping */
3538 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3539 stream->from_time = lace_time;
3540 if (stream->from_offset == -1)
3541 stream->from_offset = offset;
3543 GST_DEBUG_OBJECT (demux,
3544 "Pushing lace %d, data of size %d for stream %d, time=%"
3545 GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
3546 GST_BUFFER_SIZE (sub), stream_num,
3547 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
3548 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3550 if (demux->common.element_index) {
3551 if (stream->index_writer_id == -1)
3552 gst_index_get_writer_id (demux->common.element_index,
3553 GST_OBJECT (stream->pad), &stream->index_writer_id);
3555 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3556 G_GUINT64_FORMAT " for writer id %d",
3557 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
3558 stream->index_writer_id);
3559 gst_index_add_association (demux->common.element_index,
3560 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3561 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3562 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
3563 cluster_offset, NULL);
3566 gst_buffer_set_caps (sub, GST_PAD_CAPS (stream->pad));
3568 /* Postprocess the buffers depending on the codec used */
3569 if (stream->postprocess_frame) {
3570 GST_LOG_OBJECT (demux, "running post process");
3571 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3574 /* At this point, we have a sub-buffer pointing at data within a larger
3575 buffer. This data might not be aligned with anything. If the data is
3576 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3577 for 32 bit samples, etc), or bad things will happen downstream as
3578 elements typically assume minimal alignment.
3579 Therefore, create an aligned copy if necessary. */
3580 g_assert (stream->alignment <= G_MEM_ALIGN);
3581 if (((guintptr) GST_BUFFER_DATA (sub)) & (stream->alignment - 1)) {
3582 GstBuffer *buffer = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (sub));
3583 memcpy (GST_BUFFER_DATA (buffer), GST_BUFFER_DATA (sub),
3584 GST_BUFFER_SIZE (sub));
3585 gst_buffer_copy_metadata (buffer, sub, GST_BUFFER_COPY_ALL);
3586 GST_DEBUG_OBJECT (demux, "We want output aligned on %d, reallocated",
3588 gst_buffer_unref (sub);
3592 ret = gst_pad_push (stream->pad, sub);
3593 if (demux->common.segment.rate < 0) {
3594 if (lace_time > demux->common.segment.stop
3595 && ret == GST_FLOW_UNEXPECTED) {
3596 /* In reverse playback we can get a GST_FLOW_UNEXPECTED when
3597 * we are at the end of the segment, so we just need to jump
3598 * back to the previous section. */
3599 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3604 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3607 size -= lace_size[n];
3608 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3609 lace_time += duration / laces;
3611 lace_time = GST_CLOCK_TIME_NONE;
3617 gst_buffer_unref (buf);
3628 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3633 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3634 /* non-fatal, try next block(group) */
3640 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3641 /* non-fatal, try next block(group) */
3647 /* return FALSE if block(group) should be skipped (due to a seek) */
3648 static inline gboolean
3649 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3651 if (G_UNLIKELY (demux->seek_block)) {
3652 if (!(--demux->seek_block)) {
3655 GST_LOG_OBJECT (demux, "should skip block due to seek");
3663 static GstFlowReturn
3664 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3668 guint64 seek_pos = (guint64) - 1;
3669 guint32 seek_id = 0;
3672 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3674 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3675 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3679 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3680 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3684 case GST_MATROSKA_ID_SEEKID:
3688 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3691 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3696 case GST_MATROSKA_ID_SEEKPOSITION:
3700 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3703 if (t > G_MAXINT64) {
3704 GST_WARNING_OBJECT (demux,
3705 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3709 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3715 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3721 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
3724 if (!seek_id || seek_pos == (guint64) - 1) {
3725 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3726 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3731 case GST_MATROSKA_ID_SEEKHEAD:
3734 case GST_MATROSKA_ID_CUES:
3735 case GST_MATROSKA_ID_TAGS:
3736 case GST_MATROSKA_ID_TRACKS:
3737 case GST_MATROSKA_ID_SEGMENTINFO:
3738 case GST_MATROSKA_ID_ATTACHMENTS:
3739 case GST_MATROSKA_ID_CHAPTERS:
3741 guint64 before_pos, length;
3745 length = gst_matroska_read_common_get_length (&demux->common);
3746 before_pos = demux->common.offset;
3748 if (length == (guint64) - 1) {
3749 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3753 /* check for validity */
3754 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3755 GST_WARNING_OBJECT (demux,
3756 "SeekHead reference lies outside file!" " (%"
3757 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3758 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3763 /* only pick up index location when streaming */
3764 if (demux->streaming) {
3765 if (seek_id == GST_MATROSKA_ID_CUES) {
3766 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3767 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3768 demux->index_offset);
3774 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3777 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3778 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3782 if (id != seek_id) {
3783 GST_WARNING_OBJECT (demux,
3784 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3785 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3788 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3793 demux->common.offset = before_pos;
3797 case GST_MATROSKA_ID_CLUSTER:
3799 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3801 GST_LOG_OBJECT (demux, "Cluster position");
3802 if (G_UNLIKELY (!demux->clusters))
3803 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3804 g_array_append_val (demux->clusters, pos);
3809 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3812 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3817 static GstFlowReturn
3818 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3820 GstFlowReturn ret = GST_FLOW_OK;
3823 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3825 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3826 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3830 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3831 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3835 case GST_MATROSKA_ID_SEEKENTRY:
3837 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3838 /* Ignore EOS and errors here */
3839 if (ret != GST_FLOW_OK) {
3840 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3847 ret = gst_matroska_read_common_parse_skip (&demux->common,
3848 ebml, "SeekHead", id);
3853 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3855 /* Sort clusters by position for easier searching */
3856 if (demux->clusters)
3857 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3862 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3864 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3866 static inline GstFlowReturn
3867 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
3869 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
3870 /* only a few blocks are expected/allowed to be large,
3871 * and will be recursed into, whereas others will be read and must fit */
3872 if (demux->streaming) {
3873 /* fatal in streaming case, as we can't step over easily */
3874 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3875 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
3876 "file might be corrupt.", bytes));
3877 return GST_FLOW_ERROR;
3879 /* indicate higher level to quietly give up */
3880 GST_DEBUG_OBJECT (demux,
3881 "too large block of size %" G_GUINT64_FORMAT, bytes);
3882 return GST_FLOW_ERROR;
3889 /* returns TRUE if we truely are in error state, and should give up */
3890 static inline gboolean
3891 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
3893 if (!demux->streaming && demux->next_cluster_offset > 0) {
3894 /* just repositioning to where next cluster should be and try from there */
3895 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
3896 G_GUINT64_FORMAT, demux->next_cluster_offset);
3897 demux->common.offset = demux->next_cluster_offset;
3898 demux->next_cluster_offset = 0;
3903 /* sigh, one last attempt above and beyond call of duty ...;
3904 * search for cluster mark following current pos */
3905 pos = demux->common.offset;
3906 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
3907 if (gst_matroska_demux_search_cluster (demux, &pos) != GST_FLOW_OK) {
3908 /* did not work, give up */
3911 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
3912 /* try that position */
3913 demux->common.offset = pos;
3919 static inline GstFlowReturn
3920 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
3922 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
3923 demux->common.offset += flush;
3924 if (demux->streaming) {
3927 /* hard to skip large blocks when streaming */
3928 ret = gst_matroska_demux_check_read_size (demux, flush);
3929 if (ret != GST_FLOW_OK)
3931 if (flush <= gst_adapter_available (demux->common.adapter))
3932 gst_adapter_flush (demux->common.adapter, flush);
3934 return GST_FLOW_UNEXPECTED;
3939 /* initializes @ebml with @bytes from input stream at current offset.
3940 * Returns UNEXPECTED if insufficient available,
3941 * ERROR if too much was attempted to read. */
3942 static inline GstFlowReturn
3943 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
3946 GstBuffer *buffer = NULL;
3947 GstFlowReturn ret = GST_FLOW_OK;
3949 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
3951 ret = gst_matroska_demux_check_read_size (demux, bytes);
3952 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
3953 if (!demux->streaming) {
3954 /* in pull mode, we can skip */
3955 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
3956 ret = GST_FLOW_OVERFLOW;
3958 /* otherwise fatal */
3959 ret = GST_FLOW_ERROR;
3963 if (demux->streaming) {
3964 if (gst_adapter_available (demux->common.adapter) >= bytes)
3965 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
3967 ret = GST_FLOW_UNEXPECTED;
3969 ret = gst_matroska_read_common_peek_bytes (&demux->common,
3970 demux->common.offset, bytes, &buffer, NULL);
3971 if (G_LIKELY (buffer)) {
3972 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
3973 demux->common.offset);
3974 demux->common.offset += bytes;
3981 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
3984 gboolean seekable = FALSE;
3985 gint64 start = -1, stop = -1;
3987 query = gst_query_new_seeking (GST_FORMAT_BYTES);
3988 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
3989 GST_DEBUG_OBJECT (demux, "seeking query failed");
3993 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
3995 /* try harder to query upstream size if we didn't get it the first time */
3996 if (seekable && stop == -1) {
3997 GstFormat fmt = GST_FORMAT_BYTES;
3999 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4000 gst_pad_query_peer_duration (demux->common.sinkpad, &fmt, &stop);
4003 /* if upstream doesn't know the size, it's likely that it's not seekable in
4004 * practice even if it technically may be seekable */
4005 if (seekable && (start != 0 || stop <= start)) {
4006 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4011 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4012 G_GUINT64_FORMAT ")", seekable, start, stop);
4013 demux->seekable = seekable;
4015 gst_query_unref (query);
4018 static GstFlowReturn
4019 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4025 GstFlowReturn ret = GST_FLOW_OK;
4027 GST_WARNING_OBJECT (demux,
4028 "Found Cluster element before Tracks, searching Tracks");
4031 before_pos = demux->common.offset;
4033 /* Search Tracks element */
4035 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4036 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4037 if (ret != GST_FLOW_OK)
4040 if (id != GST_MATROSKA_ID_TRACKS) {
4041 /* we may be skipping large cluster here, so forego size check etc */
4042 /* ... but we can't skip undefined size; force error */
4043 if (length == G_MAXUINT64) {
4044 ret = gst_matroska_demux_check_read_size (demux, length);
4047 demux->common.offset += needed;
4048 demux->common.offset += length;
4053 /* will lead to track parsing ... */
4054 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4059 demux->common.offset = before_pos;
4064 #define GST_READ_CHECK(stmt) \
4066 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4067 if (ret == GST_FLOW_OVERFLOW) { \
4068 ret = GST_FLOW_OK; \
4074 static GstFlowReturn
4075 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4076 guint64 length, guint needed)
4078 GstEbmlRead ebml = { 0, };
4079 GstFlowReturn ret = GST_FLOW_OK;
4082 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4083 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4085 /* if we plan to read and parse this element, we need prefix (id + length)
4086 * and the contents */
4087 /* mind about overflow wrap-around when dealing with undefined size */
4089 if (G_LIKELY (length != G_MAXUINT64))
4092 switch (demux->common.state) {
4093 case GST_MATROSKA_READ_STATE_START:
4095 case GST_EBML_ID_HEADER:
4096 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4097 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4098 if (ret != GST_FLOW_OK)
4100 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4101 gst_matroska_demux_check_seekability (demux);
4104 goto invalid_header;
4108 case GST_MATROSKA_READ_STATE_SEGMENT:
4110 case GST_MATROSKA_ID_SEGMENT:
4111 /* eat segment prefix */
4112 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4113 GST_DEBUG_OBJECT (demux,
4114 "Found Segment start at offset %" G_GUINT64_FORMAT,
4115 demux->common.offset);
4116 /* seeks are from the beginning of the segment,
4117 * after the segment ID/length */
4118 demux->common.ebml_segment_start = demux->common.offset;
4119 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4122 GST_WARNING_OBJECT (demux,
4123 "Expected a Segment ID (0x%x), but received 0x%x!",
4124 GST_MATROSKA_ID_SEGMENT, id);
4125 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4129 case GST_MATROSKA_READ_STATE_SCANNING:
4130 if (id != GST_MATROSKA_ID_CLUSTER &&
4131 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4134 case GST_MATROSKA_READ_STATE_HEADER:
4135 case GST_MATROSKA_READ_STATE_DATA:
4136 case GST_MATROSKA_READ_STATE_SEEK:
4138 case GST_MATROSKA_ID_SEGMENTINFO:
4139 if (!demux->common.segmentinfo_parsed) {
4140 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4141 ret = gst_matroska_read_common_parse_info (&demux->common,
4142 GST_ELEMENT_CAST (demux), &ebml);
4144 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4147 case GST_MATROSKA_ID_TRACKS:
4148 if (!demux->tracks_parsed) {
4149 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4150 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4152 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4155 case GST_MATROSKA_ID_CLUSTER:
4156 if (G_UNLIKELY (!demux->tracks_parsed)) {
4157 if (demux->streaming) {
4158 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4159 goto not_streamable;
4161 ret = gst_matroska_demux_find_tracks (demux);
4162 if (!demux->tracks_parsed)
4166 if (G_UNLIKELY (demux->common.state
4167 == GST_MATROSKA_READ_STATE_HEADER)) {
4168 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4169 demux->first_cluster_offset = demux->common.offset;
4170 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4171 gst_element_no_more_pads (GST_ELEMENT (demux));
4172 /* send initial newsegment - we wait till we know the first
4173 incoming timestamp, so we can properly set the start of
4175 demux->need_newsegment = TRUE;
4177 demux->cluster_time = GST_CLOCK_TIME_NONE;
4178 demux->cluster_offset = demux->common.offset;
4179 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4180 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4181 " not found in Cluster, trying next Cluster's first block instead",
4183 demux->seek_block = 0;
4185 demux->seek_first = FALSE;
4186 /* record next cluster for recovery */
4187 if (read != G_MAXUINT64)
4188 demux->next_cluster_offset = demux->cluster_offset + read;
4189 /* eat cluster prefix */
4190 gst_matroska_demux_flush (demux, needed);
4192 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4196 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4197 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4199 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4200 demux->cluster_time = num;
4201 if (demux->common.element_index) {
4202 if (demux->common.element_index_writer_id == -1)
4203 gst_index_get_writer_id (demux->common.element_index,
4204 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4205 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4206 G_GUINT64_FORMAT " for writer id %d",
4207 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4208 demux->common.element_index_writer_id);
4209 gst_index_add_association (demux->common.element_index,
4210 demux->common.element_index_writer_id,
4211 GST_ASSOCIATION_FLAG_KEY_UNIT,
4212 GST_FORMAT_TIME, demux->cluster_time,
4213 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4217 case GST_MATROSKA_ID_BLOCKGROUP:
4218 if (!gst_matroska_demux_seek_block (demux))
4220 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4221 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4222 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4223 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4224 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4226 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4228 case GST_MATROSKA_ID_SIMPLEBLOCK:
4229 if (!gst_matroska_demux_seek_block (demux))
4231 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4232 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4233 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4234 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4235 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4237 case GST_MATROSKA_ID_ATTACHMENTS:
4238 if (!demux->common.attachments_parsed) {
4239 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4240 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4241 GST_ELEMENT_CAST (demux), &ebml);
4243 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4246 case GST_MATROSKA_ID_TAGS:
4247 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4248 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4249 GST_ELEMENT_CAST (demux), &ebml);
4251 case GST_MATROSKA_ID_CHAPTERS:
4252 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4253 ret = gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4255 case GST_MATROSKA_ID_SEEKHEAD:
4256 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4257 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4259 case GST_MATROSKA_ID_CUES:
4260 if (demux->common.index_parsed) {
4261 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4264 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4265 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4266 /* only push based; delayed index building */
4267 if (ret == GST_FLOW_OK
4268 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4271 GST_OBJECT_LOCK (demux);
4272 event = demux->seek_event;
4273 demux->seek_event = NULL;
4274 GST_OBJECT_UNLOCK (demux);
4277 /* unlikely to fail, since we managed to seek to this point */
4278 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4280 /* resume data handling, main thread clear to seek again */
4281 GST_OBJECT_LOCK (demux);
4282 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4283 GST_OBJECT_UNLOCK (demux);
4286 case GST_MATROSKA_ID_POSITION:
4287 case GST_MATROSKA_ID_PREVSIZE:
4288 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4289 case GST_MATROSKA_ID_SILENTTRACKS:
4290 GST_DEBUG_OBJECT (demux,
4291 "Skipping Cluster subelement 0x%x - ignoring", id);
4295 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4296 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4302 if (ret == GST_FLOW_PARSE)
4306 gst_ebml_read_clear (&ebml);
4312 /* simply exit, maybe not enough data yet */
4313 /* no ebml to clear if read error */
4318 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4319 ("Failed to parse Element 0x%x", id));
4320 ret = GST_FLOW_ERROR;
4325 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4326 ("File layout does not permit streaming"));
4327 ret = GST_FLOW_ERROR;
4332 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4333 ("No Tracks element found"));
4334 ret = GST_FLOW_ERROR;
4339 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4340 ret = GST_FLOW_ERROR;
4345 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4346 ret = GST_FLOW_ERROR;
4352 gst_matroska_demux_loop (GstPad * pad)
4354 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4360 /* If we have to close a segment, send a new segment to do this now */
4361 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4362 if (G_UNLIKELY (demux->close_segment)) {
4363 gst_matroska_demux_send_event (demux, demux->close_segment);
4364 demux->close_segment = NULL;
4366 if (G_UNLIKELY (demux->new_segment)) {
4367 gst_matroska_demux_send_event (demux, demux->new_segment);
4368 demux->new_segment = NULL;
4372 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4373 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4374 if (ret == GST_FLOW_UNEXPECTED)
4376 if (ret != GST_FLOW_OK) {
4377 if (gst_matroska_demux_check_parse_error (demux))
4383 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4384 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4387 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4388 if (ret == GST_FLOW_UNEXPECTED)
4390 if (ret != GST_FLOW_OK)
4393 /* check if we're at the end of a configured segment */
4394 if (G_LIKELY (demux->common.src->len)) {
4397 g_assert (demux->common.num_streams == demux->common.src->len);
4398 for (i = 0; i < demux->common.src->len; i++) {
4399 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4401 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4402 GST_TIME_ARGS (context->pos));
4403 if (context->eos == FALSE)
4407 GST_INFO_OBJECT (demux, "All streams are EOS");
4408 ret = GST_FLOW_UNEXPECTED;
4413 if (G_UNLIKELY (demux->common.offset ==
4414 gst_matroska_read_common_get_length (&demux->common))) {
4415 GST_LOG_OBJECT (demux, "Reached end of stream");
4416 ret = GST_FLOW_UNEXPECTED;
4425 if (demux->common.segment.rate < 0.0) {
4426 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4427 if (ret == GST_FLOW_OK)
4434 const gchar *reason = gst_flow_get_name (ret);
4435 gboolean push_eos = FALSE;
4437 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4438 demux->segment_running = FALSE;
4439 gst_pad_pause_task (demux->common.sinkpad);
4441 if (ret == GST_FLOW_UNEXPECTED) {
4442 /* perform EOS logic */
4444 /* If we were in the headers, make sure we send no-more-pads.
4445 This will ensure decodebin2 does not get stuck thinking
4446 the chain is not complete yet, and waiting indefinitely. */
4447 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4448 if (demux->common.src->len == 0) {
4449 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4450 ("No pads created"));
4452 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4453 ("Failed to finish reading headers"));
4455 gst_element_no_more_pads (GST_ELEMENT (demux));
4458 /* Close the segment, i.e. update segment stop with the duration
4459 * if no stop was set */
4460 if (GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
4461 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
4462 GST_CLOCK_TIME_IS_VALID (demux->common.segment.start) &&
4463 demux->last_stop_end > demux->common.segment.start) {
4464 /* arrange to accumulate duration downstream, but avoid sending
4465 * newsegment with decreasing start (w.r.t. sync newsegment events) */
4467 gst_event_new_new_segment_full (TRUE, demux->common.segment.rate,
4468 demux->common.segment.applied_rate, demux->common.segment.format,
4469 demux->last_stop_end, demux->last_stop_end,
4470 demux->common.segment.time + (demux->last_stop_end -
4471 demux->common.segment.start));
4472 gst_matroska_demux_send_event (demux, event);
4475 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4478 /* for segment playback we need to post when (in stream time)
4479 * we stopped, this is either stop (when set) or the duration. */
4480 if ((stop = demux->common.segment.stop) == -1)
4481 stop = demux->last_stop_end;
4483 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4484 gst_element_post_message (GST_ELEMENT (demux),
4485 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4490 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_UNEXPECTED) {
4491 /* for fatal errors we post an error message */
4492 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4493 ("stream stopped, reason %s", reason));
4497 /* send EOS, and prevent hanging if no streams yet */
4498 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4499 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4500 (ret == GST_FLOW_UNEXPECTED)) {
4501 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4502 (NULL), ("got eos but no streams (yet)"));
4510 * Create and push a flushing seek event upstream
4513 perform_seek_to_offset (GstMatroskaDemux * demux, guint64 offset)
4518 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4521 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
4522 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4523 GST_SEEK_TYPE_NONE, -1);
4525 res = gst_pad_push_event (demux->common.sinkpad, event);
4527 /* newsegment event will update offset */
4531 static GstFlowReturn
4532 gst_matroska_demux_chain (GstPad * pad, GstBuffer * buffer)
4534 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4536 GstFlowReturn ret = GST_FLOW_OK;
4541 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4542 GST_DEBUG_OBJECT (demux, "got DISCONT");
4543 gst_adapter_clear (demux->common.adapter);
4544 GST_OBJECT_LOCK (demux);
4545 gst_matroska_read_common_reset_streams (&demux->common,
4546 GST_CLOCK_TIME_NONE, FALSE);
4547 GST_OBJECT_UNLOCK (demux);
4550 gst_adapter_push (demux->common.adapter, buffer);
4554 available = gst_adapter_available (demux->common.adapter);
4556 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4557 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4558 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED))
4561 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4562 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4563 demux->common.offset, id, length, needed, available);
4565 if (needed > available)
4568 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4569 if (ret == GST_FLOW_UNEXPECTED) {
4570 /* need more data */
4572 } else if (ret != GST_FLOW_OK) {
4579 gst_matroska_demux_handle_sink_event (GstPad * pad, GstEvent * event)
4581 gboolean res = TRUE;
4582 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4584 GST_DEBUG_OBJECT (demux,
4585 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4587 switch (GST_EVENT_TYPE (event)) {
4588 case GST_EVENT_NEWSEGMENT:
4591 gdouble rate, arate;
4592 gint64 start, stop, time = 0;
4596 /* some debug output */
4597 gst_segment_init (&segment, GST_FORMAT_UNDEFINED);
4598 gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
4599 &start, &stop, &time);
4600 gst_segment_set_newsegment_full (&segment, update, rate, arate, format,
4602 GST_DEBUG_OBJECT (demux,
4603 "received format %d newsegment %" GST_SEGMENT_FORMAT, format,
4606 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4607 GST_DEBUG_OBJECT (demux, "still starting");
4611 /* we only expect a BYTE segment, e.g. following a seek */
4612 if (format != GST_FORMAT_BYTES) {
4613 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4617 GST_DEBUG_OBJECT (demux, "clearing segment state");
4618 GST_OBJECT_LOCK (demux);
4619 /* clear current segment leftover */
4620 gst_adapter_clear (demux->common.adapter);
4621 /* and some streaming setup */
4622 demux->common.offset = start;
4623 /* do not know where we are;
4624 * need to come across a cluster and generate newsegment */
4625 demux->common.segment.last_stop = GST_CLOCK_TIME_NONE;
4626 demux->cluster_time = GST_CLOCK_TIME_NONE;
4627 demux->cluster_offset = 0;
4628 demux->need_newsegment = TRUE;
4629 /* but keep some of the upstream segment */
4630 demux->common.segment.rate = rate;
4631 GST_OBJECT_UNLOCK (demux);
4633 /* chain will send initial newsegment after pads have been added,
4634 * or otherwise come up with one */
4635 GST_DEBUG_OBJECT (demux, "eating event");
4636 gst_event_unref (event);
4642 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4643 gst_event_unref (event);
4644 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4645 (NULL), ("got eos and didn't receive a complete header object"));
4646 } else if (demux->common.num_streams == 0) {
4647 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4648 (NULL), ("got eos but no streams (yet)"));
4650 gst_matroska_demux_send_event (demux, event);
4654 case GST_EVENT_FLUSH_STOP:
4656 gst_adapter_clear (demux->common.adapter);
4657 GST_OBJECT_LOCK (demux);
4658 gst_matroska_read_common_reset_streams (&demux->common,
4659 GST_CLOCK_TIME_NONE, TRUE);
4660 demux->common.segment.last_stop = GST_CLOCK_TIME_NONE;
4661 demux->cluster_time = GST_CLOCK_TIME_NONE;
4662 demux->cluster_offset = 0;
4663 GST_OBJECT_UNLOCK (demux);
4667 res = gst_pad_event_default (pad, event);
4675 gst_matroska_demux_sink_activate (GstPad * sinkpad)
4677 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
4679 if (gst_pad_check_pull_range (sinkpad)) {
4680 GST_DEBUG ("going to pull mode");
4681 demux->streaming = FALSE;
4682 return gst_pad_activate_pull (sinkpad, TRUE);
4684 GST_DEBUG ("going to push (streaming) mode");
4685 demux->streaming = TRUE;
4686 return gst_pad_activate_push (sinkpad, TRUE);
4693 gst_matroska_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
4695 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
4698 /* if we have a scheduler we can start the task */
4699 demux->segment_running = TRUE;
4700 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4703 demux->segment_running = FALSE;
4704 gst_pad_stop_task (sinkpad);
4711 gst_duration_to_fraction (guint64 duration, gint * dest_n, gint * dest_d)
4713 static const int common_den[] = { 1, 2, 3, 4, 1001 };
4718 for (i = 0; i < G_N_ELEMENTS (common_den); i++) {
4720 n = floor (0.5 + (d * 1e9) / duration);
4721 a = gst_util_uint64_scale_int (1000000000, d, n);
4722 if (duration >= a - 1 && duration <= a + 1) {
4727 gst_util_double_to_fraction (1e9 / duration, &n, &d);
4736 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4737 videocontext, const gchar * codec_id, guint8 * data, guint size,
4738 gchar ** codec_name, guint32 * riff_fourcc)
4740 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4741 GstCaps *caps = NULL;
4743 g_assert (videocontext != NULL);
4744 g_assert (codec_name != NULL);
4746 context->send_xiph_headers = FALSE;
4747 context->send_flac_headers = FALSE;
4748 context->send_speex_headers = FALSE;
4753 /* TODO: check if we have all codec types from matroska-ids.h
4754 * check if we have to do more special things with codec_private
4757 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4758 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4761 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4762 gst_riff_strf_vids *vids = NULL;
4765 GstBuffer *buf = NULL;
4767 vids = (gst_riff_strf_vids *) data;
4769 /* assure size is big enough */
4771 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4774 if (size < sizeof (gst_riff_strf_vids)) {
4775 vids = g_new (gst_riff_strf_vids, 1);
4776 memcpy (vids, data, size);
4779 /* little-endian -> byte-order */
4780 vids->size = GUINT32_FROM_LE (vids->size);
4781 vids->width = GUINT32_FROM_LE (vids->width);
4782 vids->height = GUINT32_FROM_LE (vids->height);
4783 vids->planes = GUINT16_FROM_LE (vids->planes);
4784 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4785 vids->compression = GUINT32_FROM_LE (vids->compression);
4786 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4787 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4788 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4789 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4790 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4792 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4793 buf = gst_buffer_new_and_alloc (size - sizeof (gst_riff_strf_vids));
4794 memcpy (GST_BUFFER_DATA (buf),
4795 (guint8 *) vids + sizeof (gst_riff_strf_vids),
4796 GST_BUFFER_SIZE (buf));
4800 *riff_fourcc = vids->compression;
4802 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4803 buf, NULL, codec_name);
4806 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4807 GST_FOURCC_ARGS (vids->compression));
4811 gst_buffer_unref (buf);
4813 if (vids != (gst_riff_strf_vids *) data)
4816 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4819 switch (videocontext->fourcc) {
4820 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4821 *codec_name = g_strdup ("Raw planar YUV 4:2:0");
4822 fourcc = videocontext->fourcc;
4824 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4825 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
4826 fourcc = videocontext->fourcc;
4828 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4829 *codec_name = g_strdup ("Raw packed YUV 4:2:0");
4830 fourcc = videocontext->fourcc;
4832 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4833 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
4834 fourcc = videocontext->fourcc;
4836 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4837 *codec_name = g_strdup ("Raw packed YUV 4:4:4 with alpha channel");
4838 fourcc = videocontext->fourcc;
4842 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
4843 GST_FOURCC_ARGS (videocontext->fourcc));
4847 caps = gst_caps_new_simple ("video/x-raw-yuv",
4848 "format", GST_TYPE_FOURCC, fourcc, NULL);
4849 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
4850 caps = gst_caps_new_simple ("video/x-divx",
4851 "divxversion", G_TYPE_INT, 4, NULL);
4852 *codec_name = g_strdup ("MPEG-4 simple profile");
4853 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
4854 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
4856 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4857 "divxversion", G_TYPE_INT, 5, NULL),
4858 gst_structure_new ("video/x-xvid", NULL),
4859 gst_structure_new ("video/mpeg",
4860 "mpegversion", G_TYPE_INT, 4,
4861 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
4863 caps = gst_caps_new_simple ("video/mpeg",
4864 "mpegversion", G_TYPE_INT, 4,
4865 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
4867 GstBuffer *priv = gst_buffer_new_and_alloc (size);
4869 memcpy (GST_BUFFER_DATA (priv), data, size);
4870 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4871 gst_buffer_unref (priv);
4873 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
4874 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
4876 *codec_name = g_strdup ("MPEG-4 advanced profile");
4877 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
4879 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4880 "divxversion", G_TYPE_INT, 3, NULL),
4881 gst_structure_new ("video/x-msmpeg",
4882 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
4884 caps = gst_caps_new_simple ("video/x-msmpeg",
4885 "msmpegversion", G_TYPE_INT, 43, NULL);
4886 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
4887 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
4888 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
4891 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
4896 caps = gst_caps_new_simple ("video/mpeg",
4897 "systemstream", G_TYPE_BOOLEAN, FALSE,
4898 "mpegversion", G_TYPE_INT, mpegversion, NULL);
4899 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
4900 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
4901 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
4902 caps = gst_caps_new_simple ("image/jpeg", NULL);
4903 *codec_name = g_strdup ("Motion-JPEG");
4904 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
4905 caps = gst_caps_new_simple ("video/x-h264", NULL);
4907 GstBuffer *priv = gst_buffer_new_and_alloc (size);
4909 /* First byte is the version, second is the profile indication, and third
4910 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
4911 * level indication. */
4912 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
4915 memcpy (GST_BUFFER_DATA (priv), data, size);
4916 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4917 gst_buffer_unref (priv);
4919 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
4920 "alignment", G_TYPE_STRING, "au", NULL);
4922 GST_WARNING ("No codec data found, assuming output is byte-stream");
4923 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
4926 *codec_name = g_strdup ("H264");
4927 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
4928 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
4929 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
4930 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
4931 gint rmversion = -1;
4933 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
4935 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
4937 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
4939 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
4942 caps = gst_caps_new_simple ("video/x-pn-realvideo",
4943 "rmversion", G_TYPE_INT, rmversion, NULL);
4944 GST_DEBUG ("data:%p, size:0x%x", data, size);
4945 /* We need to extract the extradata ! */
4946 if (data && (size >= 0x22)) {
4951 subformat = GST_READ_UINT32_BE (data + 0x1a);
4952 rformat = GST_READ_UINT32_BE (data + 0x1e);
4954 priv = gst_buffer_new_and_alloc (size - 0x1a);
4956 memcpy (GST_BUFFER_DATA (priv), data + 0x1a, size - 0x1a);
4957 gst_caps_set_simple (caps,
4958 "codec_data", GST_TYPE_BUFFER, priv,
4959 "format", G_TYPE_INT, rformat,
4960 "subformat", G_TYPE_INT, subformat, NULL);
4961 gst_buffer_unref (priv);
4964 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
4965 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
4966 caps = gst_caps_new_simple ("video/x-theora", NULL);
4967 context->send_xiph_headers = TRUE;
4968 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
4969 caps = gst_caps_new_simple ("video/x-dirac", NULL);
4970 *codec_name = g_strdup_printf ("Dirac");
4971 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
4972 caps = gst_caps_new_simple ("video/x-vp8", NULL);
4973 *codec_name = g_strdup_printf ("On2 VP8");
4975 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
4981 GstStructure *structure;
4983 for (i = 0; i < gst_caps_get_size (caps); i++) {
4984 structure = gst_caps_get_structure (caps, i);
4986 /* FIXME: use the real unit here! */
4987 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
4988 videocontext->pixel_width,
4989 videocontext->pixel_height,
4990 videocontext->display_width, videocontext->display_height);
4992 /* pixel width and height are the w and h of the video in pixels */
4993 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
4994 gint w = videocontext->pixel_width;
4995 gint h = videocontext->pixel_height;
4997 gst_structure_set (structure,
4998 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5001 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5004 if (videocontext->display_width <= 0)
5005 videocontext->display_width = videocontext->pixel_width;
5006 if (videocontext->display_height <= 0)
5007 videocontext->display_height = videocontext->pixel_height;
5009 /* calculate the pixel aspect ratio using the display and pixel w/h */
5010 n = videocontext->display_width * videocontext->pixel_height;
5011 d = videocontext->display_height * videocontext->pixel_width;
5012 GST_DEBUG ("setting PAR to %d/%d", n, d);
5013 gst_structure_set (structure, "pixel-aspect-ratio",
5015 videocontext->display_width * videocontext->pixel_height,
5016 videocontext->display_height * videocontext->pixel_width, NULL);
5019 if (videocontext->default_fps > 0.0) {
5020 GValue fps_double = { 0, };
5021 GValue fps_fraction = { 0, };
5023 g_value_init (&fps_double, G_TYPE_DOUBLE);
5024 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
5025 g_value_set_double (&fps_double, videocontext->default_fps);
5026 g_value_transform (&fps_double, &fps_fraction);
5028 GST_DEBUG ("using default fps %f", videocontext->default_fps);
5030 gst_structure_set_value (structure, "framerate", &fps_fraction);
5031 g_value_unset (&fps_double);
5032 g_value_unset (&fps_fraction);
5033 } else if (context->default_duration > 0) {
5036 gst_duration_to_fraction (context->default_duration, &fps_n, &fps_d);
5038 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5039 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5041 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5042 fps_n, fps_d, NULL);
5044 /* sort of a hack to get most codecs to support,
5045 * even if the default_duration is missing */
5046 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5050 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5051 gst_structure_set (structure, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
5054 gst_caps_do_simplify (caps);
5061 * Some AAC specific code... *sigh*
5062 * FIXME: maybe we should use '15' and code the sample rate explicitly
5063 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5067 aac_rate_idx (gint rate)
5071 else if (75132 <= rate)
5073 else if (55426 <= rate)
5075 else if (46009 <= rate)
5077 else if (37566 <= rate)
5079 else if (27713 <= rate)
5081 else if (23004 <= rate)
5083 else if (18783 <= rate)
5085 else if (13856 <= rate)
5087 else if (11502 <= rate)
5089 else if (9391 <= rate)
5096 aac_profile_idx (const gchar * codec_id)
5100 if (strlen (codec_id) <= 12)
5102 else if (!strncmp (&codec_id[12], "MAIN", 4))
5104 else if (!strncmp (&codec_id[12], "LC", 2))
5106 else if (!strncmp (&codec_id[12], "SSR", 3))
5114 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5117 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5118 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5119 gchar ** codec_name, guint16 * riff_audio_fmt)
5121 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5122 GstCaps *caps = NULL;
5124 g_assert (audiocontext != NULL);
5125 g_assert (codec_name != NULL);
5128 *riff_audio_fmt = 0;
5130 context->send_xiph_headers = FALSE;
5131 context->send_flac_headers = FALSE;
5132 context->send_speex_headers = FALSE;
5134 /* TODO: check if we have all codec types from matroska-ids.h
5135 * check if we have to do more special things with codec_private
5136 * check if we need bitdepth in different places too
5137 * implement channel position magic
5139 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5140 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5141 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5142 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5145 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5146 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5147 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5150 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5152 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5157 caps = gst_caps_new_simple ("audio/mpeg",
5158 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5159 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5160 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5161 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5164 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5165 endianness = G_BIG_ENDIAN;
5167 endianness = G_LITTLE_ENDIAN;
5169 caps = gst_caps_new_simple ("audio/x-raw-int",
5170 "width", G_TYPE_INT, audiocontext->bitdepth,
5171 "depth", G_TYPE_INT, audiocontext->bitdepth,
5172 "signed", G_TYPE_BOOLEAN, audiocontext->bitdepth != 8,
5173 "endianness", G_TYPE_INT, endianness, NULL);
5175 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5176 audiocontext->bitdepth);
5177 context->alignment = audiocontext->bitdepth / 8;
5178 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5179 caps = gst_caps_new_simple ("audio/x-raw-float",
5180 "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
5181 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5182 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5183 audiocontext->bitdepth);
5184 context->alignment = audiocontext->bitdepth / 8;
5185 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5186 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5187 caps = gst_caps_new_simple ("audio/x-ac3",
5188 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5189 *codec_name = g_strdup ("AC-3 audio");
5190 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5191 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5192 caps = gst_caps_new_simple ("audio/x-eac3",
5193 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5194 *codec_name = g_strdup ("E-AC-3 audio");
5195 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5196 caps = gst_caps_new_simple ("audio/x-dts", NULL);
5197 *codec_name = g_strdup ("DTS audio");
5198 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5199 caps = gst_caps_new_simple ("audio/x-vorbis", NULL);
5200 context->send_xiph_headers = TRUE;
5201 /* vorbis decoder does tags */
5202 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5203 caps = gst_caps_new_simple ("audio/x-flac", NULL);
5204 context->send_flac_headers = TRUE;
5205 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5206 caps = gst_caps_new_simple ("audio/x-speex", NULL);
5207 context->send_speex_headers = TRUE;
5208 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5209 gst_riff_strf_auds auds;
5212 GstBuffer *codec_data = gst_buffer_new ();
5214 /* little-endian -> byte-order */
5215 auds.format = GST_READ_UINT16_LE (data);
5216 auds.channels = GST_READ_UINT16_LE (data + 2);
5217 auds.rate = GST_READ_UINT32_LE (data + 4);
5218 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5219 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5220 auds.size = GST_READ_UINT16_LE (data + 16);
5222 /* 18 is the waveformatex size */
5223 gst_buffer_set_data (codec_data, data + 18, auds.size);
5226 *riff_audio_fmt = auds.format;
5228 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5229 codec_data, codec_name);
5230 gst_buffer_unref (codec_data);
5233 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5236 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5237 GstBuffer *priv = NULL;
5239 gint rate_idx, profile;
5240 guint8 *data = NULL;
5242 /* unspecified AAC profile with opaque private codec data */
5243 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5244 if (context->codec_priv_size >= 2) {
5245 guint obj_type, freq_index, explicit_freq_bytes = 0;
5247 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5249 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5250 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5251 if (freq_index == 15)
5252 explicit_freq_bytes = 3;
5253 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5254 priv = gst_buffer_new_and_alloc (context->codec_priv_size);
5255 memcpy (GST_BUFFER_DATA (priv), context->codec_priv,
5256 context->codec_priv_size);
5257 /* assume SBR if samplerate <= 24kHz */
5258 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5259 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5260 audiocontext->samplerate *= 2;
5263 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5264 /* this is pretty broken;
5265 * maybe we need to make up some default private,
5266 * or maybe ADTS data got dumped in.
5267 * Let's set up some private data now, and check actual data later */
5268 /* just try this and see what happens ... */
5269 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5270 context->postprocess_frame = gst_matroska_demux_check_aac;
5274 /* make up decoder-specific data if it is not supplied */
5276 priv = gst_buffer_new_and_alloc (5);
5277 data = GST_BUFFER_DATA (priv);
5278 rate_idx = aac_rate_idx (audiocontext->samplerate);
5279 profile = aac_profile_idx (codec_id);
5281 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5282 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5283 GST_BUFFER_SIZE (priv) = 2;
5285 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5286 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5288 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5289 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5292 if (g_strrstr (codec_id, "SBR")) {
5293 /* HE-AAC (aka SBR AAC) */
5294 audiocontext->samplerate *= 2;
5295 rate_idx = aac_rate_idx (audiocontext->samplerate);
5296 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5297 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5298 data[4] = (1 << 7) | (rate_idx << 3);
5299 GST_BUFFER_SIZE (priv) = 5;
5302 gst_buffer_unref (priv);
5304 GST_ERROR ("Unknown AAC profile and no codec private data");
5309 caps = gst_caps_new_simple ("audio/mpeg",
5310 "mpegversion", G_TYPE_INT, mpegversion,
5311 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5312 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5313 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5314 gst_buffer_unref (priv);
5316 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5317 caps = gst_caps_new_simple ("audio/x-tta",
5318 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5319 *codec_name = g_strdup ("TTA audio");
5320 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5321 caps = gst_caps_new_simple ("audio/x-wavpack",
5322 "width", G_TYPE_INT, audiocontext->bitdepth,
5323 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5324 *codec_name = g_strdup ("Wavpack audio");
5325 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5326 audiocontext->wvpk_block_index = 0;
5327 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5328 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5329 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5330 gint raversion = -1;
5332 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5334 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5339 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5340 "raversion", G_TYPE_INT, raversion, NULL);
5341 /* Extract extra information from caps, mapping varies based on codec */
5342 if (data && (size >= 0x50)) {
5349 guint extra_data_size;
5351 GST_ERROR ("real audio raversion:%d", raversion);
5352 if (raversion == 8) {
5354 flavor = GST_READ_UINT16_BE (data + 22);
5355 packet_size = GST_READ_UINT32_BE (data + 24);
5356 height = GST_READ_UINT16_BE (data + 40);
5357 leaf_size = GST_READ_UINT16_BE (data + 44);
5358 sample_width = GST_READ_UINT16_BE (data + 58);
5359 extra_data_size = GST_READ_UINT32_BE (data + 74);
5362 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5363 flavor, packet_size, height, leaf_size, sample_width,
5365 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5366 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5367 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5369 if ((size - 78) >= extra_data_size) {
5370 priv = gst_buffer_new_and_alloc (extra_data_size);
5371 memcpy (GST_BUFFER_DATA (priv), data + 78, extra_data_size);
5372 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5373 gst_buffer_unref (priv);
5378 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5379 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5380 caps = gst_caps_new_simple ("audio/x-sipro", NULL);
5381 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5382 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5383 caps = gst_caps_new_simple ("audio/x-ralf-mpeg4-generic", NULL);
5384 *codec_name = g_strdup ("Real Audio Lossless");
5385 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5386 caps = gst_caps_new_simple ("audio/x-vnd.sony.atrac3", NULL);
5387 *codec_name = g_strdup ("Sony ATRAC3");
5389 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5394 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5397 for (i = 0; i < gst_caps_get_size (caps); i++) {
5398 gst_structure_set (gst_caps_get_structure (caps, i),
5399 "channels", G_TYPE_INT, audiocontext->channels,
5400 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5404 gst_caps_do_simplify (caps);
5411 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5412 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5414 GstCaps *caps = NULL;
5415 GstMatroskaTrackContext *context =
5416 (GstMatroskaTrackContext *) subtitlecontext;
5418 /* for backwards compatibility */
5419 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5420 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5421 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5422 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5423 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5424 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5425 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5426 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5428 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5429 * Check if we have to do something with codec_private */
5430 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5431 /* well, plain text simply does not have a lot of markup ... */
5432 caps = gst_caps_new_simple ("text/x-pango-markup", NULL);
5433 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5434 subtitlecontext->check_markup = TRUE;
5435 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5436 caps = gst_caps_new_simple ("application/x-ssa", NULL);
5437 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5438 subtitlecontext->check_markup = FALSE;
5439 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5440 caps = gst_caps_new_simple ("application/x-ass", NULL);
5441 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5442 subtitlecontext->check_markup = FALSE;
5443 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5444 caps = gst_caps_new_simple ("application/x-usf", NULL);
5445 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5446 subtitlecontext->check_markup = FALSE;
5447 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5448 caps = gst_caps_new_simple ("video/x-dvd-subpicture", NULL);
5449 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5450 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5451 caps = gst_caps_new_simple ("subpicture/x-pgs", NULL);
5452 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5453 caps = gst_caps_new_simple ("subtitle/x-kate", NULL);
5454 context->send_xiph_headers = TRUE;
5456 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5457 caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
5460 if (data != NULL && size > 0) {
5463 buf = gst_buffer_new_and_alloc (size);
5464 memcpy (GST_BUFFER_DATA (buf), data, size);
5465 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5466 gst_buffer_unref (buf);
5473 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5475 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5477 GST_OBJECT_LOCK (demux);
5478 if (demux->common.element_index)
5479 gst_object_unref (demux->common.element_index);
5480 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5481 GST_OBJECT_UNLOCK (demux);
5482 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5483 demux->common.element_index);
5487 gst_matroska_demux_get_index (GstElement * element)
5489 GstIndex *result = NULL;
5490 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5492 GST_OBJECT_LOCK (demux);
5493 if (demux->common.element_index)
5494 result = gst_object_ref (demux->common.element_index);
5495 GST_OBJECT_UNLOCK (demux);
5497 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5502 static GstStateChangeReturn
5503 gst_matroska_demux_change_state (GstElement * element,
5504 GstStateChange transition)
5506 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5507 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5509 /* handle upwards state changes here */
5510 switch (transition) {
5515 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5517 /* handle downwards state changes */
5518 switch (transition) {
5519 case GST_STATE_CHANGE_PAUSED_TO_READY:
5520 gst_matroska_demux_reset (GST_ELEMENT (demux));
5530 gst_matroska_demux_set_property (GObject * object,
5531 guint prop_id, const GValue * value, GParamSpec * pspec)
5533 GstMatroskaDemux *demux;
5535 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5536 demux = GST_MATROSKA_DEMUX (object);
5539 case ARG_MAX_GAP_TIME:
5540 GST_OBJECT_LOCK (demux);
5541 demux->max_gap_time = g_value_get_uint64 (value);
5542 GST_OBJECT_UNLOCK (demux);
5545 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5551 gst_matroska_demux_get_property (GObject * object,
5552 guint prop_id, GValue * value, GParamSpec * pspec)
5554 GstMatroskaDemux *demux;
5556 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5557 demux = GST_MATROSKA_DEMUX (object);
5560 case ARG_MAX_GAP_TIME:
5561 GST_OBJECT_LOCK (demux);
5562 g_value_set_uint64 (value, demux->max_gap_time);
5563 GST_OBJECT_UNLOCK (demux);
5566 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5572 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5576 /* parser helper separate debug */
5577 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5578 0, "EBML stream helper class");
5580 /* create an elementfactory for the matroska_demux element */
5581 if (!gst_element_register (plugin, "matroskademux",
5582 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))