1 /* GStreamer Matroska muxer/demuxer
2 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3 * (c) 2006 Tim-Philipp Müller <tim centricular net>
4 * (c) 2008 Sebastian Dröge <slomo@circular-chaos.org>
5 * (c) 2011 Debarshi Ray <rishi@gnu.org>
7 * matroska-demux.c: matroska file/stream demuxer
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
25 /* TODO: check CRC32 if present
26 * TODO: there can be a segment after the first segment. Handle like
27 * chained oggs. Fixes #334082
28 * TODO: Test samples: http://www.matroska.org/samples/matrix/index.html
29 * http://samples.mplayerhq.hu/Matroska/
30 * TODO: check if demuxing is done correct for all codecs according to spec
31 * TODO: seeking with incomplete or without CUE
35 * SECTION:element-matroskademux
37 * matroskademux demuxes a Matroska file into the different contained streams.
40 * <title>Example launch line</title>
42 * gst-launch-1.0 -v filesrc location=/path/to/mkv ! matroskademux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
43 * ]| This pipeline demuxes a Matroska file and outputs the contained Vorbis audio.
54 #include <glib/gprintf.h>
56 /* For AVI compatibility mode
57 and for fourcc stuff */
58 #include <gst/riff/riff-read.h>
59 #include <gst/riff/riff-ids.h>
60 #include <gst/riff/riff-media.h>
62 #include <gst/audio/audio.h>
63 #include <gst/tag/tag.h>
64 #include <gst/pbutils/pbutils.h>
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-raw, format=pango-markup; application/x-ssa; "
118 "application/x-ass;application/x-usf; subpicture/x-dvd; "
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,
174 gdouble rate, guint64 offset, guint32 seqnum);
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_unref (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_unref (track->pending_tags);
314 if (track->index_table)
315 g_array_free (track->index_table, TRUE);
317 if (track->stream_headers)
318 gst_buffer_list_unref (track->stream_headers);
324 * Returns the aggregated GstFlowReturn.
327 gst_matroska_demux_combine_flows (GstMatroskaDemux * demux,
328 GstMatroskaTrackContext * track, GstFlowReturn ret)
332 /* store the value */
333 track->last_flow = ret;
335 /* any other error that is not-linked can be returned right away */
336 if (ret != GST_FLOW_NOT_LINKED)
339 /* only return NOT_LINKED if all other pads returned NOT_LINKED */
340 g_assert (demux->common.src->len == demux->common.num_streams);
341 for (i = 0; i < demux->common.src->len; i++) {
342 GstMatroskaTrackContext *ostream = g_ptr_array_index (demux->common.src,
348 ret = ostream->last_flow;
349 /* some other return value (must be SUCCESS but we can return
350 * other values as well) */
351 if (ret != GST_FLOW_NOT_LINKED)
354 /* if we get here, all other pads were unlinked and we return
357 GST_LOG_OBJECT (demux, "combined return %s", gst_flow_get_name (ret));
362 gst_matroska_demux_free_parsed_el (gpointer mem, gpointer user_data)
364 g_slice_free (guint64, mem);
368 gst_matroska_demux_reset (GstElement * element)
370 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
373 GST_DEBUG_OBJECT (demux, "Resetting state");
376 demux->common.state = GST_MATROSKA_READ_STATE_START;
378 /* clean up existing streams */
379 if (demux->common.src) {
380 g_assert (demux->common.src->len == demux->common.num_streams);
381 for (i = 0; i < demux->common.src->len; i++) {
382 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
385 if (context->pad != NULL)
386 gst_element_remove_pad (GST_ELEMENT (demux), context->pad);
388 gst_caps_replace (&context->caps, NULL);
389 gst_matroska_track_free (context);
391 g_ptr_array_free (demux->common.src, TRUE);
393 demux->common.src = g_ptr_array_new ();
395 demux->common.num_streams = 0;
396 demux->num_a_streams = 0;
397 demux->num_t_streams = 0;
398 demux->num_v_streams = 0;
400 demux->have_group_id = FALSE;
401 demux->group_id = G_MAXUINT;
403 /* reset media info */
404 g_free (demux->common.writing_app);
405 demux->common.writing_app = NULL;
406 g_free (demux->common.muxing_app);
407 demux->common.muxing_app = NULL;
410 if (demux->common.index) {
411 g_array_free (demux->common.index, TRUE);
412 demux->common.index = NULL;
415 if (demux->clusters) {
416 g_array_free (demux->clusters, TRUE);
417 demux->clusters = NULL;
422 demux->common.time_scale = 1000000;
423 demux->common.created = G_MININT64;
425 demux->common.index_parsed = FALSE;
426 demux->tracks_parsed = FALSE;
427 demux->common.segmentinfo_parsed = FALSE;
428 demux->common.attachments_parsed = FALSE;
429 demux->common.chapters_parsed = FALSE;
431 g_list_foreach (demux->common.tags_parsed,
432 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
433 g_list_free (demux->common.tags_parsed);
434 demux->common.tags_parsed = NULL;
436 g_list_foreach (demux->seek_parsed,
437 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
438 g_list_free (demux->seek_parsed);
439 demux->seek_parsed = NULL;
441 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
442 demux->last_stop_end = GST_CLOCK_TIME_NONE;
443 demux->seek_block = 0;
444 demux->stream_start_time = GST_CLOCK_TIME_NONE;
445 demux->to_time = GST_CLOCK_TIME_NONE;
447 demux->common.offset = 0;
448 demux->cluster_time = GST_CLOCK_TIME_NONE;
449 demux->cluster_offset = 0;
450 demux->next_cluster_offset = 0;
451 demux->index_offset = 0;
452 demux->seekable = FALSE;
453 demux->need_segment = FALSE;
454 demux->segment_seqnum = 0;
455 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
456 demux->seek_offset = -1;
457 demux->building_index = FALSE;
458 if (demux->seek_event) {
459 gst_event_unref (demux->seek_event);
460 demux->seek_event = NULL;
463 demux->seek_index = NULL;
464 demux->seek_entry = 0;
466 if (demux->new_segment) {
467 gst_event_unref (demux->new_segment);
468 demux->new_segment = NULL;
471 if (demux->common.element_index) {
472 gst_object_unref (demux->common.element_index);
473 demux->common.element_index = NULL;
475 demux->common.element_index_writer_id = -1;
478 if (demux->common.global_tags) {
479 gst_tag_list_unref (demux->common.global_tags);
481 demux->common.global_tags = gst_tag_list_new_empty ();
482 gst_tag_list_set_scope (demux->common.global_tags, GST_TAG_SCOPE_GLOBAL);
484 if (demux->common.cached_buffer) {
485 if (demux->common.cached_data) {
486 gst_buffer_unmap (demux->common.cached_buffer, &demux->common.cached_map);
487 demux->common.cached_data = NULL;
489 gst_buffer_unref (demux->common.cached_buffer);
490 demux->common.cached_buffer = NULL;
493 /* free chapters TOC if any */
494 if (demux->common.toc) {
495 gst_toc_unref (demux->common.toc);
496 demux->common.toc = NULL;
499 demux->invalid_duration = FALSE;
503 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
509 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
511 GST_DEBUG ("decoding buffer %p", buf);
513 gst_buffer_map (buf, &map, GST_MAP_READ);
517 g_return_val_if_fail (size > 0, buf);
519 if (gst_matroska_decode_data (context->encodings, &data, &size,
520 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
521 gst_buffer_unmap (buf, &map);
522 gst_buffer_unref (buf);
523 return gst_buffer_new_wrapped (data, size);
525 GST_DEBUG ("decode data failed");
526 gst_buffer_unmap (buf, &map);
527 gst_buffer_unref (buf);
533 gst_matroska_demux_add_stream_headers_to_caps (GstMatroskaDemux * demux,
534 GstBufferList * list, GstCaps * caps)
537 GValue arr_val = G_VALUE_INIT;
538 GValue buf_val = G_VALUE_INIT;
541 g_assert (gst_caps_is_writable (caps));
543 g_value_init (&arr_val, GST_TYPE_ARRAY);
544 g_value_init (&buf_val, GST_TYPE_BUFFER);
546 num = gst_buffer_list_length (list);
547 for (i = 0; i < num; ++i) {
548 g_value_set_boxed (&buf_val, gst_buffer_list_get (list, i));
549 gst_value_array_append_value (&arr_val, &buf_val);
552 s = gst_caps_get_structure (caps, 0);
553 gst_structure_take_value (s, "streamheader", &arr_val);
554 g_value_unset (&buf_val);
558 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
560 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
561 GstMatroskaTrackContext *context;
562 GstPadTemplate *templ = NULL;
563 GstStreamFlags stream_flags;
564 GstCaps *caps = NULL;
565 gchar *padname = NULL;
567 guint32 id, riff_fourcc = 0;
568 guint16 riff_audio_fmt = 0;
569 GstTagList *list = NULL;
570 GstEvent *stream_start;
574 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
576 /* start with the master */
577 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
578 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
582 /* allocate generic... if we know the type, we'll g_renew()
583 * with the precise type */
584 context = g_new0 (GstMatroskaTrackContext, 1);
585 g_ptr_array_add (demux->common.src, context);
586 context->index = demux->common.num_streams;
587 context->index_writer_id = -1;
588 context->type = 0; /* no type yet */
589 context->default_duration = 0;
591 context->set_discont = TRUE;
592 context->timecodescale = 1.0;
594 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
595 GST_MATROSKA_TRACK_LACING;
596 context->last_flow = GST_FLOW_OK;
597 context->from_time = GST_CLOCK_TIME_NONE;
598 context->from_offset = -1;
599 context->to_offset = G_MAXINT64;
600 context->alignment = 1;
601 demux->common.num_streams++;
602 g_assert (demux->common.src->len == demux->common.num_streams);
604 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
606 /* try reading the trackentry headers */
607 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
608 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
612 /* track number (unique stream ID) */
613 case GST_MATROSKA_ID_TRACKNUMBER:{
616 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
620 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
621 ret = GST_FLOW_ERROR;
623 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
625 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
626 " is not unique", num);
627 ret = GST_FLOW_ERROR;
631 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
635 /* track UID (unique identifier) */
636 case GST_MATROSKA_ID_TRACKUID:{
639 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
643 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
644 ret = GST_FLOW_ERROR;
648 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
653 /* track type (video, audio, combined, subtitle, etc.) */
654 case GST_MATROSKA_ID_TRACKTYPE:{
657 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
661 if (context->type != 0 && context->type != track_type) {
662 GST_WARNING_OBJECT (demux,
663 "More than one tracktype defined in a TrackEntry - skipping");
665 } else if (track_type < 1 || track_type > 254) {
666 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
671 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
673 /* ok, so we're actually going to reallocate this thing */
674 switch (track_type) {
675 case GST_MATROSKA_TRACK_TYPE_VIDEO:
676 gst_matroska_track_init_video_context (&context);
678 case GST_MATROSKA_TRACK_TYPE_AUDIO:
679 gst_matroska_track_init_audio_context (&context);
681 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
682 gst_matroska_track_init_subtitle_context (&context);
684 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
685 case GST_MATROSKA_TRACK_TYPE_LOGO:
686 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
687 case GST_MATROSKA_TRACK_TYPE_CONTROL:
689 GST_WARNING_OBJECT (demux,
690 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
695 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
700 /* tracktype specific stuff for video */
701 case GST_MATROSKA_ID_TRACKVIDEO:{
702 GstMatroskaTrackVideoContext *videocontext;
704 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
706 if (!gst_matroska_track_init_video_context (&context)) {
707 GST_WARNING_OBJECT (demux,
708 "TrackVideo element in non-video track - ignoring track");
709 ret = GST_FLOW_ERROR;
711 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
714 videocontext = (GstMatroskaTrackVideoContext *) context;
715 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
718 while (ret == GST_FLOW_OK &&
719 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
720 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
724 /* Should be one level up but some broken muxers write it here. */
725 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
728 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
732 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
736 GST_DEBUG_OBJECT (demux,
737 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
738 context->default_duration = num;
742 /* video framerate */
743 /* NOTE: This one is here only for backward compatibility.
744 * Use _TRACKDEFAULDURATION one level up. */
745 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
748 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
752 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
756 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
757 if (context->default_duration == 0)
758 context->default_duration =
759 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
760 videocontext->default_fps = num;
764 /* width of the size to display the video at */
765 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
768 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
772 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
776 GST_DEBUG_OBJECT (demux,
777 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
778 videocontext->display_width = num;
782 /* height of the size to display the video at */
783 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
786 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
790 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
794 GST_DEBUG_OBJECT (demux,
795 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
796 videocontext->display_height = num;
800 /* width of the video in the file */
801 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
804 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
808 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
812 GST_DEBUG_OBJECT (demux,
813 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
814 videocontext->pixel_width = num;
818 /* height of the video in the file */
819 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
822 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
826 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
830 GST_DEBUG_OBJECT (demux,
831 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
832 videocontext->pixel_height = num;
836 /* whether the video is interlaced */
837 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
840 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
844 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
846 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
847 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
848 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
853 /* aspect ratio behaviour */
854 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
857 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
860 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
861 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
862 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
863 GST_WARNING_OBJECT (demux,
864 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
867 GST_DEBUG_OBJECT (demux,
868 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
869 videocontext->asr_mode = num;
873 /* colourspace (only matters for raw video) fourcc */
874 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
879 gst_ebml_read_binary (ebml, &id, &data,
880 &datalen)) != GST_FLOW_OK)
885 GST_WARNING_OBJECT (demux,
886 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
891 memcpy (&videocontext->fourcc, data, 4);
892 GST_DEBUG_OBJECT (demux,
893 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
894 GST_FOURCC_ARGS (videocontext->fourcc));
900 GST_WARNING_OBJECT (demux,
901 "Unknown TrackVideo subelement 0x%x - ignoring", id);
903 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
904 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
905 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
906 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
907 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
908 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
909 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
910 ret = gst_ebml_read_skip (ebml);
915 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
919 /* tracktype specific stuff for audio */
920 case GST_MATROSKA_ID_TRACKAUDIO:{
921 GstMatroskaTrackAudioContext *audiocontext;
923 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
925 if (!gst_matroska_track_init_audio_context (&context)) {
926 GST_WARNING_OBJECT (demux,
927 "TrackAudio element in non-audio track - ignoring track");
928 ret = GST_FLOW_ERROR;
932 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
935 audiocontext = (GstMatroskaTrackAudioContext *) context;
936 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
939 while (ret == GST_FLOW_OK &&
940 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
941 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
946 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
949 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
954 GST_WARNING_OBJECT (demux,
955 "Invalid TrackAudioSamplingFrequency %lf", num);
959 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
960 audiocontext->samplerate = num;
965 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
968 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
972 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
976 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
978 audiocontext->bitdepth = num;
983 case GST_MATROSKA_ID_AUDIOCHANNELS:{
986 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
990 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
994 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
996 audiocontext->channels = num;
1001 GST_WARNING_OBJECT (demux,
1002 "Unknown TrackAudio subelement 0x%x - ignoring", id);
1004 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
1005 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
1006 ret = gst_ebml_read_skip (ebml);
1011 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
1016 /* codec identifier */
1017 case GST_MATROSKA_ID_CODECID:{
1020 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
1023 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
1024 context->codec_id = text;
1028 /* codec private data */
1029 case GST_MATROSKA_ID_CODECPRIVATE:{
1034 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
1037 context->codec_priv = data;
1038 context->codec_priv_size = size;
1040 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1045 /* name of the codec */
1046 case GST_MATROSKA_ID_CODECNAME:{
1049 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1052 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1053 context->codec_name = text;
1057 /* name of this track */
1058 case GST_MATROSKA_ID_TRACKNAME:{
1061 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1064 context->name = text;
1065 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1069 /* language (matters for audio/subtitles, mostly) */
1070 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1073 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1077 context->language = text;
1080 if (strlen (context->language) >= 4 && context->language[3] == '-')
1081 context->language[3] = '\0';
1083 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1084 GST_STR_NULL (context->language));
1088 /* whether this is actually used */
1089 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1092 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1096 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1098 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1100 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1101 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1105 /* whether it's the default for this track type */
1106 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1109 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1113 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1115 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1117 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1118 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
1122 /* whether the track must be used during playback */
1123 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1126 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1130 context->flags |= GST_MATROSKA_TRACK_FORCED;
1132 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1134 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1135 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
1139 /* lacing (like MPEG, where blocks don't end/start on frame
1141 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1144 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1148 context->flags |= GST_MATROSKA_TRACK_LACING;
1150 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1152 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1153 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
1157 /* default length (in time) of one data block in this track */
1158 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1161 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1166 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1170 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1172 context->default_duration = num;
1176 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1177 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1182 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1185 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1189 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1193 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1194 context->timecodescale = num;
1199 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1202 /* we ignore these because they're nothing useful (i.e. crap)
1203 * or simply not implemented yet. */
1204 case GST_MATROSKA_ID_TRACKMINCACHE:
1205 case GST_MATROSKA_ID_TRACKMAXCACHE:
1206 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1207 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1208 case GST_MATROSKA_ID_TRACKOVERLAY:
1209 case GST_MATROSKA_ID_TRACKTRANSLATE:
1210 case GST_MATROSKA_ID_TRACKOFFSET:
1211 case GST_MATROSKA_ID_CODECSETTINGS:
1212 case GST_MATROSKA_ID_CODECINFOURL:
1213 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1214 case GST_MATROSKA_ID_CODECDECODEALL:
1215 ret = gst_ebml_read_skip (ebml);
1220 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1222 /* Decode codec private data if necessary */
1223 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1224 && context->codec_priv_size > 0) {
1225 if (!gst_matroska_decode_data (context->encodings,
1226 &context->codec_priv, &context->codec_priv_size,
1227 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1228 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1229 ret = GST_FLOW_ERROR;
1233 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1234 && ret != GST_FLOW_EOS)) {
1235 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1236 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1238 demux->common.num_streams--;
1239 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1240 g_assert (demux->common.src->len == demux->common.num_streams);
1242 gst_matroska_track_free (context);
1248 /* now create the GStreamer connectivity */
1249 switch (context->type) {
1250 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1251 GstMatroskaTrackVideoContext *videocontext =
1252 (GstMatroskaTrackVideoContext *) context;
1254 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1255 templ = gst_element_class_get_pad_template (klass, "video_%u");
1256 caps = gst_matroska_demux_video_caps (videocontext,
1257 context->codec_id, context->codec_priv,
1258 context->codec_priv_size, &codec, &riff_fourcc);
1261 list = gst_tag_list_new (GST_TAG_VIDEO_CODEC, codec, NULL);
1267 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1268 GstMatroskaTrackAudioContext *audiocontext =
1269 (GstMatroskaTrackAudioContext *) context;
1271 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1272 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1273 caps = gst_matroska_demux_audio_caps (audiocontext,
1274 context->codec_id, context->codec_priv, context->codec_priv_size,
1275 &codec, &riff_audio_fmt);
1278 list = gst_tag_list_new (GST_TAG_AUDIO_CODEC, codec, NULL);
1284 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1285 GstMatroskaTrackSubtitleContext *subtitlecontext =
1286 (GstMatroskaTrackSubtitleContext *) context;
1288 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1289 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1290 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1291 context->codec_id, context->codec_priv, context->codec_priv_size);
1295 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1296 case GST_MATROSKA_TRACK_TYPE_LOGO:
1297 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1298 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1300 /* we should already have quit by now */
1301 g_assert_not_reached ();
1304 if ((context->language == NULL || *context->language == '\0') &&
1305 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1306 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1307 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1308 context->language = g_strdup ("eng");
1311 if (context->language) {
1315 list = gst_tag_list_new_empty ();
1317 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1318 lang = gst_tag_get_language_code (context->language);
1319 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1320 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1324 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1325 "codec_id='%s'", context->codec_id);
1326 switch (context->type) {
1327 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1328 caps = gst_caps_new_empty_simple ("video/x-unknown");
1330 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1331 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1333 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1334 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1336 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1338 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1341 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1344 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1345 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1346 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1347 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1348 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1349 GST_FOURCC_ARGS (riff_fourcc));
1350 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1353 } else if (context->stream_headers != NULL) {
1354 gst_matroska_demux_add_stream_headers_to_caps (demux,
1355 context->stream_headers, caps);
1358 /* the pad in here */
1359 context->pad = gst_pad_new_from_template (templ, padname);
1360 context->caps = caps;
1362 gst_pad_set_event_function (context->pad,
1363 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1364 gst_pad_set_query_function (context->pad,
1365 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1367 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1370 context->pending_tags = list;
1372 gst_pad_set_element_private (context->pad, context);
1374 gst_pad_use_fixed_caps (context->pad);
1375 gst_pad_set_active (context->pad, TRUE);
1378 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1379 "%03" G_GUINT64_FORMAT, context->uid);
1381 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1384 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1385 demux->have_group_id = TRUE;
1387 demux->have_group_id = FALSE;
1388 gst_event_unref (stream_start);
1389 } else if (!demux->have_group_id) {
1390 demux->have_group_id = TRUE;
1391 demux->group_id = gst_util_group_id_next ();
1394 stream_start = gst_event_new_stream_start (stream_id);
1396 if (demux->have_group_id)
1397 gst_event_set_group_id (stream_start, demux->group_id);
1398 stream_flags = GST_STREAM_FLAG_NONE;
1399 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1400 stream_flags |= GST_STREAM_FLAG_SPARSE;
1401 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1402 stream_flags |= GST_STREAM_FLAG_SELECT;
1403 gst_event_set_stream_flags (stream_start, stream_flags);
1404 gst_pad_push_event (context->pad, stream_start);
1405 gst_pad_set_caps (context->pad, context->caps);
1407 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1416 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1419 gboolean res = FALSE;
1420 GstMatroskaTrackContext *context = NULL;
1423 context = gst_pad_get_element_private (pad);
1426 switch (GST_QUERY_TYPE (query)) {
1427 case GST_QUERY_POSITION:
1431 gst_query_parse_position (query, &format, NULL);
1434 if (format == GST_FORMAT_TIME) {
1435 GST_OBJECT_LOCK (demux);
1437 gst_query_set_position (query, GST_FORMAT_TIME,
1438 MAX (context->pos, demux->stream_start_time) -
1439 demux->stream_start_time);
1441 gst_query_set_position (query, GST_FORMAT_TIME,
1442 MAX (demux->common.segment.position, demux->stream_start_time) -
1443 demux->stream_start_time);
1444 GST_OBJECT_UNLOCK (demux);
1445 } else if (format == GST_FORMAT_DEFAULT && context
1446 && context->default_duration) {
1447 GST_OBJECT_LOCK (demux);
1448 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1449 context->pos / context->default_duration);
1450 GST_OBJECT_UNLOCK (demux);
1452 GST_DEBUG_OBJECT (demux,
1453 "only position query in TIME and DEFAULT format is supported");
1459 case GST_QUERY_DURATION:
1463 gst_query_parse_duration (query, &format, NULL);
1466 if (format == GST_FORMAT_TIME) {
1467 GST_OBJECT_LOCK (demux);
1468 gst_query_set_duration (query, GST_FORMAT_TIME,
1469 demux->common.segment.duration);
1470 GST_OBJECT_UNLOCK (demux);
1471 } else if (format == GST_FORMAT_DEFAULT && context
1472 && context->default_duration) {
1473 GST_OBJECT_LOCK (demux);
1474 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1475 demux->common.segment.duration / context->default_duration);
1476 GST_OBJECT_UNLOCK (demux);
1478 GST_DEBUG_OBJECT (demux,
1479 "only duration query in TIME and DEFAULT format is supported");
1485 case GST_QUERY_SEEKING:
1489 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1490 GST_OBJECT_LOCK (demux);
1491 if (fmt == GST_FORMAT_TIME) {
1494 if (demux->streaming) {
1495 /* assuming we'll be able to get an index ... */
1496 seekable = demux->seekable;
1501 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1502 0, demux->common.segment.duration);
1505 GST_OBJECT_UNLOCK (demux);
1508 case GST_QUERY_SEGMENT:
1513 format = demux->common.segment.format;
1516 gst_segment_to_stream_time (&demux->common.segment, format,
1517 demux->common.segment.start);
1518 if ((stop = demux->common.segment.stop) == -1)
1519 stop = demux->common.segment.duration;
1522 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1524 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1531 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1534 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1543 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1545 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1549 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1552 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1554 return gst_matroska_demux_query (demux, pad, query);
1557 /* returns FALSE if there are no pads to deliver event to,
1558 * otherwise TRUE (whatever the outcome of event sending),
1559 * takes ownership of the passed event! */
1561 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1563 gboolean is_segment;
1564 gboolean ret = FALSE;
1567 g_return_val_if_fail (event != NULL, FALSE);
1569 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1570 GST_EVENT_TYPE_NAME (event));
1572 is_segment = (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
1574 g_assert (demux->common.src->len == demux->common.num_streams);
1575 for (i = 0; i < demux->common.src->len; i++) {
1576 GstMatroskaTrackContext *stream;
1578 stream = g_ptr_array_index (demux->common.src, i);
1579 gst_event_ref (event);
1580 gst_pad_push_event (stream->pad, event);
1583 /* FIXME: send global tags before stream tags */
1584 if (G_UNLIKELY (is_segment && stream->pending_tags != NULL)) {
1585 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
1586 GST_PTR_FORMAT, stream->pending_tags,
1587 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
1588 gst_pad_push_event (stream->pad,
1589 gst_event_new_tag (stream->pending_tags));
1590 stream->pending_tags = NULL;
1594 if (G_UNLIKELY (is_segment && demux->common.global_tags != NULL)) {
1595 GstEvent *tag_event;
1596 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1597 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1598 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1599 demux->common.global_tags, demux->common.global_tags);
1601 tag_event = gst_event_new_tag (demux->common.global_tags);
1603 for (i = 0; i < demux->common.src->len; i++) {
1604 GstMatroskaTrackContext *stream;
1606 stream = g_ptr_array_index (demux->common.src, i);
1607 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1610 gst_event_unref (tag_event);
1611 demux->common.global_tags = NULL;
1614 gst_event_unref (event);
1619 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1621 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1624 g_return_val_if_fail (event != NULL, FALSE);
1626 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1627 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1629 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1630 GST_EVENT_TYPE_NAME (event));
1633 gst_event_unref (event);
1638 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1639 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1643 GST_OBJECT_LOCK (demux);
1646 /* seek (relative to matroska segment) */
1647 /* position might be invalid; will error when streaming resumes ... */
1648 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1649 demux->next_cluster_offset = 0;
1651 GST_DEBUG_OBJECT (demux,
1652 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1653 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1654 entry->block, GST_TIME_ARGS (entry->time));
1656 /* update the time */
1657 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1658 demux->common.segment.position = entry->time;
1659 demux->seek_block = entry->block;
1660 demux->seek_first = TRUE;
1661 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1664 for (i = 0; i < demux->common.src->len; i++) {
1665 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1668 stream->to_offset = G_MAXINT64;
1670 if (stream->from_offset != -1)
1671 stream->to_offset = stream->from_offset;
1673 stream->from_offset = -1;
1674 stream->from_time = GST_CLOCK_TIME_NONE;
1677 GST_OBJECT_UNLOCK (demux);
1683 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1693 /* searches for a cluster start from @pos,
1694 * return GST_FLOW_OK and cluster position in @pos if found */
1695 static GstFlowReturn
1696 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1698 gint64 newpos = *pos;
1700 GstFlowReturn ret = GST_FLOW_OK;
1701 const guint chunk = 64 * 1024;
1702 GstBuffer *buf = NULL;
1704 gpointer data = NULL;
1710 orig_offset = demux->common.offset;
1712 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1715 if (demux->clusters) {
1718 cpos = gst_util_array_binary_search (demux->clusters->data,
1719 demux->clusters->len, sizeof (gint64),
1720 (GCompareDataFunc) gst_matroska_cluster_compare,
1721 GST_SEARCH_MODE_AFTER, pos, NULL);
1724 GST_DEBUG_OBJECT (demux,
1725 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1726 demux->common.offset = *cpos;
1727 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1728 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1729 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1736 /* read in at newpos and scan for ebml cluster id */
1738 GstByteReader reader;
1742 gst_buffer_unmap (buf, &map);
1743 gst_buffer_unref (buf);
1746 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1747 if (ret != GST_FLOW_OK)
1749 GST_DEBUG_OBJECT (demux,
1750 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1751 gst_buffer_get_size (buf), newpos);
1752 gst_buffer_map (buf, &map, GST_MAP_READ);
1755 gst_byte_reader_init (&reader, data, size);
1757 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1758 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1759 if (cluster_pos >= 0) {
1760 newpos += cluster_pos;
1761 /* prepare resuming at next byte */
1762 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1763 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1766 GST_DEBUG_OBJECT (demux,
1767 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1768 /* extra checks whether we really sync'ed to a cluster:
1769 * - either it is the first and only cluster
1770 * - either there is a cluster after this one
1771 * - either cluster length is undefined
1773 /* ok if first cluster (there may not a subsequent one) */
1774 if (newpos == demux->first_cluster_offset) {
1775 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1778 demux->common.offset = newpos;
1779 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1780 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1781 if (ret != GST_FLOW_OK) {
1782 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1785 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1786 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1788 /* ok if undefined length or first cluster */
1789 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1790 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1794 demux->common.offset += length + needed;
1795 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1796 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1797 if (ret != GST_FLOW_OK)
1799 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1800 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1801 if (id == GST_MATROSKA_ID_CLUSTER)
1803 /* not ok, resume */
1806 /* partial cluster id may have been in tail of buffer */
1807 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1812 gst_buffer_unmap (buf, &map);
1813 gst_buffer_unref (buf);
1818 demux->common.offset = orig_offset;
1823 /* bisect and scan through file for cluster starting before @time,
1824 * returns fake index entry with corresponding info on cluster */
1825 static GstMatroskaIndex *
1826 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1828 GstMatroskaIndex *entry = NULL;
1829 GstMatroskaReadState current_state;
1830 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1831 gint64 opos, newpos, startpos = 0, current_offset;
1832 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1833 const guint chunk = 64 * 1024;
1839 /* (under)estimate new position, resync using cluster ebml id,
1840 * and scan forward to appropriate cluster
1841 * (and re-estimate if need to go backward) */
1843 prev_cluster_time = GST_CLOCK_TIME_NONE;
1845 /* store some current state */
1846 current_state = demux->common.state;
1847 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1849 current_cluster_offset = demux->cluster_offset;
1850 current_cluster_time = demux->cluster_time;
1851 current_offset = demux->common.offset;
1853 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1855 /* estimate using start and current position */
1856 GST_OBJECT_LOCK (demux);
1857 opos = demux->common.offset - demux->common.ebml_segment_start;
1858 otime = demux->common.segment.position;
1859 GST_OBJECT_UNLOCK (demux);
1862 time = MAX (time, demux->stream_start_time);
1864 /* avoid division by zero in first estimation below */
1865 if (otime <= demux->stream_start_time)
1869 GST_LOG_OBJECT (demux,
1870 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1871 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1872 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1873 GST_TIME_ARGS (otime - demux->stream_start_time),
1874 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1876 if (otime <= demux->stream_start_time) {
1880 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1881 time - demux->stream_start_time,
1882 otime - demux->stream_start_time) - chunk;
1886 /* favour undershoot */
1887 newpos = newpos * 90 / 100;
1888 newpos += demux->common.ebml_segment_start;
1890 GST_DEBUG_OBJECT (demux,
1891 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1892 GST_TIME_ARGS (time), newpos);
1894 /* and at least start scanning before previous scan start to avoid looping */
1895 startpos = startpos * 90 / 100;
1896 if (startpos && startpos < newpos)
1899 /* read in at newpos and scan for ebml cluster id */
1903 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1904 if (ret == GST_FLOW_EOS) {
1905 /* heuristic HACK */
1906 newpos = startpos * 80 / 100;
1907 GST_DEBUG_OBJECT (demux, "EOS; "
1908 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1909 GST_TIME_ARGS (time), newpos);
1912 } else if (ret != GST_FLOW_OK) {
1919 /* then start scanning and parsing for cluster time,
1920 * re-estimate if overshoot, otherwise next cluster and so on */
1921 demux->common.offset = newpos;
1922 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1924 guint64 cluster_size = 0;
1926 /* peek and parse some elements */
1927 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1928 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1929 if (ret != GST_FLOW_OK)
1931 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1932 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1934 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1935 if (ret != GST_FLOW_OK)
1938 if (id == GST_MATROSKA_ID_CLUSTER) {
1939 cluster_time = GST_CLOCK_TIME_NONE;
1940 if (length == G_MAXUINT64)
1943 cluster_size = length + needed;
1945 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1946 cluster_time == GST_CLOCK_TIME_NONE) {
1947 cluster_time = demux->cluster_time * demux->common.time_scale;
1948 cluster_offset = demux->cluster_offset;
1949 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1950 " with time %" GST_TIME_FORMAT, cluster_offset,
1951 GST_TIME_ARGS (cluster_time));
1952 if (cluster_time > time) {
1953 GST_DEBUG_OBJECT (demux, "overshot target");
1954 /* cluster overshoots */
1955 if (cluster_offset == demux->first_cluster_offset) {
1956 /* but no prev one */
1957 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1958 prev_cluster_time = cluster_time;
1959 prev_cluster_offset = cluster_offset;
1962 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1963 /* prev cluster did not overshoot, so prev cluster is target */
1966 /* re-estimate using this new position info */
1967 opos = cluster_offset;
1968 otime = cluster_time;
1972 /* cluster undershoots, goto next one */
1973 prev_cluster_time = cluster_time;
1974 prev_cluster_offset = cluster_offset;
1975 /* skip cluster if length is defined,
1976 * otherwise will be skippingly parsed into */
1978 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1979 demux->common.offset = cluster_offset + cluster_size;
1980 demux->cluster_time = GST_CLOCK_TIME_NONE;
1982 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1989 if (ret == GST_FLOW_EOS) {
1990 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1996 entry = g_new0 (GstMatroskaIndex, 1);
1997 entry->time = prev_cluster_time;
1998 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1999 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
2000 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
2004 /* restore some state */
2005 demux->cluster_offset = current_cluster_offset;
2006 demux->cluster_time = current_cluster_time;
2007 demux->common.offset = current_offset;
2008 demux->common.state = current_state;
2014 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
2015 GstPad * pad, GstEvent * event)
2017 GstMatroskaIndex *entry = NULL;
2018 GstMatroskaIndex scan_entry;
2020 GstSeekType cur_type, stop_type;
2022 gboolean flush, keyunit, before, after, snap_next;
2025 GstMatroskaTrackContext *track = NULL;
2026 GstSegment seeksegment = { 0, };
2027 gboolean update = TRUE;
2028 gboolean pad_locked = FALSE;
2032 track = gst_pad_get_element_private (pad);
2034 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2036 seqnum = gst_event_get_seqnum (event);
2038 /* we can only seek on time */
2039 if (format != GST_FORMAT_TIME) {
2040 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2044 /* copy segment, we need this because we still need the old
2045 * segment when we close the current segment. */
2046 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
2048 /* pull mode without index means that the actual duration is not known,
2049 * we might be playing a file that's still being recorded
2050 * so, invalidate our current duration, which is only a moving target,
2051 * and should not be used to clamp anything */
2052 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
2053 seeksegment.duration = GST_CLOCK_TIME_NONE;
2057 GST_DEBUG_OBJECT (demux, "configuring seek");
2058 gst_segment_do_seek (&seeksegment, rate, format, flags,
2059 cur_type, cur, stop_type, stop, &update);
2060 /* compensate for clip start time, but only for SET seeks,
2061 * otherwise it is already part of the segments */
2062 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2063 if (cur_type == GST_SEEK_TYPE_SET) {
2065 seeksegment.position += demux->stream_start_time;
2066 seeksegment.start += demux->stream_start_time;
2068 if (stop_type == GST_SEEK_TYPE_SET
2069 && GST_CLOCK_TIME_IS_VALID (seeksegment.stop)) {
2071 seeksegment.position += demux->stream_start_time;
2072 seeksegment.stop += demux->stream_start_time;
2077 /* restore segment duration (if any effect),
2078 * would be determined again when parsing, but anyway ... */
2079 seeksegment.duration = demux->common.segment.duration;
2081 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2082 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2083 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
2084 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
2086 /* always do full update if flushing,
2087 * otherwise problems might arise downstream with missing keyframes etc */
2088 update = update || flush;
2090 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2092 /* check sanity before we start flushing and all that */
2093 snap_next = after && !before;
2094 if (seeksegment.rate < 0)
2095 snap_next = !snap_next;
2096 GST_OBJECT_LOCK (demux);
2097 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2098 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2099 seeksegment.position, &demux->seek_index, &demux->seek_entry,
2100 snap_next)) == NULL) {
2101 /* pull mode without index can scan later on */
2102 if (demux->streaming) {
2103 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2104 GST_OBJECT_UNLOCK (demux);
2106 } else if (rate < 0.0) {
2107 /* FIXME: We should build an index during playback or when scanning
2108 * that can be used here. The reverse playback code requires seek_index
2109 * and seek_entry to be set!
2111 GST_DEBUG_OBJECT (demux,
2112 "No matching seek entry in index, needed for reverse playback");
2113 GST_OBJECT_UNLOCK (demux);
2117 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2118 GST_OBJECT_UNLOCK (demux);
2121 /* only have to update some segment,
2122 * but also still have to honour flush and so on */
2123 GST_DEBUG_OBJECT (demux, "... no update");
2124 /* bad goto, bad ... */
2128 if (demux->streaming)
2133 GstEvent *flush_event = gst_event_new_flush_start ();
2134 gst_event_set_seqnum (flush_event, seqnum);
2135 GST_DEBUG_OBJECT (demux, "Starting flush");
2136 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2137 gst_matroska_demux_send_event (demux, flush_event);
2139 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2140 gst_pad_pause_task (demux->common.sinkpad);
2144 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2149 /* now grab the stream lock so that streaming cannot continue, for
2150 * non flushing seeks when the element is in PAUSED this could block
2152 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2153 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2156 /* pull mode without index can do some scanning */
2157 if (!demux->streaming && !entry) {
2158 GstEvent *flush_event;
2160 /* need to stop flushing upstream as we need it next */
2162 flush_event = gst_event_new_flush_stop (TRUE);
2163 gst_event_set_seqnum (flush_event, seqnum);
2164 gst_pad_push_event (demux->common.sinkpad, flush_event);
2166 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2167 /* keep local copy */
2169 scan_entry = *entry;
2171 entry = &scan_entry;
2173 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2175 flush_event = gst_event_new_flush_stop (TRUE);
2176 gst_event_set_seqnum (flush_event, seqnum);
2177 gst_matroska_demux_send_event (demux, flush_event);
2185 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2186 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2187 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2188 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2189 seeksegment.position = seeksegment.start;
2190 seeksegment.time = seeksegment.start - demux->stream_start_time;
2193 if (demux->streaming) {
2194 GST_OBJECT_LOCK (demux);
2195 /* track real position we should start at */
2196 GST_DEBUG_OBJECT (demux, "storing segment start");
2197 demux->requested_seek_time = seeksegment.position;
2198 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2199 GST_OBJECT_UNLOCK (demux);
2200 /* need to seek to cluster start to pick up cluster time */
2201 /* upstream takes care of flushing and all that
2202 * ... and newsegment event handling takes care of the rest */
2203 return perform_seek_to_offset (demux, rate,
2204 entry->pos + demux->common.ebml_segment_start, seqnum);
2209 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2210 gst_event_set_seqnum (flush_event, seqnum);
2211 GST_DEBUG_OBJECT (demux, "Stopping flush");
2212 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2213 gst_matroska_demux_send_event (demux, flush_event);
2216 GST_OBJECT_LOCK (demux);
2217 /* now update the real segment info */
2218 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2219 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2220 GST_OBJECT_UNLOCK (demux);
2222 /* update some (segment) state */
2223 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2226 /* notify start of new segment */
2227 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2230 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2231 GST_FORMAT_TIME, demux->common.segment.start);
2232 gst_message_set_seqnum (msg, seqnum);
2233 gst_element_post_message (GST_ELEMENT (demux), msg);
2236 GST_OBJECT_LOCK (demux);
2237 if (demux->new_segment)
2238 gst_event_unref (demux->new_segment);
2240 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2241 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2242 gst_event_set_seqnum (demux->new_segment, seqnum);
2243 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2244 demux->to_time = demux->common.segment.position;
2246 demux->to_time = GST_CLOCK_TIME_NONE;
2247 GST_OBJECT_UNLOCK (demux);
2249 /* restart our task since it might have been stopped when we did the
2251 gst_pad_start_task (demux->common.sinkpad,
2252 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2254 /* streaming can continue now */
2256 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2264 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2266 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2272 * Handle whether we can perform the seek event or if we have to let the chain
2273 * function handle seeks to build the seek indexes first.
2276 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2280 GstSeekType cur_type, stop_type;
2285 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2290 /* we can only seek on time */
2291 if (format != GST_FORMAT_TIME) {
2292 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2296 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2297 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2301 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2302 GST_DEBUG_OBJECT (demux,
2303 "Non-flushing seek not supported in streaming mode");
2307 if (flags & GST_SEEK_FLAG_SEGMENT) {
2308 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2312 /* check for having parsed index already */
2313 if (!demux->common.index_parsed) {
2314 gboolean building_index;
2317 if (!demux->index_offset) {
2318 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2322 GST_OBJECT_LOCK (demux);
2323 /* handle the seek event in the chain function */
2324 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2325 /* no more seek can be issued until state reset to _DATA */
2327 /* copy the event */
2328 if (demux->seek_event)
2329 gst_event_unref (demux->seek_event);
2330 demux->seek_event = gst_event_ref (event);
2332 /* set the building_index flag so that only one thread can setup the
2333 * structures for index seeking. */
2334 building_index = demux->building_index;
2335 if (!building_index) {
2336 demux->building_index = TRUE;
2337 offset = demux->index_offset;
2339 GST_OBJECT_UNLOCK (demux);
2341 if (!building_index) {
2342 /* seek to the first subindex or legacy index */
2343 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2344 return perform_seek_to_offset (demux, rate, offset,
2345 gst_event_get_seqnum (event));
2348 /* well, we are handling it already */
2352 /* delegate to tweaked regular seek */
2353 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2357 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2360 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2361 gboolean res = TRUE;
2363 switch (GST_EVENT_TYPE (event)) {
2364 case GST_EVENT_SEEK:
2365 /* no seeking until we are (safely) ready */
2366 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2367 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2370 if (!demux->streaming)
2371 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2373 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2374 gst_event_unref (event);
2379 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2380 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2381 GstMatroskaTrackVideoContext *videocontext =
2382 (GstMatroskaTrackVideoContext *) context;
2384 GstClockTimeDiff diff;
2385 GstClockTime timestamp;
2387 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2389 GST_OBJECT_LOCK (demux);
2390 videocontext->earliest_time = timestamp + diff;
2391 GST_OBJECT_UNLOCK (demux);
2394 gst_event_unref (event);
2398 case GST_EVENT_TOC_SELECT:
2401 GstTocEntry *entry = NULL;
2402 GstEvent *seek_event;
2405 if (!demux->common.toc) {
2406 GST_DEBUG_OBJECT (demux, "no TOC to select");
2409 gst_event_parse_toc_select (event, &uid);
2411 GST_OBJECT_LOCK (demux);
2412 entry = gst_toc_find_entry (demux->common.toc, uid);
2413 if (entry == NULL) {
2414 GST_OBJECT_UNLOCK (demux);
2415 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2418 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2419 GST_OBJECT_UNLOCK (demux);
2420 seek_event = gst_event_new_seek (1.0,
2422 GST_SEEK_FLAG_FLUSH,
2423 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2424 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2425 gst_event_unref (seek_event);
2429 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2433 gst_event_unref (event);
2437 /* events we don't need to handle */
2438 case GST_EVENT_NAVIGATION:
2439 gst_event_unref (event);
2443 case GST_EVENT_LATENCY:
2445 res = gst_pad_push_event (demux->common.sinkpad, event);
2452 static GstFlowReturn
2453 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2455 GstFlowReturn ret = GST_FLOW_EOS;
2456 gboolean done = TRUE;
2459 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2460 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2463 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2465 if (!demux->seek_entry) {
2466 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2470 for (i = 0; i < demux->common.src->len; i++) {
2471 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2473 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2474 ", stream %d at %" GST_TIME_FORMAT,
2475 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2476 GST_TIME_ARGS (stream->from_time));
2477 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2478 if (stream->from_time > demux->common.segment.start) {
2479 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2483 /* nothing pushed for this stream;
2484 * likely seek entry did not start at keyframe, so all was skipped.
2485 * So we need an earlier entry */
2491 GstMatroskaIndex *entry;
2493 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2494 --demux->seek_entry);
2495 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2505 static GstFlowReturn
2506 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2508 GstFlowReturn ret = GST_FLOW_OK;
2511 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2513 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2514 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2518 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2519 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2523 /* one track within the "all-tracks" header */
2524 case GST_MATROSKA_ID_TRACKENTRY:
2525 ret = gst_matroska_demux_add_stream (demux, ebml);
2529 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2534 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2536 demux->tracks_parsed = TRUE;
2542 * Read signed/unsigned "EBML" numbers.
2543 * Return: number of bytes processed.
2547 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2549 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2557 while (read <= 8 && !(total & len_mask)) {
2564 if ((total &= (len_mask - 1)) == len_mask - 1)
2569 if (data[n] == 0xff)
2571 total = (total << 8) | data[n];
2575 if (read == num_ffs && total != 0)
2584 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2589 /* read as unsigned number first */
2590 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2594 if (unum == G_MAXUINT64)
2597 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2603 * Mostly used for subtitles. We add void filler data for each
2604 * lagging stream to make sure we don't deadlock.
2608 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2612 GST_OBJECT_LOCK (demux);
2614 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2615 GST_TIME_ARGS (demux->common.segment.position));
2617 g_assert (demux->common.num_streams == demux->common.src->len);
2618 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2619 GstMatroskaTrackContext *context;
2621 context = g_ptr_array_index (demux->common.src, stream_nr);
2623 GST_LOG_OBJECT (demux,
2624 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2625 GST_TIME_ARGS (context->pos));
2627 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2628 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2632 /* does it lag? 0.5 seconds is a random threshold...
2633 * lag need only be considered if we have advanced into requested segment */
2634 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2635 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2636 demux->common.segment.position > demux->common.segment.start &&
2637 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2640 guint64 start = context->pos;
2641 guint64 stop = demux->common.segment.position - (GST_SECOND / 2);
2643 GST_DEBUG_OBJECT (demux,
2644 "Synchronizing stream %d with other by advancing time from %"
2645 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2646 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2648 context->pos = stop;
2650 event = gst_event_new_gap (start, stop - start);
2651 GST_OBJECT_UNLOCK (demux);
2652 gst_pad_push_event (context->pad, event);
2653 GST_OBJECT_LOCK (demux);
2657 GST_OBJECT_UNLOCK (demux);
2660 static GstFlowReturn
2661 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2662 GstMatroskaTrackContext * stream)
2664 GstFlowReturn ret = GST_FLOW_OK;
2667 num = gst_buffer_list_length (stream->stream_headers);
2668 for (i = 0; i < num; ++i) {
2671 buf = gst_buffer_list_get (stream->stream_headers, i);
2672 buf = gst_buffer_copy (buf);
2674 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2676 if (stream->set_discont) {
2677 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2678 stream->set_discont = FALSE;
2680 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2683 /* push out all headers in one go and use last flow return */
2684 ret = gst_pad_push (stream->pad, buf);
2687 /* don't need these any longer */
2688 gst_buffer_list_unref (stream->stream_headers);
2689 stream->stream_headers = NULL;
2692 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
2698 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2699 GstMatroskaTrackContext * stream)
2703 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2705 if (!stream->codec_priv)
2708 /* ideally, VobSub private data should be parsed and stored more convenient
2709 * elsewhere, but for now, only interested in a small part */
2711 /* make sure we have terminating 0 */
2712 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2714 /* just locate and parse palette part */
2715 start = strstr (buf, "palette:");
2720 guint8 r, g, b, y, u, v;
2723 while (g_ascii_isspace (*start))
2725 for (i = 0; i < 16; i++) {
2726 if (sscanf (start, "%06x", &col) != 1)
2729 while ((*start == ',') || g_ascii_isspace (*start))
2731 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2732 r = (col >> 16) & 0xff;
2733 g = (col >> 8) & 0xff;
2735 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2737 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2738 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2739 clut[i] = (y << 16) | (u << 8) | v;
2742 /* got them all without problems; build and send event */
2746 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2747 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2748 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2749 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2750 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2751 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2752 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2753 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2754 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2755 G_TYPE_INT, clut[15], NULL);
2757 gst_pad_push_event (stream->pad,
2758 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2764 static GstFlowReturn
2765 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2766 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2769 guint seq_header_len;
2770 guint32 header, tmp;
2772 if (stream->codec_state) {
2773 seq_header = stream->codec_state;
2774 seq_header_len = stream->codec_state_size;
2775 } else if (stream->codec_priv) {
2776 seq_header = stream->codec_priv;
2777 seq_header_len = stream->codec_priv_size;
2782 /* Sequence header only needed for keyframes */
2783 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2786 if (gst_buffer_get_size (*buf) < 4)
2789 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2790 header = GUINT32_FROM_BE (tmp);
2792 /* Sequence start code, if not found prepend */
2793 if (header != 0x000001b3) {
2796 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2798 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2801 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2802 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2803 gst_buffer_get_size (*buf));
2805 gst_buffer_unref (*buf);
2812 static GstFlowReturn
2813 gst_matroska_demux_add_wvpk_header (GstElement * element,
2814 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2816 GstMatroskaTrackAudioContext *audiocontext =
2817 (GstMatroskaTrackAudioContext *) stream;
2818 GstBuffer *newbuf = NULL;
2819 GstMapInfo map, outmap;
2820 guint8 *buf_data, *data;
2828 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2831 wvh.total_samples = -1;
2832 wvh.block_index = audiocontext->wvpk_block_index;
2834 if (audiocontext->channels <= 2) {
2835 guint32 block_samples, tmp;
2836 gsize size = gst_buffer_get_size (*buf);
2838 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2839 block_samples = GUINT32_FROM_LE (tmp);
2840 /* we need to reconstruct the header of the wavpack block */
2842 /* -20 because ck_size is the size of the wavpack block -8
2843 * and lace_size is the size of the wavpack block + 12
2844 * (the three guint32 of the header that already are in the buffer) */
2845 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2847 /* block_samples, flags and crc are already in the buffer */
2848 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2850 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2856 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2857 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2858 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2859 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2860 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2861 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2863 /* Append data from buf: */
2864 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2865 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2867 gst_buffer_unref (*buf);
2869 audiocontext->wvpk_block_index += block_samples;
2871 guint8 *outdata = NULL;
2873 gsize buf_size, size, out_size = 0;
2874 guint32 block_samples, flags, crc, blocksize;
2876 gst_buffer_map (*buf, &map, GST_MAP_READ);
2877 buf_data = map.data;
2878 buf_size = map.size;
2881 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2882 gst_buffer_unmap (*buf, &map);
2883 return GST_FLOW_ERROR;
2889 block_samples = GST_READ_UINT32_LE (data);
2894 flags = GST_READ_UINT32_LE (data);
2897 crc = GST_READ_UINT32_LE (data);
2900 blocksize = GST_READ_UINT32_LE (data);
2904 if (blocksize == 0 || size < blocksize)
2907 g_assert ((newbuf == NULL) == (outdata == NULL));
2909 if (newbuf == NULL) {
2910 out_size = sizeof (Wavpack4Header) + blocksize;
2911 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2913 gst_buffer_copy_into (newbuf, *buf,
2914 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2917 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2918 outdata = outmap.data;
2920 gst_buffer_unmap (newbuf, &outmap);
2921 out_size += sizeof (Wavpack4Header) + blocksize;
2922 gst_buffer_set_size (newbuf, out_size);
2923 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2924 outdata = outmap.data;
2927 outdata[outpos] = 'w';
2928 outdata[outpos + 1] = 'v';
2929 outdata[outpos + 2] = 'p';
2930 outdata[outpos + 3] = 'k';
2933 GST_WRITE_UINT32_LE (outdata + outpos,
2934 blocksize + sizeof (Wavpack4Header) - 8);
2935 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2936 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2937 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2938 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2939 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2940 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2941 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2942 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2945 g_memmove (outdata + outpos, data, blocksize);
2946 outpos += blocksize;
2950 gst_buffer_unmap (*buf, &map);
2951 gst_buffer_unref (*buf);
2954 gst_buffer_unmap (newbuf, &outmap);
2957 audiocontext->wvpk_block_index += block_samples;
2963 /* @text must be null-terminated */
2965 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2970 g_return_val_if_fail (text != NULL, FALSE);
2972 /* yes, this might all lead to false positives ... */
2973 tag = (gchar *) text;
2974 while ((tag = strchr (tag, '<'))) {
2976 if (*tag != '\0' && *(tag + 1) == '>') {
2977 /* some common convenience ones */
2978 /* maybe any character will do here ? */
2991 if (strstr (text, "<span"))
2997 static GstFlowReturn
2998 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2999 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3001 GstMatroskaTrackSubtitleContext *sub_stream;
3002 const gchar *encoding;
3007 gboolean needs_unmap = TRUE;
3009 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3011 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
3014 /* Need \0-terminator at the end */
3015 if (map.data[map.size - 1] != '\0') {
3016 newbuf = gst_buffer_new_and_alloc (map.size + 1);
3018 /* Copy old buffer and add a 0 at the end */
3019 gst_buffer_fill (newbuf, 0, map.data, map.size);
3020 gst_buffer_memset (newbuf, map.size, 0, 1);
3021 gst_buffer_unmap (*buf, &map);
3023 gst_buffer_copy_into (newbuf, *buf,
3024 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3025 GST_BUFFER_COPY_META, 0, -1);
3026 gst_buffer_unref (*buf);
3028 gst_buffer_map (*buf, &map, GST_MAP_READ);
3031 if (!sub_stream->invalid_utf8) {
3032 if (g_utf8_validate ((gchar *) map.data, map.size - 1, NULL)) {
3035 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
3036 " is not valid UTF-8, this is broken according to the matroska"
3037 " specification", stream->num);
3038 sub_stream->invalid_utf8 = TRUE;
3041 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3042 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3043 if (encoding == NULL || *encoding == '\0') {
3044 /* if local encoding is UTF-8 and no encoding specified
3045 * via the environment variable, assume ISO-8859-15 */
3046 if (g_get_charset (&encoding)) {
3047 encoding = "ISO-8859-15";
3052 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3053 (char *) "*", NULL, NULL, &err);
3056 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3057 encoding, err->message);
3061 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3062 encoding = "ISO-8859-15";
3064 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3065 encoding, (char *) "*", NULL, NULL, NULL);
3068 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3069 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3072 utf8 = g_strdup ("invalid subtitle");
3074 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3075 gst_buffer_unmap (*buf, &map);
3076 gst_buffer_copy_into (newbuf, *buf,
3077 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3079 gst_buffer_unref (*buf);
3082 gst_buffer_map (*buf, &map, GST_MAP_READ);
3086 if (sub_stream->check_markup) {
3087 /* caps claim markup text, so we need to escape text,
3088 * except if text is already markup and then needs no further escaping */
3089 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3090 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3092 if (!sub_stream->seen_markup_tag) {
3093 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3095 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3096 gst_buffer_unmap (*buf, &map);
3097 gst_buffer_copy_into (newbuf, *buf,
3098 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3099 GST_BUFFER_COPY_META, 0, -1);
3100 gst_buffer_unref (*buf);
3103 needs_unmap = FALSE;
3108 gst_buffer_unmap (*buf, &map);
3113 static GstFlowReturn
3114 gst_matroska_demux_check_aac (GstElement * element,
3115 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3120 gst_buffer_extract (*buf, 0, data, 2);
3121 size = gst_buffer_get_size (*buf);
3123 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3126 /* tss, ADTS data, remove codec_data
3127 * still assume it is at least parsed */
3128 stream->caps = gst_caps_make_writable (stream->caps);
3129 s = gst_caps_get_structure (stream->caps, 0);
3131 gst_structure_remove_field (s, "codec_data");
3132 gst_pad_set_caps (stream->pad, stream->caps);
3133 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3134 "new caps: %" GST_PTR_FORMAT, stream->caps);
3137 /* disable subsequent checking */
3138 stream->postprocess_frame = NULL;
3144 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3145 GstBuffer * buffer, gsize alignment)
3149 gst_buffer_map (buffer, &map, GST_MAP_READ);
3151 if (map.size < sizeof (guintptr)) {
3152 gst_buffer_unmap (buffer, &map);
3156 if (((guintptr) map.data) & (alignment - 1)) {
3157 GstBuffer *new_buffer;
3158 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3160 new_buffer = gst_buffer_new_allocate (NULL,
3161 gst_buffer_get_size (buffer), ¶ms);
3163 /* Copy data "by hand", so ensure alignment is kept: */
3164 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3166 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3167 GST_DEBUG_OBJECT (demux,
3168 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3171 gst_buffer_unmap (buffer, &map);
3172 gst_buffer_unref (buffer);
3177 gst_buffer_unmap (buffer, &map);
3181 static GstFlowReturn
3182 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3183 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3184 gboolean is_simpleblock)
3186 GstMatroskaTrackContext *stream = NULL;
3187 GstFlowReturn ret = GST_FLOW_OK;
3188 gboolean readblock = FALSE;
3190 guint64 block_duration = -1;
3191 GstBuffer *buf = NULL;
3193 gint stream_num = -1, n, laces = 0;
3195 gint *lace_size = NULL;
3198 gint64 referenceblock = 0;
3201 offset = gst_ebml_read_get_offset (ebml);
3203 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3204 if (!is_simpleblock) {
3205 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3209 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3213 /* one block inside the group. Note, block parsing is one
3214 * of the harder things, so this code is a bit complicated.
3215 * See http://www.matroska.org/ for documentation. */
3216 case GST_MATROSKA_ID_SIMPLEBLOCK:
3217 case GST_MATROSKA_ID_BLOCK:
3223 gst_buffer_unmap (buf, &map);
3224 gst_buffer_unref (buf);
3227 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3230 gst_buffer_map (buf, &map, GST_MAP_READ);
3234 /* first byte(s): blocknum */
3235 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3240 /* fetch stream from num */
3241 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3243 if (G_UNLIKELY (size < 3)) {
3244 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3245 /* non-fatal, try next block(group) */
3248 } else if (G_UNLIKELY (stream_num < 0 ||
3249 stream_num >= demux->common.num_streams)) {
3250 /* let's not give up on a stray invalid track number */
3251 GST_WARNING_OBJECT (demux,
3252 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3253 "; ignoring block", stream_num, num);
3257 stream = g_ptr_array_index (demux->common.src, stream_num);
3259 /* time (relative to cluster time) */
3260 time = ((gint16) GST_READ_UINT16_BE (data));
3263 flags = GST_READ_UINT8 (data);
3267 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3270 switch ((flags & 0x06) >> 1) {
3271 case 0x0: /* no lacing */
3273 lace_size = g_new (gint, 1);
3274 lace_size[0] = size;
3277 case 0x1: /* xiph lacing */
3278 case 0x2: /* fixed-size lacing */
3279 case 0x3: /* EBML lacing */
3281 goto invalid_lacing;
3282 laces = GST_READ_UINT8 (data) + 1;
3285 lace_size = g_new0 (gint, laces);
3287 switch ((flags & 0x06) >> 1) {
3288 case 0x1: /* xiph lacing */ {
3289 guint temp, total = 0;
3291 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3294 goto invalid_lacing;
3295 temp = GST_READ_UINT8 (data);
3296 lace_size[n] += temp;
3302 total += lace_size[n];
3304 lace_size[n] = size - total;
3308 case 0x2: /* fixed-size lacing */
3309 for (n = 0; n < laces; n++)
3310 lace_size[n] = size / laces;
3313 case 0x3: /* EBML lacing */ {
3316 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3320 total = lace_size[0] = num;
3321 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3325 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3329 lace_size[n] = lace_size[n - 1] + snum;
3330 total += lace_size[n];
3333 lace_size[n] = size - total;
3340 if (ret != GST_FLOW_OK)
3347 case GST_MATROSKA_ID_BLOCKDURATION:{
3348 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3349 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3354 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3355 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3356 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3361 case GST_MATROSKA_ID_CODECSTATE:{
3363 guint64 data_len = 0;
3366 gst_ebml_read_binary (ebml, &id, &data,
3367 &data_len)) != GST_FLOW_OK)
3370 if (G_UNLIKELY (stream == NULL)) {
3371 GST_WARNING_OBJECT (demux,
3372 "Unexpected CodecState subelement - ignoring");
3376 g_free (stream->codec_state);
3377 stream->codec_state = data;
3378 stream->codec_state_size = data_len;
3380 /* Decode if necessary */
3381 if (stream->encodings && stream->encodings->len > 0
3382 && stream->codec_state && stream->codec_state_size > 0) {
3383 if (!gst_matroska_decode_data (stream->encodings,
3384 &stream->codec_state, &stream->codec_state_size,
3385 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3386 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3390 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3391 stream->codec_state_size);
3396 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3400 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3401 case GST_MATROSKA_ID_BLOCKADDITIONS:
3402 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3403 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3404 case GST_MATROSKA_ID_SLICES:
3405 GST_DEBUG_OBJECT (demux,
3406 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3407 ret = gst_ebml_read_skip (ebml);
3415 /* reading a number or so could have failed */
3416 if (ret != GST_FLOW_OK)
3419 if (ret == GST_FLOW_OK && readblock) {
3420 gboolean invisible_frame = FALSE;
3421 gboolean delta_unit = FALSE;
3422 guint64 duration = 0;
3423 gint64 lace_time = 0;
3425 stream = g_ptr_array_index (demux->common.src, stream_num);
3427 if (cluster_time != GST_CLOCK_TIME_NONE) {
3428 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3429 * Drop unless the lace contains timestamp 0? */
3430 if (time < 0 && (-time) > cluster_time) {
3433 if (stream->timecodescale == 1.0)
3434 lace_time = (cluster_time + time) * demux->common.time_scale;
3437 gst_util_guint64_to_gdouble ((cluster_time + time) *
3438 demux->common.time_scale) * stream->timecodescale;
3441 lace_time = GST_CLOCK_TIME_NONE;
3444 /* need to refresh segment info ASAP */
3445 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3446 GstSegment *segment = &demux->common.segment;
3448 GstEvent *segment_event;
3450 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3451 demux->stream_start_time = lace_time;
3452 GST_DEBUG_OBJECT (demux,
3453 "Setting stream start time to %" GST_TIME_FORMAT,
3454 GST_TIME_ARGS (lace_time));
3456 clace_time = MAX (lace_time, demux->stream_start_time);
3457 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3458 demux->common.segment.position != 0) {
3459 GST_DEBUG_OBJECT (demux,
3460 "using stored seek position %" GST_TIME_FORMAT,
3461 GST_TIME_ARGS (demux->common.segment.position));
3462 clace_time = demux->common.segment.position + demux->stream_start_time;
3463 segment->position = GST_CLOCK_TIME_NONE;
3465 segment->start = clace_time;
3466 segment->stop = GST_CLOCK_TIME_NONE;
3467 segment->time = segment->start - demux->stream_start_time;
3468 segment->position = segment->start - demux->stream_start_time;
3469 GST_DEBUG_OBJECT (demux,
3470 "generated segment starting at %" GST_TIME_FORMAT ": %"
3471 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3472 /* now convey our segment notion downstream */
3473 segment_event = gst_event_new_segment (segment);
3474 if (demux->segment_seqnum)
3475 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3476 gst_matroska_demux_send_event (demux, segment_event);
3477 demux->need_segment = FALSE;
3478 demux->segment_seqnum = 0;
3481 if (stream->send_stream_headers) {
3482 if (stream->stream_headers != NULL) {
3483 ret = gst_matroska_demux_push_stream_headers (demux, stream);
3485 /* FIXME: perhaps we can just disable and skip this stream then */
3486 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
3487 ("Failed to extract stream headers from codec private data"));
3489 stream->send_stream_headers = FALSE;
3492 if (stream->send_dvd_event) {
3493 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
3494 /* FIXME: should we send this event again after (flushing) seek ? */
3495 stream->send_dvd_event = FALSE;
3498 if (block_duration != -1) {
3499 if (stream->timecodescale == 1.0)
3500 duration = gst_util_uint64_scale (block_duration,
3501 demux->common.time_scale, 1);
3504 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3505 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3506 1)) * stream->timecodescale);
3507 } else if (stream->default_duration) {
3508 duration = stream->default_duration * laces;
3510 /* else duration is diff between timecode of this and next block */
3512 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3513 a ReferenceBlock implies that this is not a keyframe. In either
3514 case, it only makes sense for video streams. */
3515 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3516 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3518 invisible_frame = ((flags & 0x08)) &&
3519 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3520 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3524 if (delta_unit && stream->set_discont) {
3525 /* When doing seeks or such, we need to restart on key frames or
3526 * decoders might choke. */
3527 GST_DEBUG_OBJECT (demux, "skipping delta unit");
3531 for (n = 0; n < laces; n++) {
3534 if (G_UNLIKELY (lace_size[n] > size)) {
3535 GST_WARNING_OBJECT (demux, "Invalid lace size");
3539 /* QoS for video track with an index. the assumption is that
3540 index entries point to keyframes, but if that is not true we
3541 will instad skip until the next keyframe. */
3542 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3543 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3544 stream->index_table && demux->common.segment.rate > 0.0) {
3545 GstMatroskaTrackVideoContext *videocontext =
3546 (GstMatroskaTrackVideoContext *) stream;
3547 GstClockTime earliest_time;
3548 GstClockTime earliest_stream_time;
3550 GST_OBJECT_LOCK (demux);
3551 earliest_time = videocontext->earliest_time;
3552 GST_OBJECT_UNLOCK (demux);
3553 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3554 GST_FORMAT_TIME, earliest_time);
3556 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3557 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3558 lace_time <= earliest_stream_time) {
3559 /* find index entry (keyframe) <= earliest_stream_time */
3560 GstMatroskaIndex *entry =
3561 gst_util_array_binary_search (stream->index_table->data,
3562 stream->index_table->len, sizeof (GstMatroskaIndex),
3563 (GCompareDataFunc) gst_matroska_index_seek_find,
3564 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3566 /* if that entry (keyframe) is after the current the current
3567 buffer, we can skip pushing (and thus decoding) all
3568 buffers until that keyframe. */
3569 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3570 entry->time > lace_time) {
3571 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3572 stream->set_discont = TRUE;
3578 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3579 gst_buffer_get_size (buf) - size, lace_size[n]);
3580 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3583 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3585 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3587 if (invisible_frame)
3588 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3590 if (stream->encodings != NULL && stream->encodings->len > 0)
3591 sub = gst_matroska_decode_buffer (stream, sub);
3594 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3598 GST_BUFFER_TIMESTAMP (sub) = lace_time;
3600 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3601 GstClockTime last_stop_end;
3603 /* Check if this stream is after segment stop */
3604 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3605 lace_time >= demux->common.segment.stop) {
3606 GST_DEBUG_OBJECT (demux,
3607 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3608 GST_TIME_ARGS (demux->common.segment.stop));
3609 gst_buffer_unref (sub);
3612 if (offset >= stream->to_offset
3613 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3614 && lace_time > demux->to_time)) {
3615 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3617 gst_buffer_unref (sub);
3621 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3622 * that landed us with timestamps not quite intended */
3623 GST_OBJECT_LOCK (demux);
3624 if (demux->max_gap_time &&
3625 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3626 demux->common.segment.rate > 0.0) {
3627 GstClockTimeDiff diff;
3629 /* only send segments with increasing start times,
3630 * otherwise if these go back and forth downstream (sinks) increase
3631 * accumulated time and running_time */
3632 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3633 if (diff > 0 && diff > demux->max_gap_time
3634 && lace_time > demux->common.segment.start
3635 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3636 || lace_time < demux->common.segment.stop)) {
3638 GstEvent *event1, *event2;
3639 GST_DEBUG_OBJECT (demux,
3640 "Gap of %" G_GINT64_FORMAT " ns detected in"
3641 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3642 "Sending updated SEGMENT events", diff,
3643 stream->index, GST_TIME_ARGS (stream->pos),
3644 GST_TIME_ARGS (lace_time));
3645 /* send segment events such that the gap is not accounted in
3646 * segment base time, hence running_time */
3647 /* close ahead of gap */
3648 segment = demux->common.segment;
3649 segment.start = demux->last_stop_end;
3650 segment.stop = demux->last_stop_end;
3651 segment.position = demux->last_stop_end;
3652 event1 = gst_event_new_segment (&segment);
3654 segment.start = lace_time;
3655 segment.stop = demux->common.segment.stop;
3656 segment.position = lace_time;
3657 event2 = gst_event_new_segment (&segment);
3658 GST_OBJECT_UNLOCK (demux);
3659 gst_matroska_demux_send_event (demux, event1);
3660 gst_matroska_demux_send_event (demux, event2);
3661 GST_OBJECT_LOCK (demux);
3662 /* align segment view with downstream,
3663 * prevents double-counting base time when closing segment */
3664 /* FIXME: in 0.10, the segment base/accum got updated here, but
3665 * maybe we don't need that because of the double accounting
3666 * mentioned above? */
3667 demux->common.segment = segment;
3671 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3672 || demux->common.segment.position < lace_time) {
3673 demux->common.segment.position = lace_time;
3675 GST_OBJECT_UNLOCK (demux);
3677 last_stop_end = lace_time;
3679 GST_BUFFER_DURATION (sub) = duration / laces;
3680 last_stop_end += GST_BUFFER_DURATION (sub);
3683 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3684 demux->last_stop_end < last_stop_end)
3685 demux->last_stop_end = last_stop_end;
3687 GST_OBJECT_LOCK (demux);
3688 if (demux->common.segment.duration == -1 ||
3689 demux->stream_start_time + demux->common.segment.duration <
3691 demux->common.segment.duration =
3692 last_stop_end - demux->stream_start_time;
3693 GST_OBJECT_UNLOCK (demux);
3694 if (!demux->invalid_duration) {
3695 gst_element_post_message (GST_ELEMENT_CAST (demux),
3696 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3697 demux->invalid_duration = TRUE;
3700 GST_OBJECT_UNLOCK (demux);
3704 stream->pos = lace_time;
3706 gst_matroska_demux_sync_streams (demux);
3708 if (stream->set_discont) {
3709 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3710 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3711 stream->set_discont = FALSE;
3713 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3716 /* reverse playback book-keeping */
3717 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3718 stream->from_time = lace_time;
3719 if (stream->from_offset == -1)
3720 stream->from_offset = offset;
3722 GST_DEBUG_OBJECT (demux,
3723 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3724 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3725 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3726 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
3727 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3730 if (demux->common.element_index) {
3731 if (stream->index_writer_id == -1)
3732 gst_index_get_writer_id (demux->common.element_index,
3733 GST_OBJECT (stream->pad), &stream->index_writer_id);
3735 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3736 G_GUINT64_FORMAT " for writer id %d",
3737 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
3738 stream->index_writer_id);
3739 gst_index_add_association (demux->common.element_index,
3740 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3741 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3742 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
3743 cluster_offset, NULL);
3747 /* Postprocess the buffers depending on the codec used */
3748 if (stream->postprocess_frame) {
3749 GST_LOG_OBJECT (demux, "running post process");
3750 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3753 /* At this point, we have a sub-buffer pointing at data within a larger
3754 buffer. This data might not be aligned with anything. If the data is
3755 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3756 for 32 bit samples, etc), or bad things will happen downstream as
3757 elements typically assume minimal alignment.
3758 Therefore, create an aligned copy if necessary. */
3759 g_assert (stream->alignment <= G_MEM_ALIGN);
3760 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3762 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3763 stream->pos = GST_BUFFER_PTS (sub);
3764 if (GST_BUFFER_DURATION_IS_VALID (sub))
3765 stream->pos += GST_BUFFER_DURATION (sub);
3768 ret = gst_pad_push (stream->pad, sub);
3770 if (demux->common.segment.rate < 0) {
3771 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3772 /* In reverse playback we can get a GST_FLOW_EOS when
3773 * we are at the end of the segment, so we just need to jump
3774 * back to the previous section. */
3775 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3780 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3783 size -= lace_size[n];
3784 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3785 lace_time += duration / laces;
3787 lace_time = GST_CLOCK_TIME_NONE;
3793 gst_buffer_unmap (buf, &map);
3794 gst_buffer_unref (buf);
3806 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3811 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3812 /* non-fatal, try next block(group) */
3818 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3819 /* non-fatal, try next block(group) */
3825 /* return FALSE if block(group) should be skipped (due to a seek) */
3826 static inline gboolean
3827 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3829 if (G_UNLIKELY (demux->seek_block)) {
3830 if (!(--demux->seek_block)) {
3833 GST_LOG_OBJECT (demux, "should skip block due to seek");
3841 static GstFlowReturn
3842 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3846 guint64 seek_pos = (guint64) - 1;
3847 guint32 seek_id = 0;
3850 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3852 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3853 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3857 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3858 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3862 case GST_MATROSKA_ID_SEEKID:
3866 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3869 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3874 case GST_MATROSKA_ID_SEEKPOSITION:
3878 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3881 if (t > G_MAXINT64) {
3882 GST_WARNING_OBJECT (demux,
3883 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3887 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3893 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3899 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3902 if (!seek_id || seek_pos == (guint64) - 1) {
3903 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3904 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3909 case GST_MATROSKA_ID_SEEKHEAD:
3912 case GST_MATROSKA_ID_CUES:
3913 case GST_MATROSKA_ID_TAGS:
3914 case GST_MATROSKA_ID_TRACKS:
3915 case GST_MATROSKA_ID_SEGMENTINFO:
3916 case GST_MATROSKA_ID_ATTACHMENTS:
3917 case GST_MATROSKA_ID_CHAPTERS:
3919 guint64 before_pos, length;
3923 length = gst_matroska_read_common_get_length (&demux->common);
3924 before_pos = demux->common.offset;
3926 if (length == (guint64) - 1) {
3927 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3931 /* check for validity */
3932 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3933 GST_WARNING_OBJECT (demux,
3934 "SeekHead reference lies outside file!" " (%"
3935 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3936 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3941 /* only pick up index location when streaming */
3942 if (demux->streaming) {
3943 if (seek_id == GST_MATROSKA_ID_CUES) {
3944 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3945 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3946 demux->index_offset);
3952 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3955 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3956 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3960 if (id != seek_id) {
3961 GST_WARNING_OBJECT (demux,
3962 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3963 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3966 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3971 demux->common.offset = before_pos;
3975 case GST_MATROSKA_ID_CLUSTER:
3977 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3979 GST_LOG_OBJECT (demux, "Cluster position");
3980 if (G_UNLIKELY (!demux->clusters))
3981 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3982 g_array_append_val (demux->clusters, pos);
3987 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3990 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3995 static GstFlowReturn
3996 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3998 GstFlowReturn ret = GST_FLOW_OK;
4001 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4003 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4004 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4008 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4009 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4013 case GST_MATROSKA_ID_SEEKENTRY:
4015 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
4016 /* Ignore EOS and errors here */
4017 if (ret != GST_FLOW_OK) {
4018 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4025 ret = gst_matroska_read_common_parse_skip (&demux->common,
4026 ebml, "SeekHead", id);
4031 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4033 /* Sort clusters by position for easier searching */
4034 if (demux->clusters)
4035 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4040 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
4042 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4044 static inline GstFlowReturn
4045 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4047 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4048 /* only a few blocks are expected/allowed to be large,
4049 * and will be recursed into, whereas others will be read and must fit */
4050 if (demux->streaming) {
4051 /* fatal in streaming case, as we can't step over easily */
4052 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4053 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4054 "file might be corrupt.", bytes));
4055 return GST_FLOW_ERROR;
4057 /* indicate higher level to quietly give up */
4058 GST_DEBUG_OBJECT (demux,
4059 "too large block of size %" G_GUINT64_FORMAT, bytes);
4060 return GST_FLOW_ERROR;
4067 /* returns TRUE if we truely are in error state, and should give up */
4068 static inline gboolean
4069 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4071 if (!demux->streaming && demux->next_cluster_offset > 0) {
4072 /* just repositioning to where next cluster should be and try from there */
4073 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4074 G_GUINT64_FORMAT, demux->next_cluster_offset);
4075 demux->common.offset = demux->next_cluster_offset;
4076 demux->next_cluster_offset = 0;
4081 /* sigh, one last attempt above and beyond call of duty ...;
4082 * search for cluster mark following current pos */
4083 pos = demux->common.offset;
4084 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4085 if (gst_matroska_demux_search_cluster (demux, &pos) != GST_FLOW_OK) {
4086 /* did not work, give up */
4089 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4090 /* try that position */
4091 demux->common.offset = pos;
4097 static inline GstFlowReturn
4098 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4100 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4101 demux->common.offset += flush;
4102 if (demux->streaming) {
4105 /* hard to skip large blocks when streaming */
4106 ret = gst_matroska_demux_check_read_size (demux, flush);
4107 if (ret != GST_FLOW_OK)
4109 if (flush <= gst_adapter_available (demux->common.adapter))
4110 gst_adapter_flush (demux->common.adapter, flush);
4112 return GST_FLOW_EOS;
4117 /* initializes @ebml with @bytes from input stream at current offset.
4118 * Returns EOS if insufficient available,
4119 * ERROR if too much was attempted to read. */
4120 static inline GstFlowReturn
4121 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4124 GstBuffer *buffer = NULL;
4125 GstFlowReturn ret = GST_FLOW_OK;
4127 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4129 ret = gst_matroska_demux_check_read_size (demux, bytes);
4130 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4131 if (!demux->streaming) {
4132 /* in pull mode, we can skip */
4133 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4134 ret = GST_FLOW_OVERFLOW;
4136 /* otherwise fatal */
4137 ret = GST_FLOW_ERROR;
4141 if (demux->streaming) {
4142 if (gst_adapter_available (demux->common.adapter) >= bytes)
4143 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4147 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4148 demux->common.offset, bytes, &buffer, NULL);
4149 if (G_LIKELY (buffer)) {
4150 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4151 demux->common.offset);
4152 demux->common.offset += bytes;
4159 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4162 gboolean seekable = FALSE;
4163 gint64 start = -1, stop = -1;
4165 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4166 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4167 GST_DEBUG_OBJECT (demux, "seeking query failed");
4171 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4173 /* try harder to query upstream size if we didn't get it the first time */
4174 if (seekable && stop == -1) {
4175 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4176 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4180 /* if upstream doesn't know the size, it's likely that it's not seekable in
4181 * practice even if it technically may be seekable */
4182 if (seekable && (start != 0 || stop <= start)) {
4183 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4188 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4189 G_GUINT64_FORMAT ")", seekable, start, stop);
4190 demux->seekable = seekable;
4192 gst_query_unref (query);
4195 static GstFlowReturn
4196 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4202 GstFlowReturn ret = GST_FLOW_OK;
4204 GST_WARNING_OBJECT (demux,
4205 "Found Cluster element before Tracks, searching Tracks");
4208 before_pos = demux->common.offset;
4210 /* Search Tracks element */
4212 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4213 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4214 if (ret != GST_FLOW_OK)
4217 if (id != GST_MATROSKA_ID_TRACKS) {
4218 /* we may be skipping large cluster here, so forego size check etc */
4219 /* ... but we can't skip undefined size; force error */
4220 if (length == G_MAXUINT64) {
4221 ret = gst_matroska_demux_check_read_size (demux, length);
4224 demux->common.offset += needed;
4225 demux->common.offset += length;
4230 /* will lead to track parsing ... */
4231 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4236 demux->common.offset = before_pos;
4241 #define GST_READ_CHECK(stmt) \
4243 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4244 if (ret == GST_FLOW_OVERFLOW) { \
4245 ret = GST_FLOW_OK; \
4251 static GstFlowReturn
4252 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4253 guint64 length, guint needed)
4255 GstEbmlRead ebml = { 0, };
4256 GstFlowReturn ret = GST_FLOW_OK;
4259 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4260 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4262 /* if we plan to read and parse this element, we need prefix (id + length)
4263 * and the contents */
4264 /* mind about overflow wrap-around when dealing with undefined size */
4266 if (G_LIKELY (length != G_MAXUINT64))
4269 switch (demux->common.state) {
4270 case GST_MATROSKA_READ_STATE_START:
4272 case GST_EBML_ID_HEADER:
4273 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4274 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4275 if (ret != GST_FLOW_OK)
4277 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4278 gst_matroska_demux_check_seekability (demux);
4281 goto invalid_header;
4285 case GST_MATROSKA_READ_STATE_SEGMENT:
4287 case GST_MATROSKA_ID_SEGMENT:
4288 /* eat segment prefix */
4289 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4290 GST_DEBUG_OBJECT (demux,
4291 "Found Segment start at offset %" G_GUINT64_FORMAT,
4292 demux->common.offset);
4293 /* seeks are from the beginning of the segment,
4294 * after the segment ID/length */
4295 demux->common.ebml_segment_start = demux->common.offset;
4296 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4299 GST_WARNING_OBJECT (demux,
4300 "Expected a Segment ID (0x%x), but received 0x%x!",
4301 GST_MATROSKA_ID_SEGMENT, id);
4302 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4306 case GST_MATROSKA_READ_STATE_SCANNING:
4307 if (id != GST_MATROSKA_ID_CLUSTER &&
4308 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4311 case GST_MATROSKA_READ_STATE_HEADER:
4312 case GST_MATROSKA_READ_STATE_DATA:
4313 case GST_MATROSKA_READ_STATE_SEEK:
4315 case GST_MATROSKA_ID_SEGMENTINFO:
4316 if (!demux->common.segmentinfo_parsed) {
4317 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4318 ret = gst_matroska_read_common_parse_info (&demux->common,
4319 GST_ELEMENT_CAST (demux), &ebml);
4321 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4324 case GST_MATROSKA_ID_TRACKS:
4325 if (!demux->tracks_parsed) {
4326 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4327 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4329 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4332 case GST_MATROSKA_ID_CLUSTER:
4333 if (G_UNLIKELY (!demux->tracks_parsed)) {
4334 if (demux->streaming) {
4335 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4336 goto not_streamable;
4338 ret = gst_matroska_demux_find_tracks (demux);
4339 if (!demux->tracks_parsed)
4343 if (G_UNLIKELY (demux->common.state
4344 == GST_MATROSKA_READ_STATE_HEADER)) {
4345 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4346 demux->first_cluster_offset = demux->common.offset;
4347 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4348 gst_element_no_more_pads (GST_ELEMENT (demux));
4349 /* send initial segment - we wait till we know the first
4350 incoming timestamp, so we can properly set the start of
4352 demux->need_segment = TRUE;
4354 demux->cluster_time = GST_CLOCK_TIME_NONE;
4355 demux->cluster_offset = demux->common.offset;
4356 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4357 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4358 " not found in Cluster, trying next Cluster's first block instead",
4360 demux->seek_block = 0;
4362 demux->seek_first = FALSE;
4363 /* record next cluster for recovery */
4364 if (read != G_MAXUINT64)
4365 demux->next_cluster_offset = demux->cluster_offset + read;
4366 /* eat cluster prefix */
4367 gst_matroska_demux_flush (demux, needed);
4369 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4373 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4374 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4376 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4377 demux->cluster_time = num;
4379 if (demux->common.element_index) {
4380 if (demux->common.element_index_writer_id == -1)
4381 gst_index_get_writer_id (demux->common.element_index,
4382 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4383 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4384 G_GUINT64_FORMAT " for writer id %d",
4385 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4386 demux->common.element_index_writer_id);
4387 gst_index_add_association (demux->common.element_index,
4388 demux->common.element_index_writer_id,
4389 GST_ASSOCIATION_FLAG_KEY_UNIT,
4390 GST_FORMAT_TIME, demux->cluster_time,
4391 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4396 case GST_MATROSKA_ID_BLOCKGROUP:
4397 if (!gst_matroska_demux_seek_block (demux))
4399 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4400 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4401 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4402 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4403 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4405 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4407 case GST_MATROSKA_ID_SIMPLEBLOCK:
4408 if (!gst_matroska_demux_seek_block (demux))
4410 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4411 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4412 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4413 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4414 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4416 case GST_MATROSKA_ID_ATTACHMENTS:
4417 if (!demux->common.attachments_parsed) {
4418 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4419 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4420 GST_ELEMENT_CAST (demux), &ebml);
4422 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4425 case GST_MATROSKA_ID_TAGS:
4426 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4427 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4428 GST_ELEMENT_CAST (demux), &ebml);
4430 case GST_MATROSKA_ID_CHAPTERS:
4431 if (!demux->common.chapters_parsed) {
4432 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4434 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4436 if (demux->common.toc) {
4437 gst_matroska_demux_send_event (demux,
4438 gst_event_new_toc (demux->common.toc, FALSE));
4441 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4443 case GST_MATROSKA_ID_SEEKHEAD:
4444 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4445 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4447 case GST_MATROSKA_ID_CUES:
4448 if (demux->common.index_parsed) {
4449 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4452 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4453 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4454 /* only push based; delayed index building */
4455 if (ret == GST_FLOW_OK
4456 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4459 GST_OBJECT_LOCK (demux);
4460 event = demux->seek_event;
4461 demux->seek_event = NULL;
4462 GST_OBJECT_UNLOCK (demux);
4465 /* unlikely to fail, since we managed to seek to this point */
4466 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4468 /* resume data handling, main thread clear to seek again */
4469 GST_OBJECT_LOCK (demux);
4470 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4471 GST_OBJECT_UNLOCK (demux);
4474 case GST_MATROSKA_ID_POSITION:
4475 case GST_MATROSKA_ID_PREVSIZE:
4476 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4477 case GST_MATROSKA_ID_SILENTTRACKS:
4478 GST_DEBUG_OBJECT (demux,
4479 "Skipping Cluster subelement 0x%x - ignoring", id);
4483 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4484 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4490 if (ret == GST_FLOW_PARSE)
4494 gst_ebml_read_clear (&ebml);
4500 /* simply exit, maybe not enough data yet */
4501 /* no ebml to clear if read error */
4506 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4507 ("Failed to parse Element 0x%x", id));
4508 ret = GST_FLOW_ERROR;
4513 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4514 ("File layout does not permit streaming"));
4515 ret = GST_FLOW_ERROR;
4520 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4521 ("No Tracks element found"));
4522 ret = GST_FLOW_ERROR;
4527 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4528 ret = GST_FLOW_ERROR;
4533 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4534 ret = GST_FLOW_ERROR;
4540 gst_matroska_demux_loop (GstPad * pad)
4542 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4548 /* If we have to close a segment, send a new segment to do this now */
4549 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4550 if (G_UNLIKELY (demux->new_segment)) {
4551 gst_matroska_demux_send_event (demux, demux->new_segment);
4552 demux->new_segment = NULL;
4556 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4557 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4558 if (ret == GST_FLOW_EOS) {
4560 } else if (ret == GST_FLOW_FLUSHING) {
4562 } else if (ret != GST_FLOW_OK) {
4563 if (gst_matroska_demux_check_parse_error (demux))
4569 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4570 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4573 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4574 if (ret == GST_FLOW_EOS)
4576 if (ret != GST_FLOW_OK)
4579 /* check if we're at the end of a configured segment */
4580 if (G_LIKELY (demux->common.src->len)) {
4583 g_assert (demux->common.num_streams == demux->common.src->len);
4584 for (i = 0; i < demux->common.src->len; i++) {
4585 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4587 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4588 GST_TIME_ARGS (context->pos));
4589 if (context->eos == FALSE)
4593 GST_INFO_OBJECT (demux, "All streams are EOS");
4599 if (G_UNLIKELY (demux->common.offset ==
4600 gst_matroska_read_common_get_length (&demux->common))) {
4601 GST_LOG_OBJECT (demux, "Reached end of stream");
4611 if (demux->common.segment.rate < 0.0) {
4612 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4613 if (ret == GST_FLOW_OK)
4620 const gchar *reason = gst_flow_get_name (ret);
4621 gboolean push_eos = FALSE;
4623 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4624 gst_pad_pause_task (demux->common.sinkpad);
4626 if (ret == GST_FLOW_EOS) {
4627 /* perform EOS logic */
4629 /* If we were in the headers, make sure we send no-more-pads.
4630 This will ensure decodebin2 does not get stuck thinking
4631 the chain is not complete yet, and waiting indefinitely. */
4632 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4633 if (demux->common.src->len == 0) {
4634 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4635 ("No pads created"));
4637 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4638 ("Failed to finish reading headers"));
4640 gst_element_no_more_pads (GST_ELEMENT (demux));
4643 /* Close the segment, i.e. update segment stop with the duration
4644 * if no stop was set */
4645 if (GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
4646 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
4647 GST_CLOCK_TIME_IS_VALID (demux->common.segment.start) &&
4648 demux->last_stop_end > demux->common.segment.start) {
4649 GstSegment segment = demux->common.segment;
4652 segment.stop = demux->last_stop_end;
4653 event = gst_event_new_segment (&segment);
4654 gst_matroska_demux_send_event (demux, event);
4657 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4660 /* for segment playback we need to post when (in stream time)
4661 * we stopped, this is either stop (when set) or the duration. */
4662 if ((stop = demux->common.segment.stop) == -1)
4663 stop = demux->last_stop_end;
4665 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4666 gst_element_post_message (GST_ELEMENT (demux),
4667 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4669 gst_matroska_demux_send_event (demux,
4670 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4674 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4675 /* for fatal errors we post an error message */
4676 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4677 ("stream stopped, reason %s", reason));
4681 /* send EOS, and prevent hanging if no streams yet */
4682 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4683 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4684 (ret == GST_FLOW_EOS)) {
4685 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4686 (NULL), ("got eos but no streams (yet)"));
4694 * Create and push a flushing seek event upstream
4697 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4703 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4706 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4707 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4708 GST_SEEK_TYPE_NONE, -1);
4709 gst_event_set_seqnum (event, seqnum);
4711 res = gst_pad_push_event (demux->common.sinkpad, event);
4713 /* segment event will update offset */
4717 static GstFlowReturn
4718 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4720 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4722 GstFlowReturn ret = GST_FLOW_OK;
4727 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4728 GST_DEBUG_OBJECT (demux, "got DISCONT");
4729 gst_adapter_clear (demux->common.adapter);
4730 GST_OBJECT_LOCK (demux);
4731 gst_matroska_read_common_reset_streams (&demux->common,
4732 GST_CLOCK_TIME_NONE, FALSE);
4733 GST_OBJECT_UNLOCK (demux);
4736 gst_adapter_push (demux->common.adapter, buffer);
4740 available = gst_adapter_available (demux->common.adapter);
4742 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4743 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4744 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS))
4747 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4748 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4749 demux->common.offset, id, length, needed, available);
4751 if (needed > available)
4754 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4755 if (ret == GST_FLOW_EOS) {
4756 /* need more data */
4758 } else if (ret != GST_FLOW_OK) {
4765 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4768 gboolean res = TRUE;
4769 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4771 GST_DEBUG_OBJECT (demux,
4772 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4774 switch (GST_EVENT_TYPE (event)) {
4775 case GST_EVENT_SEGMENT:
4777 const GstSegment *segment;
4779 /* some debug output */
4780 gst_event_parse_segment (event, &segment);
4781 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4782 GST_DEBUG_OBJECT (demux,
4783 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4786 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4787 GST_DEBUG_OBJECT (demux, "still starting");
4791 /* we only expect a BYTE segment, e.g. following a seek */
4792 if (segment->format != GST_FORMAT_BYTES) {
4793 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4797 GST_DEBUG_OBJECT (demux, "clearing segment state");
4798 GST_OBJECT_LOCK (demux);
4799 /* clear current segment leftover */
4800 gst_adapter_clear (demux->common.adapter);
4801 /* and some streaming setup */
4802 demux->common.offset = segment->start;
4803 /* accumulate base based on current position */
4804 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4805 demux->common.segment.base +=
4806 (MAX (demux->common.segment.position, demux->stream_start_time)
4807 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4808 /* do not know where we are;
4809 * need to come across a cluster and generate segment */
4810 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4811 demux->cluster_time = GST_CLOCK_TIME_NONE;
4812 demux->cluster_offset = 0;
4813 demux->need_segment = TRUE;
4814 demux->segment_seqnum = gst_event_get_seqnum (event);
4815 /* but keep some of the upstream segment */
4816 demux->common.segment.rate = segment->rate;
4817 /* also check if need to keep some of the requested seek position */
4818 if (demux->seek_offset == segment->start) {
4819 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4820 demux->common.segment.position = demux->requested_seek_time;
4822 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4824 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4825 demux->seek_offset = -1;
4826 GST_OBJECT_UNLOCK (demux);
4828 /* chain will send initial segment after pads have been added,
4829 * or otherwise come up with one */
4830 GST_DEBUG_OBJECT (demux, "eating event");
4831 gst_event_unref (event);
4837 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4838 gst_event_unref (event);
4839 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4840 (NULL), ("got eos and didn't receive a complete header object"));
4841 } else if (demux->common.num_streams == 0) {
4842 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4843 (NULL), ("got eos but no streams (yet)"));
4845 gst_matroska_demux_send_event (demux, event);
4849 case GST_EVENT_FLUSH_STOP:
4853 gst_adapter_clear (demux->common.adapter);
4854 GST_OBJECT_LOCK (demux);
4855 gst_matroska_read_common_reset_streams (&demux->common,
4856 GST_CLOCK_TIME_NONE, TRUE);
4857 dur = demux->common.segment.duration;
4858 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4859 demux->common.segment.duration = dur;
4860 demux->cluster_time = GST_CLOCK_TIME_NONE;
4861 demux->cluster_offset = 0;
4862 GST_OBJECT_UNLOCK (demux);
4866 res = gst_pad_event_default (pad, parent, event);
4874 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4876 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4878 gboolean pull_mode = FALSE;
4880 query = gst_query_new_scheduling ();
4882 if (gst_pad_peer_query (sinkpad, query))
4883 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4884 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4886 gst_query_unref (query);
4889 GST_DEBUG ("going to pull mode");
4890 demux->streaming = FALSE;
4891 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4893 GST_DEBUG ("going to push (streaming) mode");
4894 demux->streaming = TRUE;
4895 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4900 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4901 GstPadMode mode, gboolean active)
4904 case GST_PAD_MODE_PULL:
4906 /* if we have a scheduler we can start the task */
4907 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4910 gst_pad_stop_task (sinkpad);
4913 case GST_PAD_MODE_PUSH:
4921 gst_duration_to_fraction (guint64 duration, gint * dest_n, gint * dest_d)
4923 static const int common_den[] = { 1, 2, 3, 4, 1001 };
4928 for (i = 0; i < G_N_ELEMENTS (common_den); i++) {
4930 n = floor (0.5 + (d * 1e9) / duration);
4931 a = gst_util_uint64_scale_int (1000000000, d, n);
4932 if (duration >= a - 1 && duration <= a + 1) {
4937 gst_util_double_to_fraction (1e9 / duration, &n, &d);
4946 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4947 videocontext, const gchar * codec_id, guint8 * data, guint size,
4948 gchar ** codec_name, guint32 * riff_fourcc)
4950 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4951 GstCaps *caps = NULL;
4953 g_assert (videocontext != NULL);
4954 g_assert (codec_name != NULL);
4959 /* TODO: check if we have all codec types from matroska-ids.h
4960 * check if we have to do more special things with codec_private
4963 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4964 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4967 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4968 gst_riff_strf_vids *vids = NULL;
4971 GstBuffer *buf = NULL;
4973 vids = (gst_riff_strf_vids *) data;
4975 /* assure size is big enough */
4977 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4980 if (size < sizeof (gst_riff_strf_vids)) {
4981 vids = g_new (gst_riff_strf_vids, 1);
4982 memcpy (vids, data, size);
4985 /* little-endian -> byte-order */
4986 vids->size = GUINT32_FROM_LE (vids->size);
4987 vids->width = GUINT32_FROM_LE (vids->width);
4988 vids->height = GUINT32_FROM_LE (vids->height);
4989 vids->planes = GUINT16_FROM_LE (vids->planes);
4990 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4991 vids->compression = GUINT32_FROM_LE (vids->compression);
4992 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4993 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4994 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4995 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4996 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4998 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4999 gsize offset = sizeof (gst_riff_strf_vids);
5002 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
5003 size - offset), size - offset);
5007 *riff_fourcc = vids->compression;
5009 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
5010 buf, NULL, codec_name);
5013 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
5014 GST_FOURCC_ARGS (vids->compression));
5018 gst_buffer_unref (buf);
5020 if (vids != (gst_riff_strf_vids *) data)
5023 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
5024 const gchar *format = NULL;
5026 switch (videocontext->fourcc) {
5027 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5028 *codec_name = g_strdup ("Raw planar YUV 4:2:0");
5031 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5032 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
5035 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5036 *codec_name = g_strdup ("Raw packed YUV 4:2:0");
5039 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5040 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
5043 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5044 *codec_name = g_strdup ("Raw packed YUV 4:4:4 with alpha channel");
5049 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5050 GST_FOURCC_ARGS (videocontext->fourcc));
5054 caps = gst_caps_new_simple ("video/x-raw",
5055 "format", G_TYPE_STRING, format, NULL);
5056 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5057 caps = gst_caps_new_simple ("video/x-divx",
5058 "divxversion", G_TYPE_INT, 4, NULL);
5059 *codec_name = g_strdup ("MPEG-4 simple profile");
5060 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5061 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5062 caps = gst_caps_new_simple ("video/mpeg",
5063 "mpegversion", G_TYPE_INT, 4,
5064 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5068 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5069 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5070 gst_buffer_unref (priv);
5072 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
5074 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5075 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5077 *codec_name = g_strdup ("MPEG-4 advanced profile");
5078 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5080 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5081 "divxversion", G_TYPE_INT, 3, NULL),
5082 gst_structure_new ("video/x-msmpeg",
5083 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5085 caps = gst_caps_new_simple ("video/x-msmpeg",
5086 "msmpegversion", G_TYPE_INT, 43, NULL);
5087 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5088 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5089 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5092 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5097 caps = gst_caps_new_simple ("video/mpeg",
5098 "systemstream", G_TYPE_BOOLEAN, FALSE,
5099 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5100 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5101 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5102 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5103 caps = gst_caps_new_empty_simple ("image/jpeg");
5104 *codec_name = g_strdup ("Motion-JPEG");
5105 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5106 caps = gst_caps_new_empty_simple ("video/x-h264");
5110 /* First byte is the version, second is the profile indication, and third
5111 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5112 * level indication. */
5113 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5116 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5117 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5118 gst_buffer_unref (priv);
5120 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5121 "alignment", G_TYPE_STRING, "au", NULL);
5123 GST_WARNING ("No codec data found, assuming output is byte-stream");
5124 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5127 *codec_name = g_strdup ("H264");
5128 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5129 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5130 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5131 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5132 gint rmversion = -1;
5134 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5136 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5138 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5140 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5143 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5144 "rmversion", G_TYPE_INT, rmversion, NULL);
5145 GST_DEBUG ("data:%p, size:0x%x", data, size);
5146 /* We need to extract the extradata ! */
5147 if (data && (size >= 0x22)) {
5152 subformat = GST_READ_UINT32_BE (data + 0x1a);
5153 rformat = GST_READ_UINT32_BE (data + 0x1e);
5156 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5158 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5159 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5160 gst_buffer_unref (priv);
5163 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5164 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5165 caps = gst_caps_new_empty_simple ("video/x-theora");
5166 context->stream_headers =
5167 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5168 context->codec_priv_size);
5169 /* FIXME: mark stream as broken and skip if there are no stream headers */
5170 context->send_stream_headers = TRUE;
5171 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5172 caps = gst_caps_new_empty_simple ("video/x-dirac");
5173 *codec_name = g_strdup_printf ("Dirac");
5174 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5175 caps = gst_caps_new_empty_simple ("video/x-vp8");
5176 *codec_name = g_strdup_printf ("On2 VP8");
5177 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5178 caps = gst_caps_new_empty_simple ("video/x-vp9");
5179 *codec_name = g_strdup_printf ("On2 VP9");
5181 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5187 GstStructure *structure;
5189 for (i = 0; i < gst_caps_get_size (caps); i++) {
5190 structure = gst_caps_get_structure (caps, i);
5192 /* FIXME: use the real unit here! */
5193 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5194 videocontext->pixel_width,
5195 videocontext->pixel_height,
5196 videocontext->display_width, videocontext->display_height);
5198 /* pixel width and height are the w and h of the video in pixels */
5199 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5200 gint w = videocontext->pixel_width;
5201 gint h = videocontext->pixel_height;
5203 gst_structure_set (structure,
5204 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5207 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5210 if (videocontext->display_width <= 0)
5211 videocontext->display_width = videocontext->pixel_width;
5212 if (videocontext->display_height <= 0)
5213 videocontext->display_height = videocontext->pixel_height;
5215 /* calculate the pixel aspect ratio using the display and pixel w/h */
5216 n = videocontext->display_width * videocontext->pixel_height;
5217 d = videocontext->display_height * videocontext->pixel_width;
5218 GST_DEBUG ("setting PAR to %d/%d", n, d);
5219 gst_structure_set (structure, "pixel-aspect-ratio",
5221 videocontext->display_width * videocontext->pixel_height,
5222 videocontext->display_height * videocontext->pixel_width, NULL);
5225 if (videocontext->default_fps > 0.0) {
5226 GValue fps_double = { 0, };
5227 GValue fps_fraction = { 0, };
5229 g_value_init (&fps_double, G_TYPE_DOUBLE);
5230 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
5231 g_value_set_double (&fps_double, videocontext->default_fps);
5232 g_value_transform (&fps_double, &fps_fraction);
5234 GST_DEBUG ("using default fps %f", videocontext->default_fps);
5236 gst_structure_set_value (structure, "framerate", &fps_fraction);
5237 g_value_unset (&fps_double);
5238 g_value_unset (&fps_fraction);
5239 } else if (context->default_duration > 0) {
5242 gst_duration_to_fraction (context->default_duration, &fps_n, &fps_d);
5244 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5245 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5247 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5248 fps_n, fps_d, NULL);
5250 /* sort of a hack to get most codecs to support,
5251 * even if the default_duration is missing */
5252 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5256 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5257 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5261 caps = gst_caps_simplify (caps);
5268 * Some AAC specific code... *sigh*
5269 * FIXME: maybe we should use '15' and code the sample rate explicitly
5270 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5274 aac_rate_idx (gint rate)
5278 else if (75132 <= rate)
5280 else if (55426 <= rate)
5282 else if (46009 <= rate)
5284 else if (37566 <= rate)
5286 else if (27713 <= rate)
5288 else if (23004 <= rate)
5290 else if (18783 <= rate)
5292 else if (13856 <= rate)
5294 else if (11502 <= rate)
5296 else if (9391 <= rate)
5303 aac_profile_idx (const gchar * codec_id)
5307 if (strlen (codec_id) <= 12)
5309 else if (!strncmp (&codec_id[12], "MAIN", 4))
5311 else if (!strncmp (&codec_id[12], "LC", 2))
5313 else if (!strncmp (&codec_id[12], "SSR", 3))
5321 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5324 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5325 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5326 gchar ** codec_name, guint16 * riff_audio_fmt)
5328 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5329 GstCaps *caps = NULL;
5331 g_assert (audiocontext != NULL);
5332 g_assert (codec_name != NULL);
5335 *riff_audio_fmt = 0;
5337 /* TODO: check if we have all codec types from matroska-ids.h
5338 * check if we have to do more special things with codec_private
5339 * check if we need bitdepth in different places too
5340 * implement channel position magic
5342 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5343 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5344 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5345 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5348 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5349 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5350 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5353 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5355 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5360 caps = gst_caps_new_simple ("audio/mpeg",
5361 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5362 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5363 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5364 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5367 GstAudioFormat format;
5369 sign = (audiocontext->bitdepth != 8);
5370 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5371 endianness = G_BIG_ENDIAN;
5373 endianness = G_LITTLE_ENDIAN;
5375 format = gst_audio_format_build_integer (sign, endianness,
5376 audiocontext->bitdepth, audiocontext->bitdepth);
5378 /* FIXME: Channel mask and reordering */
5379 caps = gst_caps_new_simple ("audio/x-raw",
5380 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5381 "layout", G_TYPE_STRING, "interleaved", NULL);
5383 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5384 audiocontext->bitdepth);
5385 context->alignment = audiocontext->bitdepth / 8;
5386 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5387 const gchar *format;
5388 if (audiocontext->bitdepth == 32)
5392 /* FIXME: Channel mask and reordering */
5393 caps = gst_caps_new_simple ("audio/x-raw",
5394 "format", G_TYPE_STRING, format,
5395 "layout", G_TYPE_STRING, "interleaved", NULL);
5396 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5397 audiocontext->bitdepth);
5398 context->alignment = audiocontext->bitdepth / 8;
5399 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5400 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5401 caps = gst_caps_new_simple ("audio/x-ac3",
5402 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5403 *codec_name = g_strdup ("AC-3 audio");
5404 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5405 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5406 caps = gst_caps_new_simple ("audio/x-eac3",
5407 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5408 *codec_name = g_strdup ("E-AC-3 audio");
5409 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5410 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5411 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5412 *codec_name = g_strdup ("Dolby TrueHD");
5413 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5414 caps = gst_caps_new_empty_simple ("audio/x-dts");
5415 *codec_name = g_strdup ("DTS audio");
5416 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5417 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5418 context->stream_headers =
5419 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5420 context->codec_priv_size);
5421 /* FIXME: mark stream as broken and skip if there are no stream headers */
5422 context->send_stream_headers = TRUE;
5423 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5424 caps = gst_caps_new_empty_simple ("audio/x-flac");
5425 context->stream_headers =
5426 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5427 context->codec_priv_size);
5428 /* FIXME: mark stream as broken and skip if there are no stream headers */
5429 context->send_stream_headers = TRUE;
5430 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5431 caps = gst_caps_new_empty_simple ("audio/x-speex");
5432 context->stream_headers =
5433 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5434 context->codec_priv_size);
5435 /* FIXME: mark stream as broken and skip if there are no stream headers */
5436 context->send_stream_headers = TRUE;
5437 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5438 gst_riff_strf_auds auds;
5441 GstBuffer *codec_data;
5443 /* little-endian -> byte-order */
5444 auds.format = GST_READ_UINT16_LE (data);
5445 auds.channels = GST_READ_UINT16_LE (data + 2);
5446 auds.rate = GST_READ_UINT32_LE (data + 4);
5447 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5448 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5449 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5451 /* 18 is the waveformatex size */
5452 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5453 data + 18, auds.bits_per_sample, 0, auds.bits_per_sample, NULL, NULL);
5456 *riff_audio_fmt = auds.format;
5458 /* FIXME: Handle reorder map */
5459 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5460 codec_data, codec_name, NULL);
5461 gst_buffer_unref (codec_data);
5464 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5467 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5468 GstBuffer *priv = NULL;
5470 gint rate_idx, profile;
5471 guint8 *data = NULL;
5473 /* unspecified AAC profile with opaque private codec data */
5474 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5475 if (context->codec_priv_size >= 2) {
5476 guint obj_type, freq_index, explicit_freq_bytes = 0;
5478 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5480 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5481 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5482 if (freq_index == 15)
5483 explicit_freq_bytes = 3;
5484 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5485 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5486 context->codec_priv_size), context->codec_priv_size);
5487 /* assume SBR if samplerate <= 24kHz */
5488 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5489 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5490 audiocontext->samplerate *= 2;
5493 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5494 /* this is pretty broken;
5495 * maybe we need to make up some default private,
5496 * or maybe ADTS data got dumped in.
5497 * Let's set up some private data now, and check actual data later */
5498 /* just try this and see what happens ... */
5499 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5500 context->postprocess_frame = gst_matroska_demux_check_aac;
5504 /* make up decoder-specific data if it is not supplied */
5508 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5509 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5511 rate_idx = aac_rate_idx (audiocontext->samplerate);
5512 profile = aac_profile_idx (codec_id);
5514 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5515 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5517 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5518 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5520 gst_buffer_unmap (priv, &map);
5521 gst_buffer_set_size (priv, 2);
5522 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5523 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5526 if (g_strrstr (codec_id, "SBR")) {
5527 /* HE-AAC (aka SBR AAC) */
5528 audiocontext->samplerate *= 2;
5529 rate_idx = aac_rate_idx (audiocontext->samplerate);
5530 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5531 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5532 data[4] = (1 << 7) | (rate_idx << 3);
5533 gst_buffer_unmap (priv, &map);
5535 gst_buffer_unmap (priv, &map);
5536 gst_buffer_set_size (priv, 2);
5539 gst_buffer_unmap (priv, &map);
5540 gst_buffer_unref (priv);
5542 GST_ERROR ("Unknown AAC profile and no codec private data");
5547 caps = gst_caps_new_simple ("audio/mpeg",
5548 "mpegversion", G_TYPE_INT, mpegversion,
5549 "framed", G_TYPE_BOOLEAN, TRUE,
5550 "stream-format", G_TYPE_STRING, "raw", NULL);
5551 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5552 if (context->codec_priv && context->codec_priv_size > 0)
5553 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5554 context->codec_priv, context->codec_priv_size);
5555 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5556 gst_buffer_unref (priv);
5558 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5559 caps = gst_caps_new_simple ("audio/x-tta",
5560 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5561 *codec_name = g_strdup ("TTA audio");
5562 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5563 caps = gst_caps_new_simple ("audio/x-wavpack",
5564 "width", G_TYPE_INT, audiocontext->bitdepth,
5565 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5566 *codec_name = g_strdup ("Wavpack audio");
5567 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5568 audiocontext->wvpk_block_index = 0;
5569 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5570 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5571 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5572 gint raversion = -1;
5574 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5576 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5581 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5582 "raversion", G_TYPE_INT, raversion, NULL);
5583 /* Extract extra information from caps, mapping varies based on codec */
5584 if (data && (size >= 0x50)) {
5591 guint extra_data_size;
5593 GST_ERROR ("real audio raversion:%d", raversion);
5594 if (raversion == 8) {
5596 flavor = GST_READ_UINT16_BE (data + 22);
5597 packet_size = GST_READ_UINT32_BE (data + 24);
5598 height = GST_READ_UINT16_BE (data + 40);
5599 leaf_size = GST_READ_UINT16_BE (data + 44);
5600 sample_width = GST_READ_UINT16_BE (data + 58);
5601 extra_data_size = GST_READ_UINT32_BE (data + 74);
5604 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5605 flavor, packet_size, height, leaf_size, sample_width,
5607 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5608 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5609 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5611 if ((size - 78) >= extra_data_size) {
5612 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5614 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5615 gst_buffer_unref (priv);
5620 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5621 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5622 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5623 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5624 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5625 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5626 *codec_name = g_strdup ("Real Audio Lossless");
5627 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5628 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5629 *codec_name = g_strdup ("Sony ATRAC3");
5631 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5636 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5639 for (i = 0; i < gst_caps_get_size (caps); i++) {
5640 gst_structure_set (gst_caps_get_structure (caps, i),
5641 "channels", G_TYPE_INT, audiocontext->channels,
5642 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5646 caps = gst_caps_simplify (caps);
5653 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5654 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5656 GstCaps *caps = NULL;
5657 GstMatroskaTrackContext *context =
5658 (GstMatroskaTrackContext *) subtitlecontext;
5660 /* for backwards compatibility */
5661 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5662 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5663 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5664 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5665 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5666 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5667 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5668 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5670 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5671 * Check if we have to do something with codec_private */
5672 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5673 /* well, plain text simply does not have a lot of markup ... */
5674 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5675 "pango-markup", NULL);
5676 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5677 subtitlecontext->check_markup = TRUE;
5678 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5679 caps = gst_caps_new_empty_simple ("application/x-ssa");
5680 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5681 subtitlecontext->check_markup = FALSE;
5682 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5683 caps = gst_caps_new_empty_simple ("application/x-ass");
5684 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5685 subtitlecontext->check_markup = FALSE;
5686 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5687 caps = gst_caps_new_empty_simple ("application/x-usf");
5688 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5689 subtitlecontext->check_markup = FALSE;
5690 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5691 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5692 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5693 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5694 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5695 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5696 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5697 context->stream_headers =
5698 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5699 context->codec_priv_size);
5700 /* FIXME: mark stream as broken and skip if there are no stream headers */
5701 context->send_stream_headers = TRUE;
5703 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5704 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5707 if (data != NULL && size > 0) {
5710 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5711 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5712 gst_buffer_unref (buf);
5720 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5722 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5724 GST_OBJECT_LOCK (demux);
5725 if (demux->common.element_index)
5726 gst_object_unref (demux->common.element_index);
5727 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5728 GST_OBJECT_UNLOCK (demux);
5729 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5730 demux->common.element_index);
5734 gst_matroska_demux_get_index (GstElement * element)
5736 GstIndex *result = NULL;
5737 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5739 GST_OBJECT_LOCK (demux);
5740 if (demux->common.element_index)
5741 result = gst_object_ref (demux->common.element_index);
5742 GST_OBJECT_UNLOCK (demux);
5744 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5750 static GstStateChangeReturn
5751 gst_matroska_demux_change_state (GstElement * element,
5752 GstStateChange transition)
5754 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5755 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5757 /* handle upwards state changes here */
5758 switch (transition) {
5763 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5765 /* handle downwards state changes */
5766 switch (transition) {
5767 case GST_STATE_CHANGE_PAUSED_TO_READY:
5768 gst_matroska_demux_reset (GST_ELEMENT (demux));
5778 gst_matroska_demux_set_property (GObject * object,
5779 guint prop_id, const GValue * value, GParamSpec * pspec)
5781 GstMatroskaDemux *demux;
5783 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5784 demux = GST_MATROSKA_DEMUX (object);
5787 case ARG_MAX_GAP_TIME:
5788 GST_OBJECT_LOCK (demux);
5789 demux->max_gap_time = g_value_get_uint64 (value);
5790 GST_OBJECT_UNLOCK (demux);
5793 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5799 gst_matroska_demux_get_property (GObject * object,
5800 guint prop_id, GValue * value, GParamSpec * pspec)
5802 GstMatroskaDemux *demux;
5804 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5805 demux = GST_MATROSKA_DEMUX (object);
5808 case ARG_MAX_GAP_TIME:
5809 GST_OBJECT_LOCK (demux);
5810 g_value_set_uint64 (value, demux->max_gap_time);
5811 GST_OBJECT_UNLOCK (demux);
5814 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5820 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5824 /* parser helper separate debug */
5825 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5826 0, "EBML stream helper class");
5828 /* create an elementfactory for the matroska_demux element */
5829 if (!gst_element_register (plugin, "matroskademux",
5830 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))