1 /* GStreamer Matroska muxer/demuxer
2 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3 * (c) 2006 Tim-Philipp Müller <tim centricular net>
4 * (c) 2008 Sebastian Dröge <slomo@circular-chaos.org>
5 * (c) 2011 Debarshi Ray <rishi@gnu.org>
7 * matroska-demux.c: matroska file/stream demuxer
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
25 /* TODO: check CRC32 if present
26 * TODO: there can be a segment after the first segment. Handle like
27 * chained oggs. Fixes #334082
28 * TODO: Test samples: http://www.matroska.org/samples/matrix/index.html
29 * http://samples.mplayerhq.hu/Matroska/
30 * TODO: check if demuxing is done correct for all codecs according to spec
31 * TODO: seeking with incomplete or without CUE
35 * SECTION:element-matroskademux
37 * matroskademux demuxes a Matroska file into the different contained streams.
40 * <title>Example launch line</title>
42 * gst-launch -v filesrc location=/path/to/mkv ! matroskademux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
43 * ]| This pipeline demuxes a Matroska file and outputs the contained Vorbis audio.
54 #include <glib/gprintf.h>
56 /* For AVI compatibility mode
57 and for fourcc stuff */
58 #include <gst/riff/riff-read.h>
59 #include <gst/riff/riff-ids.h>
60 #include <gst/riff/riff-media.h>
62 #include <gst/audio/audio.h>
63 #include <gst/tag/tag.h>
64 #include <gst/pbutils/pbutils.h>
66 #include "matroska-demux.h"
67 #include "matroska-ids.h"
69 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
70 #define GST_CAT_DEFAULT matroskademux_debug
72 #define DEBUG_ELEMENT_START(demux, ebml, element) \
73 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
74 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
76 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
77 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
78 " finished with '%s'", gst_flow_get_name (ret))
88 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
90 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
93 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
94 "video/x-matroska-3d; audio/webm; video/webm")
97 /* TODO: fill in caps! */
99 static GstStaticPadTemplate audio_src_templ =
100 GST_STATIC_PAD_TEMPLATE ("audio_%u",
103 GST_STATIC_CAPS ("ANY")
106 static GstStaticPadTemplate video_src_templ =
107 GST_STATIC_PAD_TEMPLATE ("video_%u",
110 GST_STATIC_CAPS ("ANY")
113 static GstStaticPadTemplate subtitle_src_templ =
114 GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
117 GST_STATIC_CAPS ("text/x-pango-markup; application/x-ssa; "
118 "application/x-ass;application/x-usf; video/x-dvd-subpicture; "
119 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
122 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
123 guint32 id, guint64 length, guint needed);
125 /* element functions */
126 static void gst_matroska_demux_loop (GstPad * pad);
128 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
130 static gboolean gst_matroska_demux_element_query (GstElement * element,
134 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad,
136 static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
137 GstObject * parent, GstPadMode mode, gboolean active);
139 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
140 GstPad * pad, GstEvent * event);
141 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
142 GstObject * parent, GstEvent * event);
143 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
144 GstObject * parent, GstQuery * query);
146 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
147 GstObject * parent, GstEvent * event);
148 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
149 GstObject * object, GstBuffer * buffer);
151 static GstStateChangeReturn
152 gst_matroska_demux_change_state (GstElement * element,
153 GstStateChange transition);
156 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
157 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
161 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
162 * videocontext, const gchar * codec_id, guint8 * data, guint size,
163 gchar ** codec_name, guint32 * riff_fourcc);
164 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
165 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
166 gchar ** codec_name, guint16 * riff_audio_fmt);
168 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
169 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
172 static void gst_matroska_demux_reset (GstElement * element);
173 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
176 /* gobject functions */
177 static void gst_matroska_demux_set_property (GObject * object,
178 guint prop_id, const GValue * value, GParamSpec * pspec);
179 static void gst_matroska_demux_get_property (GObject * object,
180 guint prop_id, GValue * value, GParamSpec * pspec);
182 GType gst_matroska_demux_get_type (void);
183 #define parent_class gst_matroska_demux_parent_class
184 G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
187 gst_matroska_demux_finalize (GObject * object)
189 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
191 if (demux->common.src) {
192 g_ptr_array_free (demux->common.src, TRUE);
193 demux->common.src = NULL;
196 if (demux->common.global_tags) {
197 gst_tag_list_free (demux->common.global_tags);
198 demux->common.global_tags = NULL;
201 g_object_unref (demux->common.adapter);
203 G_OBJECT_CLASS (parent_class)->finalize (object);
207 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
209 GObjectClass *gobject_class = (GObjectClass *) klass;
210 GstElementClass *gstelement_class = (GstElementClass *) klass;
212 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
215 gobject_class->finalize = gst_matroska_demux_finalize;
217 gobject_class->get_property = gst_matroska_demux_get_property;
218 gobject_class->set_property = gst_matroska_demux_set_property;
220 g_object_class_install_property (gobject_class, ARG_MAX_GAP_TIME,
221 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
222 "The demuxer sends out segment events for skipping "
223 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
224 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
226 gstelement_class->change_state =
227 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
228 gstelement_class->send_event =
229 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
230 gstelement_class->query =
231 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
233 gstelement_class->set_index =
234 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
235 gstelement_class->get_index =
236 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
239 gst_element_class_add_pad_template (gstelement_class,
240 gst_static_pad_template_get (&video_src_templ));
241 gst_element_class_add_pad_template (gstelement_class,
242 gst_static_pad_template_get (&audio_src_templ));
243 gst_element_class_add_pad_template (gstelement_class,
244 gst_static_pad_template_get (&subtitle_src_templ));
245 gst_element_class_add_pad_template (gstelement_class,
246 gst_static_pad_template_get (&sink_templ));
248 gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
250 "Demuxes Matroska/WebM streams into video/audio/subtitles",
251 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
255 gst_matroska_demux_init (GstMatroskaDemux * demux)
257 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
259 gst_pad_set_activate_function (demux->common.sinkpad,
260 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
261 gst_pad_set_activatemode_function (demux->common.sinkpad,
262 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
263 gst_pad_set_chain_function (demux->common.sinkpad,
264 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
265 gst_pad_set_event_function (demux->common.sinkpad,
266 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
267 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
269 /* initial stream no. */
270 demux->common.src = NULL;
272 demux->common.writing_app = NULL;
273 demux->common.muxing_app = NULL;
274 demux->common.index = NULL;
275 demux->common.global_tags = NULL;
277 demux->common.adapter = gst_adapter_new ();
279 /* property defaults */
280 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
282 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
285 gst_matroska_demux_reset (GST_ELEMENT (demux));
289 gst_matroska_track_free (GstMatroskaTrackContext * track)
291 g_free (track->codec_id);
292 g_free (track->codec_name);
293 g_free (track->name);
294 g_free (track->language);
295 g_free (track->codec_priv);
296 g_free (track->codec_state);
298 if (track->encodings != NULL) {
301 for (i = 0; i < track->encodings->len; ++i) {
302 GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
303 GstMatroskaTrackEncoding,
306 g_free (enc->comp_settings);
308 g_array_free (track->encodings, TRUE);
311 if (track->pending_tags)
312 gst_tag_list_free (track->pending_tags);
314 if (track->index_table)
315 g_array_free (track->index_table, TRUE);
321 * Returns the aggregated GstFlowReturn.
324 gst_matroska_demux_combine_flows (GstMatroskaDemux * demux,
325 GstMatroskaTrackContext * track, GstFlowReturn ret)
329 /* store the value */
330 track->last_flow = ret;
332 /* any other error that is not-linked can be returned right away */
333 if (ret != GST_FLOW_NOT_LINKED)
336 /* only return NOT_LINKED if all other pads returned NOT_LINKED */
337 g_assert (demux->common.src->len == demux->common.num_streams);
338 for (i = 0; i < demux->common.src->len; i++) {
339 GstMatroskaTrackContext *ostream = g_ptr_array_index (demux->common.src,
345 ret = ostream->last_flow;
346 /* some other return value (must be SUCCESS but we can return
347 * other values as well) */
348 if (ret != GST_FLOW_NOT_LINKED)
351 /* if we get here, all other pads were unlinked and we return
354 GST_LOG_OBJECT (demux, "combined return %s", gst_flow_get_name (ret));
359 gst_matroska_demux_free_parsed_el (gpointer mem, gpointer user_data)
361 g_slice_free (guint64, mem);
365 gst_matroska_demux_reset (GstElement * element)
367 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
370 GST_DEBUG_OBJECT (demux, "Resetting state");
373 demux->common.state = GST_MATROSKA_READ_STATE_START;
375 /* clean up existing streams */
376 if (demux->common.src) {
377 g_assert (demux->common.src->len == demux->common.num_streams);
378 for (i = 0; i < demux->common.src->len; i++) {
379 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
382 if (context->pad != NULL)
383 gst_element_remove_pad (GST_ELEMENT (demux), context->pad);
385 gst_caps_replace (&context->caps, NULL);
386 gst_matroska_track_free (context);
388 g_ptr_array_free (demux->common.src, TRUE);
390 demux->common.src = g_ptr_array_new ();
392 demux->common.num_streams = 0;
393 demux->num_a_streams = 0;
394 demux->num_t_streams = 0;
395 demux->num_v_streams = 0;
397 /* reset media info */
398 g_free (demux->common.writing_app);
399 demux->common.writing_app = NULL;
400 g_free (demux->common.muxing_app);
401 demux->common.muxing_app = NULL;
404 if (demux->common.index) {
405 g_array_free (demux->common.index, TRUE);
406 demux->common.index = NULL;
409 if (demux->clusters) {
410 g_array_free (demux->clusters, TRUE);
411 demux->clusters = NULL;
416 demux->common.time_scale = 1000000;
417 demux->common.created = G_MININT64;
419 demux->common.index_parsed = FALSE;
420 demux->tracks_parsed = FALSE;
421 demux->common.segmentinfo_parsed = FALSE;
422 demux->common.attachments_parsed = FALSE;
423 demux->common.chapters_parsed = FALSE;
425 g_list_foreach (demux->common.tags_parsed,
426 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
427 g_list_free (demux->common.tags_parsed);
428 demux->common.tags_parsed = NULL;
430 g_list_foreach (demux->seek_parsed,
431 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
432 g_list_free (demux->seek_parsed);
433 demux->seek_parsed = NULL;
435 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
436 demux->last_stop_end = GST_CLOCK_TIME_NONE;
437 demux->seek_block = 0;
438 demux->stream_start_time = GST_CLOCK_TIME_NONE;
440 demux->common.offset = 0;
441 demux->cluster_time = GST_CLOCK_TIME_NONE;
442 demux->cluster_offset = 0;
443 demux->next_cluster_offset = 0;
444 demux->index_offset = 0;
445 demux->seekable = FALSE;
446 demux->need_segment = FALSE;
447 demux->building_index = FALSE;
448 if (demux->seek_event) {
449 gst_event_unref (demux->seek_event);
450 demux->seek_event = NULL;
453 demux->seek_index = NULL;
454 demux->seek_entry = 0;
456 if (demux->new_segment) {
457 gst_event_unref (demux->new_segment);
458 demux->new_segment = NULL;
461 if (demux->common.element_index) {
462 gst_object_unref (demux->common.element_index);
463 demux->common.element_index = NULL;
465 demux->common.element_index_writer_id = -1;
468 if (demux->common.global_tags) {
469 gst_tag_list_free (demux->common.global_tags);
471 demux->common.global_tags = gst_tag_list_new_empty ();
473 if (demux->common.cached_buffer) {
474 if (demux->common.cached_data) {
475 gst_buffer_unmap (demux->common.cached_buffer, &demux->common.cached_map);
476 demux->common.cached_data = NULL;
478 gst_buffer_unref (demux->common.cached_buffer);
479 demux->common.cached_buffer = NULL;
482 /* free chapters TOC if any */
483 if (demux->common.toc) {
484 gst_toc_free (demux->common.toc);
485 demux->common.toc = NULL;
488 demux->invalid_duration = FALSE;
492 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
498 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
500 GST_DEBUG ("decoding buffer %p", buf);
502 gst_buffer_map (buf, &map, GST_MAP_READ);
506 g_return_val_if_fail (size > 0, buf);
508 if (gst_matroska_decode_data (context->encodings, &data, &size,
509 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
510 gst_buffer_unmap (buf, &map);
511 gst_buffer_unref (buf);
512 return gst_buffer_new_wrapped (data, size);
514 GST_DEBUG ("decode data failed");
515 gst_buffer_unmap (buf, &map);
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_EOS)) {
1194 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
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_%u", demux->num_v_streams++);
1214 templ = gst_element_class_get_pad_template (klass, "video_%u");
1215 caps = gst_matroska_demux_video_caps (videocontext,
1216 context->codec_id, context->codec_priv,
1217 context->codec_priv_size, &codec, &riff_fourcc);
1220 list = gst_tag_list_new (GST_TAG_VIDEO_CODEC, codec, NULL);
1226 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1227 GstMatroskaTrackAudioContext *audiocontext =
1228 (GstMatroskaTrackAudioContext *) context;
1230 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1231 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1232 caps = gst_matroska_demux_audio_caps (audiocontext,
1233 context->codec_id, context->codec_priv, context->codec_priv_size,
1234 &codec, &riff_audio_fmt);
1237 list = gst_tag_list_new (GST_TAG_AUDIO_CODEC, codec, NULL);
1243 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1244 GstMatroskaTrackSubtitleContext *subtitlecontext =
1245 (GstMatroskaTrackSubtitleContext *) context;
1247 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1248 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1249 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1250 context->codec_id, context->codec_priv, context->codec_priv_size);
1254 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1255 case GST_MATROSKA_TRACK_TYPE_LOGO:
1256 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1257 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1259 /* we should already have quit by now */
1260 g_assert_not_reached ();
1263 if ((context->language == NULL || *context->language == '\0') &&
1264 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1265 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1266 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1267 context->language = g_strdup ("eng");
1270 if (context->language) {
1274 list = gst_tag_list_new_empty ();
1276 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1277 lang = gst_tag_get_language_code (context->language);
1278 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1279 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1283 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1284 "codec_id='%s'", context->codec_id);
1285 switch (context->type) {
1286 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1287 caps = gst_caps_new_empty_simple ("video/x-unknown");
1289 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1290 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1292 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1293 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1295 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1297 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1300 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1303 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1304 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1305 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1306 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1307 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1308 GST_FOURCC_ARGS (riff_fourcc));
1309 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, 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_function (context->pad,
1321 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1323 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1326 context->pending_tags = list;
1328 gst_pad_set_element_private (context->pad, context);
1330 gst_pad_use_fixed_caps (context->pad);
1331 gst_pad_set_active (context->pad, TRUE);
1332 gst_pad_set_caps (context->pad, context->caps);
1333 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1342 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1345 gboolean res = FALSE;
1346 GstMatroskaTrackContext *context = NULL;
1349 context = gst_pad_get_element_private (pad);
1352 switch (GST_QUERY_TYPE (query)) {
1353 case GST_QUERY_POSITION:
1357 gst_query_parse_position (query, &format, NULL);
1359 if (format == GST_FORMAT_TIME) {
1360 GST_OBJECT_LOCK (demux);
1362 gst_query_set_position (query, GST_FORMAT_TIME,
1363 MAX (context->pos, demux->stream_start_time) -
1364 demux->stream_start_time);
1366 gst_query_set_position (query, GST_FORMAT_TIME,
1367 MAX (demux->common.segment.position, demux->stream_start_time) -
1368 demux->stream_start_time);
1369 GST_OBJECT_UNLOCK (demux);
1370 } else if (format == GST_FORMAT_DEFAULT && context
1371 && context->default_duration) {
1372 GST_OBJECT_LOCK (demux);
1373 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1374 context->pos / context->default_duration);
1375 GST_OBJECT_UNLOCK (demux);
1377 GST_DEBUG_OBJECT (demux,
1378 "only position query in TIME and DEFAULT format is supported");
1384 case GST_QUERY_DURATION:
1388 gst_query_parse_duration (query, &format, NULL);
1390 if (format == GST_FORMAT_TIME) {
1391 GST_OBJECT_LOCK (demux);
1392 gst_query_set_duration (query, GST_FORMAT_TIME,
1393 demux->common.segment.duration);
1394 GST_OBJECT_UNLOCK (demux);
1395 } else if (format == GST_FORMAT_DEFAULT && context
1396 && context->default_duration) {
1397 GST_OBJECT_LOCK (demux);
1398 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1399 demux->common.segment.duration / context->default_duration);
1400 GST_OBJECT_UNLOCK (demux);
1402 GST_DEBUG_OBJECT (demux,
1403 "only duration query in TIME and DEFAULT format is supported");
1410 case GST_QUERY_SEEKING:
1414 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1415 GST_OBJECT_LOCK (demux);
1416 if (fmt == GST_FORMAT_TIME) {
1419 if (demux->streaming) {
1420 /* assuming we'll be able to get an index ... */
1421 seekable = demux->seekable;
1426 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1427 0, demux->common.segment.duration);
1430 GST_OBJECT_UNLOCK (demux);
1438 GST_OBJECT_LOCK (demux);
1439 if (demux->common.toc)
1440 toc = demux->common.toc;
1442 toc = gst_toc_new ();
1443 gst_query_set_toc (query, toc, 0);
1445 if (!demux->common.toc)
1447 GST_OBJECT_UNLOCK (demux);
1451 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1459 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1461 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1465 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1468 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1470 return gst_matroska_demux_query (demux, pad, query);
1473 /* returns FALSE if there are no pads to deliver event to,
1474 * otherwise TRUE (whatever the outcome of event sending),
1475 * takes ownership of the passed event! */
1477 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1479 gboolean is_segment;
1480 gboolean ret = FALSE;
1483 g_return_val_if_fail (event != NULL, FALSE);
1485 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1486 GST_EVENT_TYPE_NAME (event));
1488 is_segment = (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
1490 g_assert (demux->common.src->len == demux->common.num_streams);
1491 for (i = 0; i < demux->common.src->len; i++) {
1492 GstMatroskaTrackContext *stream;
1494 stream = g_ptr_array_index (demux->common.src, i);
1495 gst_event_ref (event);
1496 gst_pad_push_event (stream->pad, event);
1499 /* FIXME: send global tags before stream tags */
1500 if (G_UNLIKELY (is_segment && stream->pending_tags != NULL)) {
1501 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
1502 GST_PTR_FORMAT, stream->pending_tags,
1503 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
1504 gst_pad_push_event (stream->pad,
1505 gst_event_new_tag (stream->pending_tags));
1506 stream->pending_tags = NULL;
1510 if (G_UNLIKELY (is_segment && demux->common.global_tags != NULL)) {
1511 GstEvent *tag_event;
1512 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1513 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1514 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1515 demux->common.global_tags, demux->common.global_tags);
1517 tag_event = gst_event_new_tag (demux->common.global_tags);
1519 for (i = 0; i < demux->common.src->len; i++) {
1520 GstMatroskaTrackContext *stream;
1522 stream = g_ptr_array_index (demux->common.src, i);
1523 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1526 gst_event_unref (tag_event);
1527 demux->common.global_tags = NULL;
1530 gst_event_unref (event);
1535 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1537 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1540 g_return_val_if_fail (event != NULL, FALSE);
1542 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1543 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1545 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1546 GST_EVENT_TYPE_NAME (event));
1549 gst_event_unref (event);
1554 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1555 GstMatroskaIndex * entry, gboolean reset)
1559 GST_OBJECT_LOCK (demux);
1561 /* seek (relative to matroska segment) */
1562 /* position might be invalid; will error when streaming resumes ... */
1563 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1565 GST_DEBUG_OBJECT (demux, "Seeked to offset %" G_GUINT64_FORMAT ", block %d, "
1566 "time %" GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1567 entry->block, GST_TIME_ARGS (entry->time));
1569 /* update the time */
1570 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1571 demux->common.segment.position = entry->time;
1572 demux->seek_block = entry->block;
1573 demux->seek_first = TRUE;
1574 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1576 for (i = 0; i < demux->common.src->len; i++) {
1577 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1580 stream->to_offset = G_MAXINT64;
1582 if (stream->from_offset != -1)
1583 stream->to_offset = stream->from_offset;
1585 stream->from_offset = -1;
1588 GST_OBJECT_UNLOCK (demux);
1594 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1604 /* searches for a cluster start from @pos,
1605 * return GST_FLOW_OK and cluster position in @pos if found */
1606 static GstFlowReturn
1607 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1609 gint64 newpos = *pos;
1611 GstFlowReturn ret = GST_FLOW_OK;
1612 const guint chunk = 64 * 1024;
1613 GstBuffer *buf = NULL;
1615 gpointer data = NULL;
1621 orig_offset = demux->common.offset;
1623 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1626 if (demux->clusters) {
1629 cpos = gst_util_array_binary_search (demux->clusters->data,
1630 demux->clusters->len, sizeof (gint64),
1631 (GCompareDataFunc) gst_matroska_cluster_compare,
1632 GST_SEARCH_MODE_AFTER, pos, NULL);
1635 GST_DEBUG_OBJECT (demux,
1636 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1637 demux->common.offset = *cpos;
1638 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1639 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1640 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1647 /* read in at newpos and scan for ebml cluster id */
1649 GstByteReader reader;
1653 gst_buffer_unmap (buf, &map);
1654 gst_buffer_unref (buf);
1657 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1658 if (ret != GST_FLOW_OK)
1660 GST_DEBUG_OBJECT (demux,
1661 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1662 gst_buffer_get_size (buf), newpos);
1663 gst_buffer_map (buf, &map, GST_MAP_READ);
1666 gst_byte_reader_init (&reader, data, size);
1668 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1669 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1670 if (cluster_pos >= 0) {
1671 newpos += cluster_pos;
1672 /* prepare resuming at next byte */
1673 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1674 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1677 GST_DEBUG_OBJECT (demux,
1678 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1679 /* extra checks whether we really sync'ed to a cluster:
1680 * - either it is the first and only cluster
1681 * - either there is a cluster after this one
1682 * - either cluster length is undefined
1684 /* ok if first cluster (there may not a subsequent one) */
1685 if (newpos == demux->first_cluster_offset) {
1686 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1689 demux->common.offset = newpos;
1690 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1691 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1692 if (ret != GST_FLOW_OK) {
1693 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1696 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1697 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1699 /* ok if undefined length or first cluster */
1700 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1701 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1705 demux->common.offset += length + needed;
1706 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1707 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1708 if (ret != GST_FLOW_OK)
1710 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1711 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1712 if (id == GST_MATROSKA_ID_CLUSTER)
1714 /* not ok, resume */
1717 /* partial cluster id may have been in tail of buffer */
1718 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1723 gst_buffer_unmap (buf, &map);
1724 gst_buffer_unref (buf);
1729 demux->common.offset = orig_offset;
1734 /* bisect and scan through file for cluster starting before @time,
1735 * returns fake index entry with corresponding info on cluster */
1736 static GstMatroskaIndex *
1737 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1739 GstMatroskaIndex *entry = NULL;
1740 GstMatroskaReadState current_state;
1741 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1742 gint64 opos, newpos, startpos = 0, current_offset;
1743 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1744 const guint chunk = 64 * 1024;
1750 /* (under)estimate new position, resync using cluster ebml id,
1751 * and scan forward to appropriate cluster
1752 * (and re-estimate if need to go backward) */
1754 prev_cluster_time = GST_CLOCK_TIME_NONE;
1756 /* store some current state */
1757 current_state = demux->common.state;
1758 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1760 current_cluster_offset = demux->cluster_offset;
1761 current_cluster_time = demux->cluster_time;
1762 current_offset = demux->common.offset;
1764 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1766 /* estimate using start and current position */
1767 GST_OBJECT_LOCK (demux);
1768 opos = demux->common.offset - demux->common.ebml_segment_start;
1769 otime = demux->common.segment.position;
1770 GST_OBJECT_UNLOCK (demux);
1773 time = MAX (time, demux->stream_start_time);
1775 /* avoid division by zero in first estimation below */
1776 if (otime <= demux->stream_start_time)
1780 GST_LOG_OBJECT (demux,
1781 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1782 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1783 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1784 GST_TIME_ARGS (otime - demux->stream_start_time),
1785 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1787 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1788 time - demux->stream_start_time,
1789 otime - demux->stream_start_time) - chunk;
1792 /* favour undershoot */
1793 newpos = newpos * 90 / 100;
1794 newpos += demux->common.ebml_segment_start;
1796 GST_DEBUG_OBJECT (demux,
1797 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1798 GST_TIME_ARGS (time), newpos);
1800 /* and at least start scanning before previous scan start to avoid looping */
1801 startpos = startpos * 90 / 100;
1802 if (startpos && startpos < newpos)
1805 /* read in at newpos and scan for ebml cluster id */
1809 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1810 if (ret == GST_FLOW_EOS) {
1811 /* heuristic HACK */
1812 newpos = startpos * 80 / 100;
1813 GST_DEBUG_OBJECT (demux, "EOS; "
1814 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1815 GST_TIME_ARGS (time), newpos);
1818 } else if (ret != GST_FLOW_OK) {
1825 /* then start scanning and parsing for cluster time,
1826 * re-estimate if overshoot, otherwise next cluster and so on */
1827 demux->common.offset = newpos;
1828 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1830 guint64 cluster_size = 0;
1832 /* peek and parse some elements */
1833 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1834 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1835 if (ret != GST_FLOW_OK)
1837 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1838 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1840 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1841 if (ret != GST_FLOW_OK)
1844 if (id == GST_MATROSKA_ID_CLUSTER) {
1845 cluster_time = GST_CLOCK_TIME_NONE;
1846 if (length == G_MAXUINT64)
1849 cluster_size = length + needed;
1851 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1852 cluster_time == GST_CLOCK_TIME_NONE) {
1853 cluster_time = demux->cluster_time * demux->common.time_scale;
1854 cluster_offset = demux->cluster_offset;
1855 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1856 " with time %" GST_TIME_FORMAT, cluster_offset,
1857 GST_TIME_ARGS (cluster_time));
1858 if (cluster_time > time) {
1859 GST_DEBUG_OBJECT (demux, "overshot target");
1860 /* cluster overshoots */
1861 if (cluster_offset == demux->first_cluster_offset) {
1862 /* but no prev one */
1863 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1864 prev_cluster_time = cluster_time;
1865 prev_cluster_offset = cluster_offset;
1868 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1869 /* prev cluster did not overshoot, so prev cluster is target */
1872 /* re-estimate using this new position info */
1873 opos = cluster_offset;
1874 otime = cluster_time;
1878 /* cluster undershoots, goto next one */
1879 prev_cluster_time = cluster_time;
1880 prev_cluster_offset = cluster_offset;
1881 /* skip cluster if length is defined,
1882 * otherwise will be skippingly parsed into */
1884 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1885 demux->common.offset = cluster_offset + cluster_size;
1886 demux->cluster_time = GST_CLOCK_TIME_NONE;
1888 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1895 if (ret == GST_FLOW_EOS) {
1896 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1902 entry = g_new0 (GstMatroskaIndex, 1);
1903 entry->time = prev_cluster_time;
1904 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1905 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1906 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1910 /* restore some state */
1911 demux->cluster_offset = current_cluster_offset;
1912 demux->cluster_time = current_cluster_time;
1913 demux->common.offset = current_offset;
1914 demux->common.state = current_state;
1920 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1921 GstPad * pad, GstEvent * event)
1923 GstMatroskaIndex *entry = NULL;
1924 GstMatroskaIndex scan_entry;
1926 GstSeekType cur_type, stop_type;
1928 gboolean flush, keyunit;
1931 GstMatroskaTrackContext *track = NULL;
1932 GstSegment seeksegment = { 0, };
1933 gboolean update = TRUE;
1934 gboolean pad_locked = FALSE;
1937 track = gst_pad_get_element_private (pad);
1939 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1942 /* we can only seek on time */
1943 if (format != GST_FORMAT_TIME) {
1944 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1948 /* copy segment, we need this because we still need the old
1949 * segment when we close the current segment. */
1950 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1952 /* pull mode without index means that the actual duration is not known,
1953 * we might be playing a file that's still being recorded
1954 * so, invalidate our current duration, which is only a moving target,
1955 * and should not be used to clamp anything */
1956 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
1957 seeksegment.duration = GST_CLOCK_TIME_NONE;
1961 GST_DEBUG_OBJECT (demux, "configuring seek");
1962 gst_segment_do_seek (&seeksegment, rate, format, flags,
1963 cur_type, cur, stop_type, stop, &update);
1964 /* compensate for clip start time */
1965 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1966 seeksegment.position += demux->stream_start_time;
1967 seeksegment.start += demux->stream_start_time;
1968 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1969 seeksegment.stop += demux->stream_start_time;
1970 /* note that time should stay at indicated position */
1974 /* restore segment duration (if any effect),
1975 * would be determined again when parsing, but anyway ... */
1976 seeksegment.duration = demux->common.segment.duration;
1978 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
1979 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
1981 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1984 /* only have to update some segment,
1985 * but also still have to honour flush and so on */
1986 GST_DEBUG_OBJECT (demux, "... no update");
1987 /* bad goto, bad ... */
1991 /* check sanity before we start flushing and all that */
1992 GST_OBJECT_LOCK (demux);
1993 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
1994 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
1995 seeksegment.position, &demux->seek_index, &demux->seek_entry)) ==
1997 /* pull mode without index can scan later on */
1998 if (demux->streaming) {
1999 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2000 GST_OBJECT_UNLOCK (demux);
2004 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2005 GST_OBJECT_UNLOCK (demux);
2007 if (demux->streaming) {
2008 /* need to seek to cluster start to pick up cluster time */
2009 /* upstream takes care of flushing and all that
2010 * ... and segment event handling takes care of the rest */
2011 return perform_seek_to_offset (demux,
2012 entry->pos + demux->common.ebml_segment_start);
2017 GST_DEBUG_OBJECT (demux, "Starting flush");
2018 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_start ());
2019 gst_matroska_demux_send_event (demux, gst_event_new_flush_start ());
2021 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2022 gst_pad_pause_task (demux->common.sinkpad);
2028 /* now grab the stream lock so that streaming cannot continue, for
2029 * non flushing seeks when the element is in PAUSED this could block
2031 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2032 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2035 /* pull mode without index can do some scanning */
2036 if (!demux->streaming && !entry) {
2037 /* need to stop flushing upstream as we need it next */
2039 gst_pad_push_event (demux->common.sinkpad,
2040 gst_event_new_flush_stop (TRUE));
2041 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2042 /* keep local copy */
2044 scan_entry = *entry;
2046 entry = &scan_entry;
2048 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2050 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop (TRUE));
2056 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start to %"
2057 GST_TIME_FORMAT, GST_TIME_ARGS (entry->time));
2058 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2059 seeksegment.position = seeksegment.start;
2060 seeksegment.time = seeksegment.start - demux->stream_start_time;
2065 GST_DEBUG_OBJECT (demux, "Stopping flush");
2066 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_stop (TRUE));
2067 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop (TRUE));
2070 GST_OBJECT_LOCK (demux);
2071 /* now update the real segment info */
2072 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2073 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2074 GST_OBJECT_UNLOCK (demux);
2076 /* update some (segment) state */
2077 if (update && !gst_matroska_demux_move_to_entry (demux, entry, TRUE))
2080 /* notify start of new segment */
2081 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2084 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2085 GST_FORMAT_TIME, demux->common.segment.start);
2086 gst_element_post_message (GST_ELEMENT (demux), msg);
2089 GST_OBJECT_LOCK (demux);
2090 if (demux->new_segment)
2091 gst_event_unref (demux->new_segment);
2092 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2093 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2094 GST_OBJECT_UNLOCK (demux);
2096 /* restart our task since it might have been stopped when we did the
2098 gst_pad_start_task (demux->common.sinkpad,
2099 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad);
2101 /* streaming can continue now */
2103 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2111 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2113 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2119 * Handle whether we can perform the seek event or if we have to let the chain
2120 * function handle seeks to build the seek indexes first.
2123 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2127 GstSeekType cur_type, stop_type;
2132 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2137 /* we can only seek on time */
2138 if (format != GST_FORMAT_TIME) {
2139 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2143 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2144 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2148 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2149 GST_DEBUG_OBJECT (demux,
2150 "Non-flushing seek not supported in streaming mode");
2154 if (flags & GST_SEEK_FLAG_SEGMENT) {
2155 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2159 /* check for having parsed index already */
2160 if (!demux->common.index_parsed) {
2161 gboolean building_index;
2164 if (!demux->index_offset) {
2165 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2169 GST_OBJECT_LOCK (demux);
2170 /* handle the seek event in the chain function */
2171 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2172 /* no more seek can be issued until state reset to _DATA */
2174 /* copy the event */
2175 if (demux->seek_event)
2176 gst_event_unref (demux->seek_event);
2177 demux->seek_event = gst_event_ref (event);
2179 /* set the building_index flag so that only one thread can setup the
2180 * structures for index seeking. */
2181 building_index = demux->building_index;
2182 if (!building_index) {
2183 demux->building_index = TRUE;
2184 offset = demux->index_offset;
2186 GST_OBJECT_UNLOCK (demux);
2188 if (!building_index) {
2189 /* seek to the first subindex or legacy index */
2190 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2191 return perform_seek_to_offset (demux, offset);
2194 /* well, we are handling it already */
2198 /* delegate to tweaked regular seek */
2199 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2203 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2206 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2207 gboolean res = TRUE;
2209 switch (GST_EVENT_TYPE (event)) {
2210 case GST_EVENT_SEEK:
2211 /* no seeking until we are (safely) ready */
2212 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2213 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2216 if (!demux->streaming)
2217 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2219 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2220 gst_event_unref (event);
2225 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2226 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2227 GstMatroskaTrackVideoContext *videocontext =
2228 (GstMatroskaTrackVideoContext *) context;
2230 GstClockTimeDiff diff;
2231 GstClockTime timestamp;
2233 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2235 GST_OBJECT_LOCK (demux);
2236 videocontext->earliest_time = timestamp + diff;
2237 GST_OBJECT_UNLOCK (demux);
2240 gst_event_unref (event);
2244 case GST_EVENT_TOC_SELECT:
2247 GstTocEntry *entry = NULL;
2248 GstEvent *seek_event;
2251 if (!demux->common.toc) {
2252 GST_DEBUG_OBJECT (demux, "no TOC to select");
2255 gst_event_parse_toc_select (event, &uid);
2257 GST_OBJECT_LOCK (demux);
2258 entry = gst_toc_find_entry (demux->common.toc, uid);
2259 if (entry == NULL) {
2260 GST_OBJECT_UNLOCK (demux);
2261 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2264 gst_toc_entry_get_start_stop (entry, &start_pos, NULL);
2265 GST_OBJECT_UNLOCK (demux);
2266 seek_event = gst_event_new_seek (1.0,
2268 GST_SEEK_FLAG_FLUSH,
2269 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2270 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2271 gst_event_unref (seek_event);
2275 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2279 gst_event_unref (event);
2283 /* events we don't need to handle */
2284 case GST_EVENT_NAVIGATION:
2285 gst_event_unref (event);
2289 case GST_EVENT_LATENCY:
2291 res = gst_pad_push_event (demux->common.sinkpad, event);
2298 static GstFlowReturn
2299 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2301 GstFlowReturn ret = GST_FLOW_EOS;
2302 gboolean done = TRUE;
2305 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2306 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2309 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2311 if (!demux->seek_entry) {
2312 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2316 for (i = 0; i < demux->common.src->len; i++) {
2317 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2319 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2320 ", stream %d at %" GST_TIME_FORMAT,
2321 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2322 GST_TIME_ARGS (stream->from_time));
2323 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2324 if (stream->from_time > demux->common.segment.start) {
2325 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2329 /* nothing pushed for this stream;
2330 * likely seek entry did not start at keyframe, so all was skipped.
2331 * So we need an earlier entry */
2337 GstMatroskaIndex *entry;
2339 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2340 --demux->seek_entry);
2341 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE))
2351 static GstFlowReturn
2352 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2354 GstFlowReturn ret = GST_FLOW_OK;
2357 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2359 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2360 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2364 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2365 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2369 /* one track within the "all-tracks" header */
2370 case GST_MATROSKA_ID_TRACKENTRY:
2371 ret = gst_matroska_demux_add_stream (demux, ebml);
2375 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2380 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2382 demux->tracks_parsed = TRUE;
2388 * Read signed/unsigned "EBML" numbers.
2389 * Return: number of bytes processed.
2393 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2395 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2403 while (read <= 8 && !(total & len_mask)) {
2410 if ((total &= (len_mask - 1)) == len_mask - 1)
2415 if (data[n] == 0xff)
2417 total = (total << 8) | data[n];
2421 if (read == num_ffs && total != 0)
2430 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2435 /* read as unsigned number first */
2436 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2440 if (unum == G_MAXUINT64)
2443 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2449 * Mostly used for subtitles. We add void filler data for each
2450 * lagging stream to make sure we don't deadlock.
2454 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2458 GST_OBJECT_LOCK (demux);
2460 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2461 GST_TIME_ARGS (demux->common.segment.position));
2463 g_assert (demux->common.num_streams == demux->common.src->len);
2464 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2465 GstMatroskaTrackContext *context;
2467 context = g_ptr_array_index (demux->common.src, stream_nr);
2469 GST_LOG_OBJECT (demux,
2470 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2471 GST_TIME_ARGS (context->pos));
2473 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2474 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2478 /* does it lag? 0.5 seconds is a random threshold...
2479 * lag need only be considered if we have advanced into requested segment */
2480 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2481 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2482 demux->common.segment.position > demux->common.segment.start &&
2483 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2488 new_start = demux->common.segment.position - (GST_SECOND / 2);
2489 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop))
2490 new_start = MIN (new_start, demux->common.segment.stop);
2491 GST_DEBUG_OBJECT (demux,
2492 "Synchronizing stream %d with others by advancing time " "from %"
2493 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2494 GST_TIME_ARGS (context->pos), GST_TIME_ARGS (new_start));
2496 context->pos = new_start;
2498 /* advance stream time */
2499 segment = demux->common.segment;
2500 segment.position = new_start;
2501 event = gst_event_new_segment (&segment);
2502 GST_OBJECT_UNLOCK (demux);
2503 gst_pad_push_event (context->pad, event);
2504 GST_OBJECT_LOCK (demux);
2508 GST_OBJECT_UNLOCK (demux);
2511 static GstFlowReturn
2512 gst_matroska_demux_push_hdr_buf (GstMatroskaDemux * demux,
2513 GstMatroskaTrackContext * stream, guint8 * data, guint len)
2515 GstFlowReturn ret, cret;
2516 GstBuffer *header_buf;
2518 header_buf = gst_buffer_new_wrapped (g_memdup (data, len), len);
2520 if (stream->set_discont) {
2521 GST_BUFFER_FLAG_SET (header_buf, GST_BUFFER_FLAG_DISCONT);
2522 stream->set_discont = FALSE;
2525 ret = gst_pad_push (stream->pad, header_buf);
2528 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
2533 static GstFlowReturn
2534 gst_matroska_demux_push_flac_codec_priv_data (GstMatroskaDemux * demux,
2535 GstMatroskaTrackContext * stream)
2541 GST_LOG_OBJECT (demux, "priv data size = %" G_GSIZE_FORMAT,
2542 stream->codec_priv_size);
2544 pdata = (guint8 *) stream->codec_priv;
2546 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2547 if (stream->codec_priv_size < ((4) + (4 + 34))) {
2548 GST_WARNING_OBJECT (demux, "not enough codec priv data for flac headers");
2549 return GST_FLOW_ERROR;
2552 if (memcmp (pdata, "fLaC", 4) != 0) {
2553 GST_WARNING_OBJECT (demux, "no flac marker at start of stream headers");
2554 return GST_FLOW_ERROR;
2557 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 4);
2558 if (ret != GST_FLOW_OK)
2561 off = 4; /* skip fLaC marker */
2562 while (off < stream->codec_priv_size) {
2563 len = GST_READ_UINT8 (pdata + off + 1) << 16;
2564 len |= GST_READ_UINT8 (pdata + off + 2) << 8;
2565 len |= GST_READ_UINT8 (pdata + off + 3);
2567 GST_DEBUG_OBJECT (demux, "header packet: len=%u bytes, flags=0x%02x",
2568 len, (guint) pdata[off]);
2570 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata + off, len + 4);
2571 if (ret != GST_FLOW_OK)
2579 static GstFlowReturn
2580 gst_matroska_demux_push_speex_codec_priv_data (GstMatroskaDemux * demux,
2581 GstMatroskaTrackContext * stream)
2584 guint8 *pdata = stream->codec_priv;
2586 GST_LOG_OBJECT (demux, "priv data size = %" G_GSIZE_FORMAT,
2587 stream->codec_priv_size);
2589 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2590 if (stream->codec_priv_size < 80) {
2591 GST_WARNING_OBJECT (demux, "not enough codec priv data for speex headers");
2592 return GST_FLOW_ERROR;
2595 if (memcmp (pdata, "Speex ", 8) != 0) {
2596 GST_WARNING_OBJECT (demux, "no Speex marker at start of stream headers");
2597 return GST_FLOW_ERROR;
2600 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 80);
2601 if (ret != GST_FLOW_OK)
2604 if (stream->codec_priv_size == 80)
2607 return gst_matroska_demux_push_hdr_buf (demux, stream, pdata + 80,
2608 stream->codec_priv_size - 80);
2611 static GstFlowReturn
2612 gst_matroska_demux_push_xiph_codec_priv_data (GstMatroskaDemux * demux,
2613 GstMatroskaTrackContext * stream)
2616 guint8 *p = stream->codec_priv;
2617 gint i, offset, num_packets;
2618 guint *length, last;
2620 if (stream->codec_priv == NULL || stream->codec_priv_size == 0) {
2621 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
2622 ("Missing codec private data for xiph headers, broken file"));
2623 return GST_FLOW_ERROR;
2626 /* start of the stream and vorbis audio or theora video, need to
2627 * send the codec_priv data as first three packets */
2628 num_packets = p[0] + 1;
2629 GST_DEBUG_OBJECT (demux,
2630 "%u stream headers, total length=%" G_GSIZE_FORMAT " bytes",
2631 (guint) num_packets, stream->codec_priv_size);
2633 length = g_alloca (num_packets * sizeof (guint));
2637 /* first packets, read length values */
2638 for (i = 0; i < num_packets - 1; i++) {
2640 while (offset < stream->codec_priv_size) {
2641 length[i] += p[offset];
2642 if (p[offset++] != 0xff)
2647 if (offset + last > stream->codec_priv_size)
2648 return GST_FLOW_ERROR;
2650 /* last packet is the remaining size */
2651 length[i] = stream->codec_priv_size - offset - last;
2653 for (i = 0; i < num_packets; i++) {
2654 GST_DEBUG_OBJECT (demux, "buffer %d: length=%u bytes", i,
2656 if (offset + length[i] > stream->codec_priv_size)
2657 return GST_FLOW_ERROR;
2660 gst_matroska_demux_push_hdr_buf (demux, stream, p + offset, length[i]);
2661 if (ret != GST_FLOW_OK)
2664 offset += length[i];
2670 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2671 GstMatroskaTrackContext * stream)
2675 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2677 if (!stream->codec_priv)
2680 /* ideally, VobSub private data should be parsed and stored more convenient
2681 * elsewhere, but for now, only interested in a small part */
2683 /* make sure we have terminating 0 */
2684 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2686 /* just locate and parse palette part */
2687 start = strstr (buf, "palette:");
2692 guint8 r, g, b, y, u, v;
2695 while (g_ascii_isspace (*start))
2697 for (i = 0; i < 16; i++) {
2698 if (sscanf (start, "%06x", &col) != 1)
2701 while ((*start == ',') || g_ascii_isspace (*start))
2703 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2704 r = (col >> 16) & 0xff;
2705 g = (col >> 8) & 0xff;
2707 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2709 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2710 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2711 clut[i] = (y << 16) | (u << 8) | v;
2714 /* got them all without problems; build and send event */
2718 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2719 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2720 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2721 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2722 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2723 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2724 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2725 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2726 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2727 G_TYPE_INT, clut[15], NULL);
2729 gst_pad_push_event (stream->pad,
2730 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
2736 static GstFlowReturn
2737 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2738 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2741 guint seq_header_len;
2742 guint32 header, tmp;
2744 if (stream->codec_state) {
2745 seq_header = stream->codec_state;
2746 seq_header_len = stream->codec_state_size;
2747 } else if (stream->codec_priv) {
2748 seq_header = stream->codec_priv;
2749 seq_header_len = stream->codec_priv_size;
2754 /* Sequence header only needed for keyframes */
2755 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2758 if (gst_buffer_get_size (*buf) < 4)
2761 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2762 header = GUINT32_FROM_BE (tmp);
2764 /* Sequence start code, if not found prepend */
2765 if (header != 0x000001b3) {
2768 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2770 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2773 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2774 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2775 gst_buffer_get_size (*buf));
2777 gst_buffer_unref (*buf);
2784 static GstFlowReturn
2785 gst_matroska_demux_add_wvpk_header (GstElement * element,
2786 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2788 GstMatroskaTrackAudioContext *audiocontext =
2789 (GstMatroskaTrackAudioContext *) stream;
2790 GstBuffer *newbuf = NULL;
2791 GstMapInfo map, outmap;
2792 guint8 *buf_data, *data;
2800 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2803 wvh.total_samples = -1;
2804 wvh.block_index = audiocontext->wvpk_block_index;
2806 if (audiocontext->channels <= 2) {
2807 guint32 block_samples, tmp;
2808 gsize size = gst_buffer_get_size (*buf);
2810 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2811 block_samples = GUINT32_FROM_LE (tmp);
2812 /* we need to reconstruct the header of the wavpack block */
2814 /* -20 because ck_size is the size of the wavpack block -8
2815 * and lace_size is the size of the wavpack block + 12
2816 * (the three guint32 of the header that already are in the buffer) */
2817 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2819 /* block_samples, flags and crc are already in the buffer */
2820 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2822 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2828 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2829 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2830 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2831 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2832 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2833 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2835 /* Append data from buf: */
2836 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2837 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2839 gst_buffer_unref (*buf);
2841 audiocontext->wvpk_block_index += block_samples;
2843 guint8 *outdata = NULL;
2845 gsize buf_size, size, out_size = 0;
2846 guint32 block_samples, flags, crc, blocksize;
2848 gst_buffer_map (*buf, &map, GST_MAP_READ);
2849 buf_data = map.data;
2850 buf_size = map.size;
2853 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2854 gst_buffer_unmap (*buf, &map);
2855 return GST_FLOW_ERROR;
2861 block_samples = GST_READ_UINT32_LE (data);
2866 flags = GST_READ_UINT32_LE (data);
2869 crc = GST_READ_UINT32_LE (data);
2872 blocksize = GST_READ_UINT32_LE (data);
2876 if (blocksize == 0 || size < blocksize)
2879 g_assert ((newbuf == NULL) == (outdata == NULL));
2881 if (newbuf == NULL) {
2882 out_size = sizeof (Wavpack4Header) + blocksize;
2883 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2885 gst_buffer_copy_into (newbuf, *buf,
2886 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2889 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2890 outdata = outmap.data;
2892 gst_buffer_unmap (newbuf, &outmap);
2893 out_size += sizeof (Wavpack4Header) + blocksize;
2894 gst_buffer_set_size (newbuf, out_size);
2895 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2896 outdata = outmap.data;
2899 outdata[outpos] = 'w';
2900 outdata[outpos + 1] = 'v';
2901 outdata[outpos + 2] = 'p';
2902 outdata[outpos + 3] = 'k';
2905 GST_WRITE_UINT32_LE (outdata + outpos,
2906 blocksize + sizeof (Wavpack4Header) - 8);
2907 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2908 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2909 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2910 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2911 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2912 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2913 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2914 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2917 g_memmove (outdata + outpos, data, blocksize);
2918 outpos += blocksize;
2922 gst_buffer_unmap (*buf, &map);
2923 gst_buffer_unref (*buf);
2926 gst_buffer_unmap (newbuf, &outmap);
2929 audiocontext->wvpk_block_index += block_samples;
2935 /* @text must be null-terminated */
2937 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2942 /* yes, this might all lead to false positives ... */
2943 tag = (gchar *) text;
2944 while ((tag = strchr (tag, '<'))) {
2946 if (*tag != '\0' && *(tag + 1) == '>') {
2947 /* some common convenience ones */
2948 /* maybe any character will do here ? */
2961 if (strstr (text, "<span"))
2967 static GstFlowReturn
2968 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2969 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2971 GstMatroskaTrackSubtitleContext *sub_stream;
2972 const gchar *encoding;
2978 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
2980 if (!gst_buffer_map (*buf, &map, GST_MAP_READ))
2983 if (!sub_stream->invalid_utf8) {
2984 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
2987 GST_WARNING_OBJECT (element, "subtitle stream %d is not valid UTF-8, this "
2988 "is broken according to the matroska specification", stream->num);
2989 sub_stream->invalid_utf8 = TRUE;
2992 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
2993 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
2994 if (encoding == NULL || *encoding == '\0') {
2995 /* if local encoding is UTF-8 and no encoding specified
2996 * via the environment variable, assume ISO-8859-15 */
2997 if (g_get_charset (&encoding)) {
2998 encoding = "ISO-8859-15";
3003 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3004 (char *) "*", NULL, NULL, &err);
3007 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3008 encoding, err->message);
3012 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3013 encoding = "ISO-8859-15";
3015 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3016 encoding, (char *) "*", NULL, NULL, NULL);
3019 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3020 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3023 utf8 = g_strdup ("invalid subtitle");
3025 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3026 gst_buffer_copy_into (newbuf, *buf,
3027 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3029 gst_buffer_unmap (*buf, &map);
3030 gst_buffer_unref (*buf);
3033 gst_buffer_map (*buf, &map, GST_MAP_READ);
3036 if (sub_stream->check_markup) {
3037 /* caps claim markup text, so we need to escape text,
3038 * except if text is already markup and then needs no further escaping */
3039 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3040 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3042 if (!sub_stream->seen_markup_tag) {
3043 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3045 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3046 gst_buffer_copy_into (newbuf, *buf,
3047 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3048 GST_BUFFER_COPY_META, 0, -1);
3049 gst_buffer_unmap (*buf, &map);
3050 gst_buffer_unref (*buf);
3059 static GstFlowReturn
3060 gst_matroska_demux_check_aac (GstElement * element,
3061 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3066 gst_buffer_extract (*buf, 0, data, 2);
3067 size = gst_buffer_get_size (*buf);
3069 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3072 /* tss, ADTS data, remove codec_data
3073 * still assume it is at least parsed */
3074 stream->caps = gst_caps_make_writable (stream->caps);
3075 s = gst_caps_get_structure (stream->caps, 0);
3077 gst_structure_remove_field (s, "codec_data");
3078 gst_pad_set_caps (stream->pad, stream->caps);
3079 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3080 "new caps: %" GST_PTR_FORMAT, stream->caps);
3083 /* disable subsequent checking */
3084 stream->postprocess_frame = NULL;
3090 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3091 GstBuffer * buffer, gsize alignment)
3095 gst_buffer_map (buffer, &map, GST_MAP_READ);
3097 if (map.size < sizeof (guintptr)) {
3098 gst_buffer_unmap (buffer, &map);
3102 if (((guintptr) map.data) & (alignment - 1)) {
3103 GstBuffer *new_buffer;
3104 GstAllocationParams params = { 0, 0, 0, alignment - 1, };
3106 new_buffer = gst_buffer_new_allocate (NULL,
3107 gst_buffer_get_size (buffer), ¶ms);
3109 /* Copy data "by hand", so ensure alignment is kept: */
3110 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3112 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3113 GST_DEBUG_OBJECT (demux,
3114 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3117 gst_buffer_unmap (buffer, &map);
3118 gst_buffer_unref (buffer);
3123 gst_buffer_unmap (buffer, &map);
3127 static GstFlowReturn
3128 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3129 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3130 gboolean is_simpleblock)
3132 GstMatroskaTrackContext *stream = NULL;
3133 GstFlowReturn ret = GST_FLOW_OK;
3134 gboolean readblock = FALSE;
3136 guint64 block_duration = -1;
3137 GstBuffer *buf = NULL;
3139 gint stream_num = -1, n, laces = 0;
3141 gint *lace_size = NULL;
3144 gint64 referenceblock = 0;
3147 offset = gst_ebml_read_get_offset (ebml);
3149 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3150 if (!is_simpleblock) {
3151 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3155 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3159 /* one block inside the group. Note, block parsing is one
3160 * of the harder things, so this code is a bit complicated.
3161 * See http://www.matroska.org/ for documentation. */
3162 case GST_MATROSKA_ID_SIMPLEBLOCK:
3163 case GST_MATROSKA_ID_BLOCK:
3169 gst_buffer_unmap (buf, &map);
3170 gst_buffer_unref (buf);
3173 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3176 gst_buffer_map (buf, &map, GST_MAP_READ);
3180 /* first byte(s): blocknum */
3181 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3186 /* fetch stream from num */
3187 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3189 if (G_UNLIKELY (size < 3)) {
3190 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3191 /* non-fatal, try next block(group) */
3194 } else if (G_UNLIKELY (stream_num < 0 ||
3195 stream_num >= demux->common.num_streams)) {
3196 /* let's not give up on a stray invalid track number */
3197 GST_WARNING_OBJECT (demux,
3198 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3199 "; ignoring block", stream_num, num);
3203 stream = g_ptr_array_index (demux->common.src, stream_num);
3205 /* time (relative to cluster time) */
3206 time = ((gint16) GST_READ_UINT16_BE (data));
3209 flags = GST_READ_UINT8 (data);
3213 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3216 switch ((flags & 0x06) >> 1) {
3217 case 0x0: /* no lacing */
3219 lace_size = g_new (gint, 1);
3220 lace_size[0] = size;
3223 case 0x1: /* xiph lacing */
3224 case 0x2: /* fixed-size lacing */
3225 case 0x3: /* EBML lacing */
3227 goto invalid_lacing;
3228 laces = GST_READ_UINT8 (data) + 1;
3231 lace_size = g_new0 (gint, laces);
3233 switch ((flags & 0x06) >> 1) {
3234 case 0x1: /* xiph lacing */ {
3235 guint temp, total = 0;
3237 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3240 goto invalid_lacing;
3241 temp = GST_READ_UINT8 (data);
3242 lace_size[n] += temp;
3248 total += lace_size[n];
3250 lace_size[n] = size - total;
3254 case 0x2: /* fixed-size lacing */
3255 for (n = 0; n < laces; n++)
3256 lace_size[n] = size / laces;
3259 case 0x3: /* EBML lacing */ {
3262 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3266 total = lace_size[0] = num;
3267 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3271 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3275 lace_size[n] = lace_size[n - 1] + snum;
3276 total += lace_size[n];
3279 lace_size[n] = size - total;
3286 if (stream->send_xiph_headers) {
3287 ret = gst_matroska_demux_push_xiph_codec_priv_data (demux, stream);
3288 stream->send_xiph_headers = FALSE;
3291 if (stream->send_flac_headers) {
3292 ret = gst_matroska_demux_push_flac_codec_priv_data (demux, stream);
3293 stream->send_flac_headers = FALSE;
3296 if (stream->send_speex_headers) {
3297 ret = gst_matroska_demux_push_speex_codec_priv_data (demux, stream);
3298 stream->send_speex_headers = FALSE;
3301 if (stream->send_dvd_event) {
3302 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
3303 /* FIXME: should we send this event again after (flushing) seek ? */
3304 stream->send_dvd_event = FALSE;
3307 if (ret != GST_FLOW_OK)
3314 case GST_MATROSKA_ID_BLOCKDURATION:{
3315 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3316 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3321 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3322 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3323 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3328 case GST_MATROSKA_ID_CODECSTATE:{
3330 guint64 data_len = 0;
3333 gst_ebml_read_binary (ebml, &id, &data,
3334 &data_len)) != GST_FLOW_OK)
3337 if (G_UNLIKELY (stream == NULL)) {
3338 GST_WARNING_OBJECT (demux,
3339 "Unexpected CodecState subelement - ignoring");
3343 g_free (stream->codec_state);
3344 stream->codec_state = data;
3345 stream->codec_state_size = data_len;
3347 /* Decode if necessary */
3348 if (stream->encodings && stream->encodings->len > 0
3349 && stream->codec_state && stream->codec_state_size > 0) {
3350 if (!gst_matroska_decode_data (stream->encodings,
3351 &stream->codec_state, &stream->codec_state_size,
3352 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3353 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3357 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3358 stream->codec_state_size);
3363 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3367 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3368 case GST_MATROSKA_ID_BLOCKADDITIONS:
3369 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3370 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3371 case GST_MATROSKA_ID_SLICES:
3372 GST_DEBUG_OBJECT (demux,
3373 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3374 ret = gst_ebml_read_skip (ebml);
3382 /* reading a number or so could have failed */
3383 if (ret != GST_FLOW_OK)
3386 if (ret == GST_FLOW_OK && readblock) {
3387 guint64 duration = 0;
3388 gint64 lace_time = 0;
3389 gboolean delta_unit;
3391 stream = g_ptr_array_index (demux->common.src, stream_num);
3393 if (cluster_time != GST_CLOCK_TIME_NONE) {
3394 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3395 * Drop unless the lace contains timestamp 0? */
3396 if (time < 0 && (-time) > cluster_time) {
3399 if (stream->timecodescale == 1.0)
3400 lace_time = (cluster_time + time) * demux->common.time_scale;
3403 gst_util_guint64_to_gdouble ((cluster_time + time) *
3404 demux->common.time_scale) * stream->timecodescale;
3407 lace_time = GST_CLOCK_TIME_NONE;
3410 /* need to refresh segment info ASAP */
3411 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3412 GstSegment *segment = &demux->common.segment;
3413 guint64 segment_duration = 0;
3415 GST_DEBUG_OBJECT (demux,
3416 "generating segment starting at %" GST_TIME_FORMAT,
3417 GST_TIME_ARGS (lace_time));
3418 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3419 demux->stream_start_time = lace_time;
3420 GST_DEBUG_OBJECT (demux,
3421 "Setting stream start time to %" GST_TIME_FORMAT,
3422 GST_TIME_ARGS (lace_time));
3424 if (GST_CLOCK_TIME_IS_VALID (segment->stop))
3425 segment_duration = segment->stop - segment->start;
3426 else if (GST_CLOCK_TIME_IS_VALID (segment->position))
3427 segment_duration = segment->position - segment->start;
3428 segment->base += segment_duration / fabs (segment->rate);
3429 segment->start = MAX (lace_time, demux->stream_start_time);
3430 segment->stop = GST_CLOCK_TIME_NONE;
3431 segment->position = segment->start - demux->stream_start_time;
3432 /* now convey our segment notion downstream */
3433 gst_matroska_demux_send_event (demux, gst_event_new_segment (segment));
3434 demux->need_segment = FALSE;
3437 if (block_duration != -1) {
3438 if (stream->timecodescale == 1.0)
3439 duration = gst_util_uint64_scale (block_duration,
3440 demux->common.time_scale, 1);
3443 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3444 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3445 1)) * stream->timecodescale);
3446 } else if (stream->default_duration) {
3447 duration = stream->default_duration * laces;
3449 /* else duration is diff between timecode of this and next block */
3451 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3452 a ReferenceBlock implies that this is not a keyframe. In either
3453 case, it only makes sense for video streams. */
3454 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3455 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
3457 if (delta_unit && stream->set_discont) {
3458 /* When doing seeks or such, we need to restart on key frames or
3459 * decoders might choke. */
3460 GST_DEBUG_OBJECT (demux, "skipping delta unit");
3464 for (n = 0; n < laces; n++) {
3467 if (G_UNLIKELY (lace_size[n] > size)) {
3468 GST_WARNING_OBJECT (demux, "Invalid lace size");
3472 /* QoS for video track with an index. the assumption is that
3473 index entries point to keyframes, but if that is not true we
3474 will instad skip until the next keyframe. */
3475 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3476 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3477 stream->index_table && demux->common.segment.rate > 0.0) {
3478 GstMatroskaTrackVideoContext *videocontext =
3479 (GstMatroskaTrackVideoContext *) stream;
3480 GstClockTime earliest_time;
3481 GstClockTime earliest_stream_time;
3483 GST_OBJECT_LOCK (demux);
3484 earliest_time = videocontext->earliest_time;
3485 GST_OBJECT_UNLOCK (demux);
3486 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3487 GST_FORMAT_TIME, earliest_time);
3489 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3490 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3491 lace_time <= earliest_stream_time) {
3492 /* find index entry (keyframe) <= earliest_stream_time */
3493 GstMatroskaIndex *entry =
3494 gst_util_array_binary_search (stream->index_table->data,
3495 stream->index_table->len, sizeof (GstMatroskaIndex),
3496 (GCompareDataFunc) gst_matroska_index_seek_find,
3497 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3499 /* if that entry (keyframe) is after the current the current
3500 buffer, we can skip pushing (and thus decoding) all
3501 buffers until that keyframe. */
3502 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3503 entry->time > lace_time) {
3504 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3505 stream->set_discont = TRUE;
3511 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3512 gst_buffer_get_size (buf) - size, lace_size[n]);
3513 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3516 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3518 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3520 if (stream->encodings != NULL && stream->encodings->len > 0)
3521 sub = gst_matroska_decode_buffer (stream, sub);
3524 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3528 GST_BUFFER_TIMESTAMP (sub) = lace_time;
3530 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3531 GstClockTime last_stop_end;
3533 /* Check if this stream is after segment stop */
3534 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3535 lace_time >= demux->common.segment.stop) {
3536 GST_DEBUG_OBJECT (demux,
3537 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3538 GST_TIME_ARGS (demux->common.segment.stop));
3539 gst_buffer_unref (sub);
3542 if (offset >= stream->to_offset) {
3543 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3545 gst_buffer_unref (sub);
3549 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3550 * that landed us with timestamps not quite intended */
3551 GST_OBJECT_LOCK (demux);
3552 if (demux->max_gap_time &&
3553 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3554 demux->common.segment.rate > 0.0) {
3555 GstClockTimeDiff diff;
3557 /* only send segments with increasing start times,
3558 * otherwise if these go back and forth downstream (sinks) increase
3559 * accumulated time and running_time */
3560 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3561 if (diff > 0 && diff > demux->max_gap_time
3562 && lace_time > demux->common.segment.start
3563 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3564 || lace_time < demux->common.segment.stop)) {
3566 GstEvent *event1, *event2;
3567 GST_DEBUG_OBJECT (demux,
3568 "Gap of %" G_GINT64_FORMAT " ns detected in"
3569 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3570 "Sending updated SEGMENT events", diff,
3571 stream->index, GST_TIME_ARGS (stream->pos),
3572 GST_TIME_ARGS (lace_time));
3573 /* send segment events such that the gap is not accounted in
3574 * segment base time, hence running_time */
3575 /* close ahead of gap */
3576 segment = demux->common.segment;
3577 segment.start = demux->last_stop_end;
3578 segment.stop = demux->last_stop_end;
3579 segment.position = demux->last_stop_end;
3580 event1 = gst_event_new_segment (&segment);
3582 segment.start = lace_time;
3583 segment.stop = demux->common.segment.stop;
3584 segment.position = lace_time;
3585 event2 = gst_event_new_segment (&segment);
3586 GST_OBJECT_UNLOCK (demux);
3587 gst_matroska_demux_send_event (demux, event1);
3588 gst_matroska_demux_send_event (demux, event2);
3589 GST_OBJECT_LOCK (demux);
3590 /* align segment view with downstream,
3591 * prevents double-counting base time when closing segment */
3592 /* FIXME: in 0.10, the segment base/accum got updated here, but
3593 * maybe we don't need that because of the double accounting
3594 * mentioned above? */
3595 demux->common.segment = segment;
3599 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3600 || demux->common.segment.position < lace_time) {
3601 demux->common.segment.position = lace_time;
3603 GST_OBJECT_UNLOCK (demux);
3605 last_stop_end = lace_time;
3607 GST_BUFFER_DURATION (sub) = duration / laces;
3608 last_stop_end += GST_BUFFER_DURATION (sub);
3611 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3612 demux->last_stop_end < last_stop_end)
3613 demux->last_stop_end = last_stop_end;
3615 GST_OBJECT_LOCK (demux);
3616 if (demux->common.segment.duration == -1 ||
3617 demux->stream_start_time + demux->common.segment.duration <
3619 demux->common.segment.duration =
3620 last_stop_end - demux->stream_start_time;
3621 GST_OBJECT_UNLOCK (demux);
3622 if (!demux->invalid_duration) {
3623 gst_element_post_message (GST_ELEMENT_CAST (demux),
3624 gst_message_new_duration (GST_OBJECT_CAST (demux),
3625 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
3626 demux->invalid_duration = TRUE;
3629 GST_OBJECT_UNLOCK (demux);
3633 stream->pos = lace_time;
3635 gst_matroska_demux_sync_streams (demux);
3637 if (stream->set_discont) {
3638 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3639 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3640 stream->set_discont = FALSE;
3643 /* reverse playback book-keeping */
3644 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3645 stream->from_time = lace_time;
3646 if (stream->from_offset == -1)
3647 stream->from_offset = offset;
3649 GST_DEBUG_OBJECT (demux,
3650 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3651 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3652 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3653 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
3654 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3657 if (demux->common.element_index) {
3658 if (stream->index_writer_id == -1)
3659 gst_index_get_writer_id (demux->common.element_index,
3660 GST_OBJECT (stream->pad), &stream->index_writer_id);
3662 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3663 G_GUINT64_FORMAT " for writer id %d",
3664 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
3665 stream->index_writer_id);
3666 gst_index_add_association (demux->common.element_index,
3667 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3668 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3669 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
3670 cluster_offset, NULL);
3674 /* Postprocess the buffers depending on the codec used */
3675 if (stream->postprocess_frame) {
3676 GST_LOG_OBJECT (demux, "running post process");
3677 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3680 /* At this point, we have a sub-buffer pointing at data within a larger
3681 buffer. This data might not be aligned with anything. If the data is
3682 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3683 for 32 bit samples, etc), or bad things will happen downstream as
3684 elements typically assume minimal alignment.
3685 Therefore, create an aligned copy if necessary. */
3686 g_assert (stream->alignment <= G_MEM_ALIGN);
3687 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3689 ret = gst_pad_push (stream->pad, sub);
3690 if (demux->common.segment.rate < 0) {
3691 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3692 /* In reverse playback we can get a GST_FLOW_EOS when
3693 * we are at the end of the segment, so we just need to jump
3694 * back to the previous section. */
3695 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3700 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3703 size -= lace_size[n];
3704 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3705 lace_time += duration / laces;
3707 lace_time = GST_CLOCK_TIME_NONE;
3713 gst_buffer_unmap (buf, &map);
3714 gst_buffer_unref (buf);
3726 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3731 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3732 /* non-fatal, try next block(group) */
3738 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3739 /* non-fatal, try next block(group) */
3745 /* return FALSE if block(group) should be skipped (due to a seek) */
3746 static inline gboolean
3747 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3749 if (G_UNLIKELY (demux->seek_block)) {
3750 if (!(--demux->seek_block)) {
3753 GST_LOG_OBJECT (demux, "should skip block due to seek");
3761 static GstFlowReturn
3762 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3766 guint64 seek_pos = (guint64) - 1;
3767 guint32 seek_id = 0;
3770 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3772 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3773 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3777 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3778 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3782 case GST_MATROSKA_ID_SEEKID:
3786 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3789 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3794 case GST_MATROSKA_ID_SEEKPOSITION:
3798 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3801 if (t > G_MAXINT64) {
3802 GST_WARNING_OBJECT (demux,
3803 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3807 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3813 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3819 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3822 if (!seek_id || seek_pos == (guint64) - 1) {
3823 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3824 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3829 case GST_MATROSKA_ID_SEEKHEAD:
3832 case GST_MATROSKA_ID_CUES:
3833 case GST_MATROSKA_ID_TAGS:
3834 case GST_MATROSKA_ID_TRACKS:
3835 case GST_MATROSKA_ID_SEGMENTINFO:
3836 case GST_MATROSKA_ID_ATTACHMENTS:
3837 case GST_MATROSKA_ID_CHAPTERS:
3839 guint64 before_pos, length;
3843 length = gst_matroska_read_common_get_length (&demux->common);
3844 before_pos = demux->common.offset;
3846 if (length == (guint64) - 1) {
3847 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3851 /* check for validity */
3852 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3853 GST_WARNING_OBJECT (demux,
3854 "SeekHead reference lies outside file!" " (%"
3855 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3856 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3861 /* only pick up index location when streaming */
3862 if (demux->streaming) {
3863 if (seek_id == GST_MATROSKA_ID_CUES) {
3864 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3865 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3866 demux->index_offset);
3872 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3875 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3876 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3880 if (id != seek_id) {
3881 GST_WARNING_OBJECT (demux,
3882 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3883 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3886 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3891 demux->common.offset = before_pos;
3895 case GST_MATROSKA_ID_CLUSTER:
3897 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3899 GST_LOG_OBJECT (demux, "Cluster position");
3900 if (G_UNLIKELY (!demux->clusters))
3901 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3902 g_array_append_val (demux->clusters, pos);
3907 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3910 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3915 static GstFlowReturn
3916 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3918 GstFlowReturn ret = GST_FLOW_OK;
3921 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3923 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3924 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3928 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3929 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3933 case GST_MATROSKA_ID_SEEKENTRY:
3935 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3936 /* Ignore EOS and errors here */
3937 if (ret != GST_FLOW_OK) {
3938 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3945 ret = gst_matroska_read_common_parse_skip (&demux->common,
3946 ebml, "SeekHead", id);
3951 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3953 /* Sort clusters by position for easier searching */
3954 if (demux->clusters)
3955 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3960 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3962 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3964 static inline GstFlowReturn
3965 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
3967 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
3968 /* only a few blocks are expected/allowed to be large,
3969 * and will be recursed into, whereas others will be read and must fit */
3970 if (demux->streaming) {
3971 /* fatal in streaming case, as we can't step over easily */
3972 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3973 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
3974 "file might be corrupt.", bytes));
3975 return GST_FLOW_ERROR;
3977 /* indicate higher level to quietly give up */
3978 GST_DEBUG_OBJECT (demux,
3979 "too large block of size %" G_GUINT64_FORMAT, bytes);
3980 return GST_FLOW_ERROR;
3987 /* returns TRUE if we truely are in error state, and should give up */
3988 static inline gboolean
3989 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
3991 if (!demux->streaming && demux->next_cluster_offset > 0) {
3992 /* just repositioning to where next cluster should be and try from there */
3993 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
3994 G_GUINT64_FORMAT, demux->next_cluster_offset);
3995 demux->common.offset = demux->next_cluster_offset;
3996 demux->next_cluster_offset = 0;
4001 /* sigh, one last attempt above and beyond call of duty ...;
4002 * search for cluster mark following current pos */
4003 pos = demux->common.offset;
4004 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4005 if (gst_matroska_demux_search_cluster (demux, &pos) != GST_FLOW_OK) {
4006 /* did not work, give up */
4009 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4010 /* try that position */
4011 demux->common.offset = pos;
4017 static inline GstFlowReturn
4018 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4020 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4021 demux->common.offset += flush;
4022 if (demux->streaming) {
4025 /* hard to skip large blocks when streaming */
4026 ret = gst_matroska_demux_check_read_size (demux, flush);
4027 if (ret != GST_FLOW_OK)
4029 if (flush <= gst_adapter_available (demux->common.adapter))
4030 gst_adapter_flush (demux->common.adapter, flush);
4032 return GST_FLOW_EOS;
4037 /* initializes @ebml with @bytes from input stream at current offset.
4038 * Returns EOS if insufficient available,
4039 * ERROR if too much was attempted to read. */
4040 static inline GstFlowReturn
4041 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4044 GstBuffer *buffer = NULL;
4045 GstFlowReturn ret = GST_FLOW_OK;
4047 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4049 ret = gst_matroska_demux_check_read_size (demux, bytes);
4050 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4051 if (!demux->streaming) {
4052 /* in pull mode, we can skip */
4053 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4054 ret = GST_FLOW_OVERFLOW;
4056 /* otherwise fatal */
4057 ret = GST_FLOW_ERROR;
4061 if (demux->streaming) {
4062 if (gst_adapter_available (demux->common.adapter) >= bytes)
4063 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4067 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4068 demux->common.offset, bytes, &buffer, NULL);
4069 if (G_LIKELY (buffer)) {
4070 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4071 demux->common.offset);
4072 demux->common.offset += bytes;
4079 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4082 gboolean seekable = FALSE;
4083 gint64 start = -1, stop = -1;
4085 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4086 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4087 GST_DEBUG_OBJECT (demux, "seeking query failed");
4091 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4093 /* try harder to query upstream size if we didn't get it the first time */
4094 if (seekable && stop == -1) {
4095 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4096 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4100 /* if upstream doesn't know the size, it's likely that it's not seekable in
4101 * practice even if it technically may be seekable */
4102 if (seekable && (start != 0 || stop <= start)) {
4103 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4108 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4109 G_GUINT64_FORMAT ")", seekable, start, stop);
4110 demux->seekable = seekable;
4112 gst_query_unref (query);
4115 static GstFlowReturn
4116 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4122 GstFlowReturn ret = GST_FLOW_OK;
4124 GST_WARNING_OBJECT (demux,
4125 "Found Cluster element before Tracks, searching Tracks");
4128 before_pos = demux->common.offset;
4130 /* Search Tracks element */
4132 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4133 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4134 if (ret != GST_FLOW_OK)
4137 if (id != GST_MATROSKA_ID_TRACKS) {
4138 /* we may be skipping large cluster here, so forego size check etc */
4139 /* ... but we can't skip undefined size; force error */
4140 if (length == G_MAXUINT64) {
4141 ret = gst_matroska_demux_check_read_size (demux, length);
4144 demux->common.offset += needed;
4145 demux->common.offset += length;
4150 /* will lead to track parsing ... */
4151 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4156 demux->common.offset = before_pos;
4161 #define GST_READ_CHECK(stmt) \
4163 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4164 if (ret == GST_FLOW_OVERFLOW) { \
4165 ret = GST_FLOW_OK; \
4171 static GstFlowReturn
4172 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4173 guint64 length, guint needed)
4175 GstEbmlRead ebml = { 0, };
4176 GstFlowReturn ret = GST_FLOW_OK;
4179 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4180 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4182 /* if we plan to read and parse this element, we need prefix (id + length)
4183 * and the contents */
4184 /* mind about overflow wrap-around when dealing with undefined size */
4186 if (G_LIKELY (length != G_MAXUINT64))
4189 switch (demux->common.state) {
4190 case GST_MATROSKA_READ_STATE_START:
4192 case GST_EBML_ID_HEADER:
4193 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4194 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4195 if (ret != GST_FLOW_OK)
4197 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4198 gst_matroska_demux_check_seekability (demux);
4201 goto invalid_header;
4205 case GST_MATROSKA_READ_STATE_SEGMENT:
4207 case GST_MATROSKA_ID_SEGMENT:
4208 /* eat segment prefix */
4209 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4210 GST_DEBUG_OBJECT (demux,
4211 "Found Segment start at offset %" G_GUINT64_FORMAT,
4212 demux->common.offset);
4213 /* seeks are from the beginning of the segment,
4214 * after the segment ID/length */
4215 demux->common.ebml_segment_start = demux->common.offset;
4216 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4219 GST_WARNING_OBJECT (demux,
4220 "Expected a Segment ID (0x%x), but received 0x%x!",
4221 GST_MATROSKA_ID_SEGMENT, id);
4222 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4226 case GST_MATROSKA_READ_STATE_SCANNING:
4227 if (id != GST_MATROSKA_ID_CLUSTER &&
4228 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4231 case GST_MATROSKA_READ_STATE_HEADER:
4232 case GST_MATROSKA_READ_STATE_DATA:
4233 case GST_MATROSKA_READ_STATE_SEEK:
4235 case GST_MATROSKA_ID_SEGMENTINFO:
4236 if (!demux->common.segmentinfo_parsed) {
4237 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4238 ret = gst_matroska_read_common_parse_info (&demux->common,
4239 GST_ELEMENT_CAST (demux), &ebml);
4241 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4244 case GST_MATROSKA_ID_TRACKS:
4245 if (!demux->tracks_parsed) {
4246 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4247 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4249 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4252 case GST_MATROSKA_ID_CLUSTER:
4253 if (G_UNLIKELY (!demux->tracks_parsed)) {
4254 if (demux->streaming) {
4255 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4256 goto not_streamable;
4258 ret = gst_matroska_demux_find_tracks (demux);
4259 if (!demux->tracks_parsed)
4263 if (G_UNLIKELY (demux->common.state
4264 == GST_MATROSKA_READ_STATE_HEADER)) {
4265 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4266 demux->first_cluster_offset = demux->common.offset;
4267 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4268 gst_element_no_more_pads (GST_ELEMENT (demux));
4269 /* send initial segment - we wait till we know the first
4270 incoming timestamp, so we can properly set the start of
4272 demux->need_segment = TRUE;
4274 demux->cluster_time = GST_CLOCK_TIME_NONE;
4275 demux->cluster_offset = demux->common.offset;
4276 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4277 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4278 " not found in Cluster, trying next Cluster's first block instead",
4280 demux->seek_block = 0;
4282 demux->seek_first = FALSE;
4283 /* record next cluster for recovery */
4284 if (read != G_MAXUINT64)
4285 demux->next_cluster_offset = demux->cluster_offset + read;
4286 /* eat cluster prefix */
4287 gst_matroska_demux_flush (demux, needed);
4289 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4293 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4294 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4296 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4297 demux->cluster_time = num;
4299 if (demux->common.element_index) {
4300 if (demux->common.element_index_writer_id == -1)
4301 gst_index_get_writer_id (demux->common.element_index,
4302 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4303 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4304 G_GUINT64_FORMAT " for writer id %d",
4305 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4306 demux->common.element_index_writer_id);
4307 gst_index_add_association (demux->common.element_index,
4308 demux->common.element_index_writer_id,
4309 GST_ASSOCIATION_FLAG_KEY_UNIT,
4310 GST_FORMAT_TIME, demux->cluster_time,
4311 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4316 case GST_MATROSKA_ID_BLOCKGROUP:
4317 if (!gst_matroska_demux_seek_block (demux))
4319 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4320 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4321 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4322 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4323 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4325 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4327 case GST_MATROSKA_ID_SIMPLEBLOCK:
4328 if (!gst_matroska_demux_seek_block (demux))
4330 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4331 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4332 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4333 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4334 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4336 case GST_MATROSKA_ID_ATTACHMENTS:
4337 if (!demux->common.attachments_parsed) {
4338 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4339 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4340 GST_ELEMENT_CAST (demux), &ebml);
4342 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4345 case GST_MATROSKA_ID_TAGS:
4346 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4347 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4348 GST_ELEMENT_CAST (demux), &ebml);
4350 case GST_MATROSKA_ID_CHAPTERS:
4351 if (!demux->common.chapters_parsed) {
4352 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4354 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4356 if (demux->common.toc) {
4357 gst_matroska_demux_send_event (demux,
4358 gst_event_new_toc (demux->common.toc, FALSE));
4359 gst_element_post_message (GST_ELEMENT_CAST (demux),
4360 gst_message_new_toc (GST_OBJECT_CAST (demux),
4361 demux->common.toc, FALSE));
4364 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4366 case GST_MATROSKA_ID_SEEKHEAD:
4367 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4368 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4370 case GST_MATROSKA_ID_CUES:
4371 if (demux->common.index_parsed) {
4372 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4375 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4376 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4377 /* only push based; delayed index building */
4378 if (ret == GST_FLOW_OK
4379 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4382 GST_OBJECT_LOCK (demux);
4383 event = demux->seek_event;
4384 demux->seek_event = NULL;
4385 GST_OBJECT_UNLOCK (demux);
4388 /* unlikely to fail, since we managed to seek to this point */
4389 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4391 /* resume data handling, main thread clear to seek again */
4392 GST_OBJECT_LOCK (demux);
4393 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4394 GST_OBJECT_UNLOCK (demux);
4397 case GST_MATROSKA_ID_POSITION:
4398 case GST_MATROSKA_ID_PREVSIZE:
4399 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4400 case GST_MATROSKA_ID_SILENTTRACKS:
4401 GST_DEBUG_OBJECT (demux,
4402 "Skipping Cluster subelement 0x%x - ignoring", id);
4406 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4407 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4413 if (ret == GST_FLOW_PARSE)
4417 gst_ebml_read_clear (&ebml);
4423 /* simply exit, maybe not enough data yet */
4424 /* no ebml to clear if read error */
4429 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4430 ("Failed to parse Element 0x%x", id));
4431 ret = GST_FLOW_ERROR;
4436 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4437 ("File layout does not permit streaming"));
4438 ret = GST_FLOW_ERROR;
4443 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4444 ("No Tracks element found"));
4445 ret = GST_FLOW_ERROR;
4450 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4451 ret = GST_FLOW_ERROR;
4456 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4457 ret = GST_FLOW_ERROR;
4463 gst_matroska_demux_loop (GstPad * pad)
4465 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4471 /* If we have to close a segment, send a new segment to do this now */
4472 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4473 if (G_UNLIKELY (demux->new_segment)) {
4474 gst_matroska_demux_send_event (demux, demux->new_segment);
4475 demux->new_segment = NULL;
4479 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4480 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4481 if (ret == GST_FLOW_EOS)
4483 if (ret != GST_FLOW_OK) {
4484 if (gst_matroska_demux_check_parse_error (demux))
4490 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4491 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4494 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4495 if (ret == GST_FLOW_EOS)
4497 if (ret != GST_FLOW_OK)
4500 /* check if we're at the end of a configured segment */
4501 if (G_LIKELY (demux->common.src->len)) {
4504 g_assert (demux->common.num_streams == demux->common.src->len);
4505 for (i = 0; i < demux->common.src->len; i++) {
4506 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4508 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4509 GST_TIME_ARGS (context->pos));
4510 if (context->eos == FALSE)
4514 GST_INFO_OBJECT (demux, "All streams are EOS");
4520 if (G_UNLIKELY (demux->common.offset ==
4521 gst_matroska_read_common_get_length (&demux->common))) {
4522 GST_LOG_OBJECT (demux, "Reached end of stream");
4532 if (demux->common.segment.rate < 0.0) {
4533 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4534 if (ret == GST_FLOW_OK)
4541 const gchar *reason = gst_flow_get_name (ret);
4542 gboolean push_eos = FALSE;
4544 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4545 gst_pad_pause_task (demux->common.sinkpad);
4547 if (ret == GST_FLOW_EOS) {
4548 /* perform EOS logic */
4550 /* If we were in the headers, make sure we send no-more-pads.
4551 This will ensure decodebin2 does not get stuck thinking
4552 the chain is not complete yet, and waiting indefinitely. */
4553 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4554 if (demux->common.src->len == 0) {
4555 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4556 ("No pads created"));
4558 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4559 ("Failed to finish reading headers"));
4561 gst_element_no_more_pads (GST_ELEMENT (demux));
4564 /* Close the segment, i.e. update segment stop with the duration
4565 * if no stop was set */
4566 if (GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
4567 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
4568 GST_CLOCK_TIME_IS_VALID (demux->common.segment.start) &&
4569 demux->last_stop_end > demux->common.segment.start) {
4570 GstSegment segment = demux->common.segment;
4573 segment.stop = demux->last_stop_end;
4574 event = gst_event_new_segment (&segment);
4575 gst_matroska_demux_send_event (demux, event);
4578 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4581 /* for segment playback we need to post when (in stream time)
4582 * we stopped, this is either stop (when set) or the duration. */
4583 if ((stop = demux->common.segment.stop) == -1)
4584 stop = demux->last_stop_end;
4586 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4587 gst_element_post_message (GST_ELEMENT (demux),
4588 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4593 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4594 /* for fatal errors we post an error message */
4595 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4596 ("stream stopped, reason %s", reason));
4600 /* send EOS, and prevent hanging if no streams yet */
4601 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4602 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4603 (ret == GST_FLOW_EOS)) {
4604 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4605 (NULL), ("got eos but no streams (yet)"));
4613 * Create and push a flushing seek event upstream
4616 perform_seek_to_offset (GstMatroskaDemux * demux, guint64 offset)
4621 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4624 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
4625 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4626 GST_SEEK_TYPE_NONE, -1);
4628 res = gst_pad_push_event (demux->common.sinkpad, event);
4630 /* segment event will update offset */
4634 static GstFlowReturn
4635 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4637 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4639 GstFlowReturn ret = GST_FLOW_OK;
4644 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4645 GST_DEBUG_OBJECT (demux, "got DISCONT");
4646 gst_adapter_clear (demux->common.adapter);
4647 GST_OBJECT_LOCK (demux);
4648 gst_matroska_read_common_reset_streams (&demux->common,
4649 GST_CLOCK_TIME_NONE, FALSE);
4650 GST_OBJECT_UNLOCK (demux);
4653 gst_adapter_push (demux->common.adapter, buffer);
4657 available = gst_adapter_available (demux->common.adapter);
4659 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4660 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4661 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS))
4664 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4665 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4666 demux->common.offset, id, length, needed, available);
4668 if (needed > available)
4671 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4672 if (ret == GST_FLOW_EOS) {
4673 /* need more data */
4675 } else if (ret != GST_FLOW_OK) {
4682 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4685 gboolean res = TRUE;
4686 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4688 GST_DEBUG_OBJECT (demux,
4689 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4691 switch (GST_EVENT_TYPE (event)) {
4692 case GST_EVENT_SEGMENT:
4694 const GstSegment *segment;
4696 /* some debug output */
4697 gst_event_parse_segment (event, &segment);
4698 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4699 GST_DEBUG_OBJECT (demux,
4700 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4703 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4704 GST_DEBUG_OBJECT (demux, "still starting");
4708 /* we only expect a BYTE segment, e.g. following a seek */
4709 if (segment->format != GST_FORMAT_BYTES) {
4710 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4714 GST_DEBUG_OBJECT (demux, "clearing segment state");
4715 GST_OBJECT_LOCK (demux);
4716 /* clear current segment leftover */
4717 gst_adapter_clear (demux->common.adapter);
4718 /* and some streaming setup */
4719 demux->common.offset = segment->start;
4720 /* do not know where we are;
4721 * need to come across a cluster and generate segment */
4722 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4723 demux->cluster_time = GST_CLOCK_TIME_NONE;
4724 demux->cluster_offset = 0;
4725 demux->need_segment = TRUE;
4726 /* but keep some of the upstream segment */
4727 demux->common.segment.rate = segment->rate;
4728 GST_OBJECT_UNLOCK (demux);
4730 /* chain will send initial segment after pads have been added,
4731 * or otherwise come up with one */
4732 GST_DEBUG_OBJECT (demux, "eating event");
4733 gst_event_unref (event);
4739 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4740 gst_event_unref (event);
4741 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4742 (NULL), ("got eos and didn't receive a complete header object"));
4743 } else if (demux->common.num_streams == 0) {
4744 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4745 (NULL), ("got eos but no streams (yet)"));
4747 gst_matroska_demux_send_event (demux, event);
4751 case GST_EVENT_FLUSH_STOP:
4755 gst_adapter_clear (demux->common.adapter);
4756 GST_OBJECT_LOCK (demux);
4757 gst_matroska_read_common_reset_streams (&demux->common,
4758 GST_CLOCK_TIME_NONE, TRUE);
4759 dur = demux->common.segment.duration;
4760 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4761 demux->common.segment.duration = dur;
4762 demux->cluster_time = GST_CLOCK_TIME_NONE;
4763 demux->cluster_offset = 0;
4764 GST_OBJECT_UNLOCK (demux);
4768 res = gst_pad_event_default (pad, parent, event);
4776 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4778 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4780 gboolean pull_mode = FALSE;
4782 query = gst_query_new_scheduling ();
4784 if (gst_pad_peer_query (sinkpad, query))
4785 pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL);
4787 gst_query_unref (query);
4790 GST_DEBUG ("going to pull mode");
4791 demux->streaming = FALSE;
4792 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4794 GST_DEBUG ("going to push (streaming) mode");
4795 demux->streaming = TRUE;
4796 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4801 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4802 GstPadMode mode, gboolean active)
4805 case GST_PAD_MODE_PULL:
4807 /* if we have a scheduler we can start the task */
4808 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4811 gst_pad_stop_task (sinkpad);
4814 case GST_PAD_MODE_PUSH:
4822 gst_duration_to_fraction (guint64 duration, gint * dest_n, gint * dest_d)
4824 static const int common_den[] = { 1, 2, 3, 4, 1001 };
4829 for (i = 0; i < G_N_ELEMENTS (common_den); i++) {
4831 n = floor (0.5 + (d * 1e9) / duration);
4832 a = gst_util_uint64_scale_int (1000000000, d, n);
4833 if (duration >= a - 1 && duration <= a + 1) {
4838 gst_util_double_to_fraction (1e9 / duration, &n, &d);
4847 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4848 videocontext, const gchar * codec_id, guint8 * data, guint size,
4849 gchar ** codec_name, guint32 * riff_fourcc)
4851 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4852 GstCaps *caps = NULL;
4854 g_assert (videocontext != NULL);
4855 g_assert (codec_name != NULL);
4857 context->send_xiph_headers = FALSE;
4858 context->send_flac_headers = FALSE;
4859 context->send_speex_headers = FALSE;
4864 /* TODO: check if we have all codec types from matroska-ids.h
4865 * check if we have to do more special things with codec_private
4868 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4869 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4872 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4873 gst_riff_strf_vids *vids = NULL;
4876 GstBuffer *buf = NULL;
4878 vids = (gst_riff_strf_vids *) data;
4880 /* assure size is big enough */
4882 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4885 if (size < sizeof (gst_riff_strf_vids)) {
4886 vids = g_new (gst_riff_strf_vids, 1);
4887 memcpy (vids, data, size);
4890 /* little-endian -> byte-order */
4891 vids->size = GUINT32_FROM_LE (vids->size);
4892 vids->width = GUINT32_FROM_LE (vids->width);
4893 vids->height = GUINT32_FROM_LE (vids->height);
4894 vids->planes = GUINT16_FROM_LE (vids->planes);
4895 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4896 vids->compression = GUINT32_FROM_LE (vids->compression);
4897 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4898 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4899 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4900 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4901 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4903 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4904 gsize offset = sizeof (gst_riff_strf_vids);
4907 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
4908 size - offset), size - offset);
4912 *riff_fourcc = vids->compression;
4914 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4915 buf, NULL, codec_name);
4918 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4919 GST_FOURCC_ARGS (vids->compression));
4923 gst_buffer_unref (buf);
4925 if (vids != (gst_riff_strf_vids *) data)
4928 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4929 const gchar *format = NULL;
4931 switch (videocontext->fourcc) {
4932 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4933 *codec_name = g_strdup ("Raw planar YUV 4:2:0");
4936 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4937 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
4940 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4941 *codec_name = g_strdup ("Raw packed YUV 4:2:0");
4944 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4945 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
4948 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4949 *codec_name = g_strdup ("Raw packed YUV 4:4:4 with alpha channel");
4954 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
4955 GST_FOURCC_ARGS (videocontext->fourcc));
4959 caps = gst_caps_new_simple ("video/x-raw",
4960 "format", G_TYPE_STRING, format, NULL);
4961 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
4962 caps = gst_caps_new_simple ("video/x-divx",
4963 "divxversion", G_TYPE_INT, 4, NULL);
4964 *codec_name = g_strdup ("MPEG-4 simple profile");
4965 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
4966 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
4968 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4969 "divxversion", G_TYPE_INT, 5, NULL),
4970 gst_structure_new ("video/x-xvid", NULL),
4971 gst_structure_new ("video/mpeg",
4972 "mpegversion", G_TYPE_INT, 4,
4973 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
4975 caps = gst_caps_new_simple ("video/mpeg",
4976 "mpegversion", G_TYPE_INT, 4,
4977 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
4981 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4982 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4983 gst_buffer_unref (priv);
4985 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
4986 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
4988 *codec_name = g_strdup ("MPEG-4 advanced profile");
4989 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
4991 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4992 "divxversion", G_TYPE_INT, 3, NULL),
4993 gst_structure_new ("video/x-msmpeg",
4994 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
4996 caps = gst_caps_new_simple ("video/x-msmpeg",
4997 "msmpegversion", G_TYPE_INT, 43, NULL);
4998 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
4999 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5000 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5003 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5008 caps = gst_caps_new_simple ("video/mpeg",
5009 "systemstream", G_TYPE_BOOLEAN, FALSE,
5010 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5011 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5012 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5013 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5014 caps = gst_caps_new_empty_simple ("image/jpeg");
5015 *codec_name = g_strdup ("Motion-JPEG");
5016 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5017 caps = gst_caps_new_empty_simple ("video/x-h264");
5021 /* First byte is the version, second is the profile indication, and third
5022 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5023 * level indication. */
5024 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5027 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5028 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5029 gst_buffer_unref (priv);
5031 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5032 "alignment", G_TYPE_STRING, "au", NULL);
5034 GST_WARNING ("No codec data found, assuming output is byte-stream");
5035 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5038 *codec_name = g_strdup ("H264");
5039 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5040 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5041 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5042 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5043 gint rmversion = -1;
5045 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5047 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5049 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5051 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5054 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5055 "rmversion", G_TYPE_INT, rmversion, NULL);
5056 GST_DEBUG ("data:%p, size:0x%x", data, size);
5057 /* We need to extract the extradata ! */
5058 if (data && (size >= 0x22)) {
5063 subformat = GST_READ_UINT32_BE (data + 0x1a);
5064 rformat = GST_READ_UINT32_BE (data + 0x1e);
5067 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5069 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5070 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5071 gst_buffer_unref (priv);
5074 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5075 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5076 caps = gst_caps_new_empty_simple ("video/x-theora");
5077 context->send_xiph_headers = TRUE;
5078 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5079 caps = gst_caps_new_empty_simple ("video/x-dirac");
5080 *codec_name = g_strdup_printf ("Dirac");
5081 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5082 caps = gst_caps_new_empty_simple ("video/x-vp8");
5083 *codec_name = g_strdup_printf ("On2 VP8");
5085 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5091 GstStructure *structure;
5093 for (i = 0; i < gst_caps_get_size (caps); i++) {
5094 structure = gst_caps_get_structure (caps, i);
5096 /* FIXME: use the real unit here! */
5097 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5098 videocontext->pixel_width,
5099 videocontext->pixel_height,
5100 videocontext->display_width, videocontext->display_height);
5102 /* pixel width and height are the w and h of the video in pixels */
5103 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5104 gint w = videocontext->pixel_width;
5105 gint h = videocontext->pixel_height;
5107 gst_structure_set (structure,
5108 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5111 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5114 if (videocontext->display_width <= 0)
5115 videocontext->display_width = videocontext->pixel_width;
5116 if (videocontext->display_height <= 0)
5117 videocontext->display_height = videocontext->pixel_height;
5119 /* calculate the pixel aspect ratio using the display and pixel w/h */
5120 n = videocontext->display_width * videocontext->pixel_height;
5121 d = videocontext->display_height * videocontext->pixel_width;
5122 GST_DEBUG ("setting PAR to %d/%d", n, d);
5123 gst_structure_set (structure, "pixel-aspect-ratio",
5125 videocontext->display_width * videocontext->pixel_height,
5126 videocontext->display_height * videocontext->pixel_width, NULL);
5129 if (videocontext->default_fps > 0.0) {
5130 GValue fps_double = { 0, };
5131 GValue fps_fraction = { 0, };
5133 g_value_init (&fps_double, G_TYPE_DOUBLE);
5134 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
5135 g_value_set_double (&fps_double, videocontext->default_fps);
5136 g_value_transform (&fps_double, &fps_fraction);
5138 GST_DEBUG ("using default fps %f", videocontext->default_fps);
5140 gst_structure_set_value (structure, "framerate", &fps_fraction);
5141 g_value_unset (&fps_double);
5142 g_value_unset (&fps_fraction);
5143 } else if (context->default_duration > 0) {
5146 gst_duration_to_fraction (context->default_duration, &fps_n, &fps_d);
5148 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5149 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5151 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5152 fps_n, fps_d, NULL);
5154 /* sort of a hack to get most codecs to support,
5155 * even if the default_duration is missing */
5156 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5160 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5161 gst_structure_set (structure, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
5164 caps = gst_caps_simplify (caps);
5171 * Some AAC specific code... *sigh*
5172 * FIXME: maybe we should use '15' and code the sample rate explicitly
5173 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5177 aac_rate_idx (gint rate)
5181 else if (75132 <= rate)
5183 else if (55426 <= rate)
5185 else if (46009 <= rate)
5187 else if (37566 <= rate)
5189 else if (27713 <= rate)
5191 else if (23004 <= rate)
5193 else if (18783 <= rate)
5195 else if (13856 <= rate)
5197 else if (11502 <= rate)
5199 else if (9391 <= rate)
5206 aac_profile_idx (const gchar * codec_id)
5210 if (strlen (codec_id) <= 12)
5212 else if (!strncmp (&codec_id[12], "MAIN", 4))
5214 else if (!strncmp (&codec_id[12], "LC", 2))
5216 else if (!strncmp (&codec_id[12], "SSR", 3))
5224 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5227 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5228 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5229 gchar ** codec_name, guint16 * riff_audio_fmt)
5231 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5232 GstCaps *caps = NULL;
5234 g_assert (audiocontext != NULL);
5235 g_assert (codec_name != NULL);
5238 *riff_audio_fmt = 0;
5240 context->send_xiph_headers = FALSE;
5241 context->send_flac_headers = FALSE;
5242 context->send_speex_headers = FALSE;
5244 /* TODO: check if we have all codec types from matroska-ids.h
5245 * check if we have to do more special things with codec_private
5246 * check if we need bitdepth in different places too
5247 * implement channel position magic
5249 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5250 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5251 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5252 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5255 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5256 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5257 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5260 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5262 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5267 caps = gst_caps_new_simple ("audio/mpeg",
5268 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5269 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5270 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5271 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5274 GstAudioFormat format;
5276 sign = (audiocontext->bitdepth != 8);
5277 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5278 endianness = G_BIG_ENDIAN;
5280 endianness = G_LITTLE_ENDIAN;
5282 format = gst_audio_format_build_integer (sign, endianness,
5283 audiocontext->bitdepth, audiocontext->bitdepth);
5285 /* FIXME: Channel mask and reordering */
5286 caps = gst_caps_new_simple ("audio/x-raw",
5287 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5288 "layout", G_TYPE_STRING, "interleaved", NULL);
5290 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5291 audiocontext->bitdepth);
5292 context->alignment = audiocontext->bitdepth / 8;
5293 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5294 const gchar *format;
5295 if (audiocontext->bitdepth == 32)
5299 /* FIXME: Channel mask and reordering */
5300 caps = gst_caps_new_simple ("audio/x-raw",
5301 "format", G_TYPE_STRING, format,
5302 "layout", G_TYPE_STRING, "interleaved", NULL);
5303 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5304 audiocontext->bitdepth);
5305 context->alignment = audiocontext->bitdepth / 8;
5306 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5307 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5308 caps = gst_caps_new_simple ("audio/x-ac3",
5309 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5310 *codec_name = g_strdup ("AC-3 audio");
5311 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5312 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5313 caps = gst_caps_new_simple ("audio/x-eac3",
5314 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5315 *codec_name = g_strdup ("E-AC-3 audio");
5316 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5317 caps = gst_caps_new_empty_simple ("audio/x-dts");
5318 *codec_name = g_strdup ("DTS audio");
5319 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5320 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5321 context->send_xiph_headers = TRUE;
5322 /* vorbis decoder does tags */
5323 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5324 caps = gst_caps_new_empty_simple ("audio/x-flac");
5325 context->send_flac_headers = TRUE;
5326 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5327 caps = gst_caps_new_empty_simple ("audio/x-speex");
5328 context->send_speex_headers = TRUE;
5329 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5330 gst_riff_strf_auds auds;
5333 GstBuffer *codec_data;
5335 /* little-endian -> byte-order */
5336 auds.format = GST_READ_UINT16_LE (data);
5337 auds.channels = GST_READ_UINT16_LE (data + 2);
5338 auds.rate = GST_READ_UINT32_LE (data + 4);
5339 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5340 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5341 auds.size = GST_READ_UINT16_LE (data + 16);
5343 /* 18 is the waveformatex size */
5344 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5345 data + 18, auds.size, 0, auds.size, NULL, NULL);
5348 *riff_audio_fmt = auds.format;
5350 /* FIXME: Handle reorder map */
5351 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5352 codec_data, codec_name, NULL);
5353 gst_buffer_unref (codec_data);
5356 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5359 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5360 GstBuffer *priv = NULL;
5362 gint rate_idx, profile;
5363 guint8 *data = NULL;
5365 /* unspecified AAC profile with opaque private codec data */
5366 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5367 if (context->codec_priv_size >= 2) {
5368 guint obj_type, freq_index, explicit_freq_bytes = 0;
5370 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5372 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5373 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5374 if (freq_index == 15)
5375 explicit_freq_bytes = 3;
5376 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5377 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5378 context->codec_priv_size), context->codec_priv_size);
5379 /* assume SBR if samplerate <= 24kHz */
5380 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5381 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5382 audiocontext->samplerate *= 2;
5385 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5386 /* this is pretty broken;
5387 * maybe we need to make up some default private,
5388 * or maybe ADTS data got dumped in.
5389 * Let's set up some private data now, and check actual data later */
5390 /* just try this and see what happens ... */
5391 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5392 context->postprocess_frame = gst_matroska_demux_check_aac;
5396 /* make up decoder-specific data if it is not supplied */
5400 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5401 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5403 rate_idx = aac_rate_idx (audiocontext->samplerate);
5404 profile = aac_profile_idx (codec_id);
5406 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5407 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5409 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5410 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5412 gst_buffer_unmap (priv, &map);
5413 gst_buffer_set_size (priv, 2);
5414 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5415 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5418 if (g_strrstr (codec_id, "SBR")) {
5419 /* HE-AAC (aka SBR AAC) */
5420 audiocontext->samplerate *= 2;
5421 rate_idx = aac_rate_idx (audiocontext->samplerate);
5422 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5423 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5424 data[4] = (1 << 7) | (rate_idx << 3);
5425 gst_buffer_unmap (priv, &map);
5427 gst_buffer_unmap (priv, &map);
5428 gst_buffer_set_size (priv, 2);
5431 gst_buffer_unmap (priv, &map);
5432 gst_buffer_unref (priv);
5434 GST_ERROR ("Unknown AAC profile and no codec private data");
5439 caps = gst_caps_new_simple ("audio/mpeg",
5440 "mpegversion", G_TYPE_INT, mpegversion,
5441 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5442 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5443 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5444 gst_buffer_unref (priv);
5446 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5447 caps = gst_caps_new_simple ("audio/x-tta",
5448 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5449 *codec_name = g_strdup ("TTA audio");
5450 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5451 caps = gst_caps_new_simple ("audio/x-wavpack",
5452 "width", G_TYPE_INT, audiocontext->bitdepth,
5453 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5454 *codec_name = g_strdup ("Wavpack audio");
5455 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5456 audiocontext->wvpk_block_index = 0;
5457 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5458 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5459 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5460 gint raversion = -1;
5462 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5464 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5469 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5470 "raversion", G_TYPE_INT, raversion, NULL);
5471 /* Extract extra information from caps, mapping varies based on codec */
5472 if (data && (size >= 0x50)) {
5479 guint extra_data_size;
5481 GST_ERROR ("real audio raversion:%d", raversion);
5482 if (raversion == 8) {
5484 flavor = GST_READ_UINT16_BE (data + 22);
5485 packet_size = GST_READ_UINT32_BE (data + 24);
5486 height = GST_READ_UINT16_BE (data + 40);
5487 leaf_size = GST_READ_UINT16_BE (data + 44);
5488 sample_width = GST_READ_UINT16_BE (data + 58);
5489 extra_data_size = GST_READ_UINT32_BE (data + 74);
5492 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5493 flavor, packet_size, height, leaf_size, sample_width,
5495 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5496 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5497 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5499 if ((size - 78) >= extra_data_size) {
5500 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5502 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5503 gst_buffer_unref (priv);
5508 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5509 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5510 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5511 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5512 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5513 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5514 *codec_name = g_strdup ("Real Audio Lossless");
5515 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5516 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5517 *codec_name = g_strdup ("Sony ATRAC3");
5519 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5524 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5527 for (i = 0; i < gst_caps_get_size (caps); i++) {
5528 gst_structure_set (gst_caps_get_structure (caps, i),
5529 "channels", G_TYPE_INT, audiocontext->channels,
5530 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5534 caps = gst_caps_simplify (caps);
5541 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5542 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5544 GstCaps *caps = NULL;
5545 GstMatroskaTrackContext *context =
5546 (GstMatroskaTrackContext *) subtitlecontext;
5548 /* for backwards compatibility */
5549 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5550 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5551 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5552 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5553 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5554 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5555 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5556 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5558 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5559 * Check if we have to do something with codec_private */
5560 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5561 /* well, plain text simply does not have a lot of markup ... */
5562 caps = gst_caps_new_empty_simple ("text/x-pango-markup");
5563 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5564 subtitlecontext->check_markup = TRUE;
5565 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5566 caps = gst_caps_new_empty_simple ("application/x-ssa");
5567 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5568 subtitlecontext->check_markup = FALSE;
5569 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5570 caps = gst_caps_new_empty_simple ("application/x-ass");
5571 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5572 subtitlecontext->check_markup = FALSE;
5573 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5574 caps = gst_caps_new_empty_simple ("application/x-usf");
5575 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5576 subtitlecontext->check_markup = FALSE;
5577 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5578 caps = gst_caps_new_empty_simple ("video/x-dvd-subpicture");
5579 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5580 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5581 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5582 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5583 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5584 context->send_xiph_headers = TRUE;
5586 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5587 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5590 if (data != NULL && size > 0) {
5593 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5594 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5595 gst_buffer_unref (buf);
5603 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5605 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5607 GST_OBJECT_LOCK (demux);
5608 if (demux->common.element_index)
5609 gst_object_unref (demux->common.element_index);
5610 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5611 GST_OBJECT_UNLOCK (demux);
5612 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5613 demux->common.element_index);
5617 gst_matroska_demux_get_index (GstElement * element)
5619 GstIndex *result = NULL;
5620 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5622 GST_OBJECT_LOCK (demux);
5623 if (demux->common.element_index)
5624 result = gst_object_ref (demux->common.element_index);
5625 GST_OBJECT_UNLOCK (demux);
5627 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5633 static GstStateChangeReturn
5634 gst_matroska_demux_change_state (GstElement * element,
5635 GstStateChange transition)
5637 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5638 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5640 /* handle upwards state changes here */
5641 switch (transition) {
5646 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5648 /* handle downwards state changes */
5649 switch (transition) {
5650 case GST_STATE_CHANGE_PAUSED_TO_READY:
5651 gst_matroska_demux_reset (GST_ELEMENT (demux));
5661 gst_matroska_demux_set_property (GObject * object,
5662 guint prop_id, const GValue * value, GParamSpec * pspec)
5664 GstMatroskaDemux *demux;
5666 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5667 demux = GST_MATROSKA_DEMUX (object);
5670 case ARG_MAX_GAP_TIME:
5671 GST_OBJECT_LOCK (demux);
5672 demux->max_gap_time = g_value_get_uint64 (value);
5673 GST_OBJECT_UNLOCK (demux);
5676 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5682 gst_matroska_demux_get_property (GObject * object,
5683 guint prop_id, GValue * value, GParamSpec * pspec)
5685 GstMatroskaDemux *demux;
5687 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5688 demux = GST_MATROSKA_DEMUX (object);
5691 case ARG_MAX_GAP_TIME:
5692 GST_OBJECT_LOCK (demux);
5693 g_value_set_uint64 (value, demux->max_gap_time);
5694 GST_OBJECT_UNLOCK (demux);
5697 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5703 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5707 /* parser helper separate debug */
5708 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5709 0, "EBML stream helper class");
5711 /* create an elementfactory for the matroska_demux element */
5712 if (!gst_element_register (plugin, "matroskademux",
5713 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))