1 /* GStreamer Matroska muxer/demuxer
2 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3 * (c) 2006 Tim-Philipp Müller <tim centricular net>
4 * (c) 2008 Sebastian Dröge <slomo@circular-chaos.org>
5 * (c) 2011 Debarshi Ray <rishi@gnu.org>
7 * matroska-demux.c: matroska file/stream demuxer
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
25 /* TODO: check CRC32 if present
26 * TODO: there can be a segment after the first segment. Handle like
27 * chained oggs. Fixes #334082
28 * TODO: Test samples: http://www.matroska.org/samples/matrix/index.html
29 * http://samples.mplayerhq.hu/Matroska/
30 * TODO: check if demuxing is done correct for all codecs according to spec
31 * TODO: seeking with incomplete or without CUE
35 * SECTION:element-matroskademux
37 * matroskademux demuxes a Matroska file into the different contained streams.
40 * <title>Example launch line</title>
42 * gst-launch -v filesrc location=/path/to/mkv ! matroskademux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
43 * ]| This pipeline demuxes a Matroska file and outputs the contained Vorbis audio.
54 #include <glib/gprintf.h>
56 /* For AVI compatibility mode
57 and for fourcc stuff */
58 #include <gst/riff/riff-read.h>
59 #include <gst/riff/riff-ids.h>
60 #include <gst/riff/riff-media.h>
62 #include <gst/audio/audio.h>
63 #include <gst/tag/tag.h>
64 #include <gst/pbutils/pbutils.h>
66 #include "matroska-demux.h"
67 #include "matroska-ids.h"
69 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
70 #define GST_CAT_DEFAULT matroskademux_debug
72 #define DEBUG_ELEMENT_START(demux, ebml, element) \
73 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
74 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
76 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
77 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
78 " finished with '%s'", gst_flow_get_name (ret))
88 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
90 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
93 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
94 "video/x-matroska-3d; audio/webm; video/webm")
97 /* TODO: fill in caps! */
99 static GstStaticPadTemplate audio_src_templ =
100 GST_STATIC_PAD_TEMPLATE ("audio_%u",
103 GST_STATIC_CAPS ("ANY")
106 static GstStaticPadTemplate video_src_templ =
107 GST_STATIC_PAD_TEMPLATE ("video_%u",
110 GST_STATIC_CAPS ("ANY")
113 static GstStaticPadTemplate subtitle_src_templ =
114 GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
117 GST_STATIC_CAPS ("text/x-pango-markup; application/x-ssa; "
118 "application/x-ass;application/x-usf; video/x-dvd-subpicture; "
119 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
122 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
123 guint32 id, guint64 length, guint needed);
125 /* element functions */
126 static void gst_matroska_demux_loop (GstPad * pad);
128 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
130 static gboolean gst_matroska_demux_element_query (GstElement * element,
134 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad,
136 static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
137 GstObject * parent, GstPadMode mode, gboolean active);
139 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
140 GstPad * pad, GstEvent * event);
141 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
142 GstObject * parent, GstEvent * event);
143 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
144 GstObject * parent, GstQuery * query);
146 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
147 GstObject * parent, GstEvent * event);
148 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
149 GstObject * object, GstBuffer * buffer);
151 static GstStateChangeReturn
152 gst_matroska_demux_change_state (GstElement * element,
153 GstStateChange transition);
156 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
157 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
161 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
162 * videocontext, const gchar * codec_id, guint8 * data, guint size,
163 gchar ** codec_name, guint32 * riff_fourcc);
164 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
165 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
166 gchar ** codec_name, guint16 * riff_audio_fmt);
168 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
169 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
172 static void gst_matroska_demux_reset (GstElement * element);
173 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
176 /* gobject functions */
177 static void gst_matroska_demux_set_property (GObject * object,
178 guint prop_id, const GValue * value, GParamSpec * pspec);
179 static void gst_matroska_demux_get_property (GObject * object,
180 guint prop_id, GValue * value, GParamSpec * pspec);
182 GType gst_matroska_demux_get_type (void);
183 #define parent_class gst_matroska_demux_parent_class
184 G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
187 gst_matroska_demux_finalize (GObject * object)
189 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
191 if (demux->common.src) {
192 g_ptr_array_free (demux->common.src, TRUE);
193 demux->common.src = NULL;
196 if (demux->common.global_tags) {
197 gst_tag_list_free (demux->common.global_tags);
198 demux->common.global_tags = NULL;
201 g_object_unref (demux->common.adapter);
203 G_OBJECT_CLASS (parent_class)->finalize (object);
207 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
209 GObjectClass *gobject_class = (GObjectClass *) klass;
210 GstElementClass *gstelement_class = (GstElementClass *) klass;
212 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
215 gobject_class->finalize = gst_matroska_demux_finalize;
217 gobject_class->get_property = gst_matroska_demux_get_property;
218 gobject_class->set_property = gst_matroska_demux_set_property;
220 g_object_class_install_property (gobject_class, ARG_MAX_GAP_TIME,
221 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
222 "The demuxer sends out segment events for skipping "
223 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
224 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
226 gstelement_class->change_state =
227 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
228 gstelement_class->send_event =
229 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
230 gstelement_class->query =
231 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
233 gstelement_class->set_index =
234 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
235 gstelement_class->get_index =
236 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
239 gst_element_class_add_pad_template (gstelement_class,
240 gst_static_pad_template_get (&video_src_templ));
241 gst_element_class_add_pad_template (gstelement_class,
242 gst_static_pad_template_get (&audio_src_templ));
243 gst_element_class_add_pad_template (gstelement_class,
244 gst_static_pad_template_get (&subtitle_src_templ));
245 gst_element_class_add_pad_template (gstelement_class,
246 gst_static_pad_template_get (&sink_templ));
248 gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
250 "Demuxes Matroska/WebM streams into video/audio/subtitles",
251 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
255 gst_matroska_demux_init (GstMatroskaDemux * demux)
257 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
259 gst_pad_set_activate_function (demux->common.sinkpad,
260 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
261 gst_pad_set_activatemode_function (demux->common.sinkpad,
262 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
263 gst_pad_set_chain_function (demux->common.sinkpad,
264 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
265 gst_pad_set_event_function (demux->common.sinkpad,
266 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
267 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
269 /* initial stream no. */
270 demux->common.src = NULL;
272 demux->common.writing_app = NULL;
273 demux->common.muxing_app = NULL;
274 demux->common.index = NULL;
275 demux->common.global_tags = NULL;
277 demux->common.adapter = gst_adapter_new ();
279 /* property defaults */
280 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
282 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
285 gst_matroska_demux_reset (GST_ELEMENT (demux));
289 gst_matroska_track_free (GstMatroskaTrackContext * track)
291 g_free (track->codec_id);
292 g_free (track->codec_name);
293 g_free (track->name);
294 g_free (track->language);
295 g_free (track->codec_priv);
296 g_free (track->codec_state);
298 if (track->encodings != NULL) {
301 for (i = 0; i < track->encodings->len; ++i) {
302 GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
303 GstMatroskaTrackEncoding,
306 g_free (enc->comp_settings);
308 g_array_free (track->encodings, TRUE);
311 if (track->pending_tags)
312 gst_tag_list_free (track->pending_tags);
314 if (track->index_table)
315 g_array_free (track->index_table, TRUE);
321 * Returns the aggregated GstFlowReturn.
324 gst_matroska_demux_combine_flows (GstMatroskaDemux * demux,
325 GstMatroskaTrackContext * track, GstFlowReturn ret)
329 /* store the value */
330 track->last_flow = ret;
332 /* any other error that is not-linked can be returned right away */
333 if (ret != GST_FLOW_NOT_LINKED)
336 /* only return NOT_LINKED if all other pads returned NOT_LINKED */
337 g_assert (demux->common.src->len == demux->common.num_streams);
338 for (i = 0; i < demux->common.src->len; i++) {
339 GstMatroskaTrackContext *ostream = g_ptr_array_index (demux->common.src,
345 ret = ostream->last_flow;
346 /* some other return value (must be SUCCESS but we can return
347 * other values as well) */
348 if (ret != GST_FLOW_NOT_LINKED)
351 /* if we get here, all other pads were unlinked and we return
354 GST_LOG_OBJECT (demux, "combined return %s", gst_flow_get_name (ret));
359 gst_matroska_demux_free_parsed_el (gpointer mem, gpointer user_data)
361 g_slice_free (guint64, mem);
365 gst_matroska_demux_reset (GstElement * element)
367 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
370 GST_DEBUG_OBJECT (demux, "Resetting state");
373 demux->common.state = GST_MATROSKA_READ_STATE_START;
375 /* clean up existing streams */
376 if (demux->common.src) {
377 g_assert (demux->common.src->len == demux->common.num_streams);
378 for (i = 0; i < demux->common.src->len; i++) {
379 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
382 if (context->pad != NULL)
383 gst_element_remove_pad (GST_ELEMENT (demux), context->pad);
385 gst_caps_replace (&context->caps, NULL);
386 gst_matroska_track_free (context);
388 g_ptr_array_free (demux->common.src, TRUE);
390 demux->common.src = g_ptr_array_new ();
392 demux->common.num_streams = 0;
393 demux->num_a_streams = 0;
394 demux->num_t_streams = 0;
395 demux->num_v_streams = 0;
397 /* reset media info */
398 g_free (demux->common.writing_app);
399 demux->common.writing_app = NULL;
400 g_free (demux->common.muxing_app);
401 demux->common.muxing_app = NULL;
404 if (demux->common.index) {
405 g_array_free (demux->common.index, TRUE);
406 demux->common.index = NULL;
409 if (demux->clusters) {
410 g_array_free (demux->clusters, TRUE);
411 demux->clusters = NULL;
416 demux->common.time_scale = 1000000;
417 demux->common.created = G_MININT64;
419 demux->common.index_parsed = FALSE;
420 demux->tracks_parsed = FALSE;
421 demux->common.segmentinfo_parsed = FALSE;
422 demux->common.attachments_parsed = FALSE;
423 demux->common.chapters_parsed = FALSE;
425 g_list_foreach (demux->common.tags_parsed,
426 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
427 g_list_free (demux->common.tags_parsed);
428 demux->common.tags_parsed = NULL;
430 g_list_foreach (demux->seek_parsed,
431 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
432 g_list_free (demux->seek_parsed);
433 demux->seek_parsed = NULL;
435 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
436 demux->last_stop_end = GST_CLOCK_TIME_NONE;
437 demux->seek_block = 0;
438 demux->stream_start_time = GST_CLOCK_TIME_NONE;
440 demux->common.offset = 0;
441 demux->cluster_time = GST_CLOCK_TIME_NONE;
442 demux->cluster_offset = 0;
443 demux->next_cluster_offset = 0;
444 demux->index_offset = 0;
445 demux->seekable = FALSE;
446 demux->need_segment = FALSE;
447 demux->building_index = FALSE;
448 if (demux->seek_event) {
449 gst_event_unref (demux->seek_event);
450 demux->seek_event = NULL;
453 demux->seek_index = NULL;
454 demux->seek_entry = 0;
456 if (demux->new_segment) {
457 gst_event_unref (demux->new_segment);
458 demux->new_segment = NULL;
461 if (demux->common.element_index) {
462 gst_object_unref (demux->common.element_index);
463 demux->common.element_index = NULL;
465 demux->common.element_index_writer_id = -1;
468 if (demux->common.global_tags) {
469 gst_tag_list_free (demux->common.global_tags);
471 demux->common.global_tags = gst_tag_list_new_empty ();
473 if (demux->common.cached_buffer) {
474 if (demux->common.cached_data) {
475 gst_buffer_unmap (demux->common.cached_buffer, &demux->common.cached_map);
476 demux->common.cached_data = NULL;
478 gst_buffer_unref (demux->common.cached_buffer);
479 demux->common.cached_buffer = NULL;
482 /* free chapters TOC if any */
483 if (demux->common.toc) {
484 gst_toc_unref (demux->common.toc);
485 demux->common.toc = NULL;
488 demux->invalid_duration = FALSE;
492 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
498 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
500 GST_DEBUG ("decoding buffer %p", buf);
502 gst_buffer_map (buf, &map, GST_MAP_READ);
506 g_return_val_if_fail (size > 0, buf);
508 if (gst_matroska_decode_data (context->encodings, &data, &size,
509 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
510 gst_buffer_unmap (buf, &map);
511 gst_buffer_unref (buf);
512 return gst_buffer_new_wrapped (data, size);
514 GST_DEBUG ("decode data failed");
515 gst_buffer_unmap (buf, &map);
516 gst_buffer_unref (buf);
522 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
524 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
525 GstMatroskaTrackContext *context;
526 GstPadTemplate *templ = NULL;
527 GstCaps *caps = NULL;
528 gchar *padname = NULL;
530 guint32 id, riff_fourcc = 0;
531 guint16 riff_audio_fmt = 0;
532 GstTagList *list = NULL;
535 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
537 /* start with the master */
538 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
539 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
543 /* allocate generic... if we know the type, we'll g_renew()
544 * with the precise type */
545 context = g_new0 (GstMatroskaTrackContext, 1);
546 g_ptr_array_add (demux->common.src, context);
547 context->index = demux->common.num_streams;
548 context->index_writer_id = -1;
549 context->type = 0; /* no type yet */
550 context->default_duration = 0;
552 context->set_discont = TRUE;
553 context->timecodescale = 1.0;
555 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
556 GST_MATROSKA_TRACK_LACING;
557 context->last_flow = GST_FLOW_OK;
558 context->to_offset = G_MAXINT64;
559 context->alignment = 1;
560 demux->common.num_streams++;
561 g_assert (demux->common.src->len == demux->common.num_streams);
563 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
565 /* try reading the trackentry headers */
566 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
567 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
571 /* track number (unique stream ID) */
572 case GST_MATROSKA_ID_TRACKNUMBER:{
575 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
579 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
580 ret = GST_FLOW_ERROR;
582 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
584 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
585 " is not unique", num);
586 ret = GST_FLOW_ERROR;
590 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
594 /* track UID (unique identifier) */
595 case GST_MATROSKA_ID_TRACKUID:{
598 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
602 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
603 ret = GST_FLOW_ERROR;
607 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
612 /* track type (video, audio, combined, subtitle, etc.) */
613 case GST_MATROSKA_ID_TRACKTYPE:{
616 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
620 if (context->type != 0 && context->type != track_type) {
621 GST_WARNING_OBJECT (demux,
622 "More than one tracktype defined in a TrackEntry - skipping");
624 } else if (track_type < 1 || track_type > 254) {
625 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
630 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
632 /* ok, so we're actually going to reallocate this thing */
633 switch (track_type) {
634 case GST_MATROSKA_TRACK_TYPE_VIDEO:
635 gst_matroska_track_init_video_context (&context);
637 case GST_MATROSKA_TRACK_TYPE_AUDIO:
638 gst_matroska_track_init_audio_context (&context);
640 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
641 gst_matroska_track_init_subtitle_context (&context);
643 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
644 case GST_MATROSKA_TRACK_TYPE_LOGO:
645 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
646 case GST_MATROSKA_TRACK_TYPE_CONTROL:
648 GST_WARNING_OBJECT (demux,
649 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
654 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
659 /* tracktype specific stuff for video */
660 case GST_MATROSKA_ID_TRACKVIDEO:{
661 GstMatroskaTrackVideoContext *videocontext;
663 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
665 if (!gst_matroska_track_init_video_context (&context)) {
666 GST_WARNING_OBJECT (demux,
667 "TrackVideo element in non-video track - ignoring track");
668 ret = GST_FLOW_ERROR;
670 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
673 videocontext = (GstMatroskaTrackVideoContext *) context;
674 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
677 while (ret == GST_FLOW_OK &&
678 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
679 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
683 /* Should be one level up but some broken muxers write it here. */
684 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
687 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
691 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
695 GST_DEBUG_OBJECT (demux,
696 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
697 context->default_duration = num;
701 /* video framerate */
702 /* NOTE: This one is here only for backward compatibility.
703 * Use _TRACKDEFAULDURATION one level up. */
704 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
707 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
711 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
715 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
716 if (context->default_duration == 0)
717 context->default_duration =
718 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
719 videocontext->default_fps = num;
723 /* width of the size to display the video at */
724 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
727 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
731 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
735 GST_DEBUG_OBJECT (demux,
736 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
737 videocontext->display_width = num;
741 /* height of the size to display the video at */
742 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
745 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
749 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
753 GST_DEBUG_OBJECT (demux,
754 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
755 videocontext->display_height = num;
759 /* width of the video in the file */
760 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
763 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
767 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
771 GST_DEBUG_OBJECT (demux,
772 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
773 videocontext->pixel_width = num;
777 /* height of the video in the file */
778 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
781 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
785 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
789 GST_DEBUG_OBJECT (demux,
790 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
791 videocontext->pixel_height = num;
795 /* whether the video is interlaced */
796 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
799 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
803 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
805 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
806 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
807 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
812 /* aspect ratio behaviour */
813 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
816 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
819 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
820 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
821 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
822 GST_WARNING_OBJECT (demux,
823 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
826 GST_DEBUG_OBJECT (demux,
827 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
828 videocontext->asr_mode = num;
832 /* colourspace (only matters for raw video) fourcc */
833 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
838 gst_ebml_read_binary (ebml, &id, &data,
839 &datalen)) != GST_FLOW_OK)
844 GST_WARNING_OBJECT (demux,
845 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
850 memcpy (&videocontext->fourcc, data, 4);
851 GST_DEBUG_OBJECT (demux,
852 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
853 GST_FOURCC_ARGS (videocontext->fourcc));
859 GST_WARNING_OBJECT (demux,
860 "Unknown TrackVideo subelement 0x%x - ignoring", id);
862 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
863 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
864 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
865 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
866 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
867 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
868 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
869 ret = gst_ebml_read_skip (ebml);
874 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
878 /* tracktype specific stuff for audio */
879 case GST_MATROSKA_ID_TRACKAUDIO:{
880 GstMatroskaTrackAudioContext *audiocontext;
882 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
884 if (!gst_matroska_track_init_audio_context (&context)) {
885 GST_WARNING_OBJECT (demux,
886 "TrackAudio element in non-audio track - ignoring track");
887 ret = GST_FLOW_ERROR;
891 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
894 audiocontext = (GstMatroskaTrackAudioContext *) context;
895 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
898 while (ret == GST_FLOW_OK &&
899 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
900 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
905 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
908 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
913 GST_WARNING_OBJECT (demux,
914 "Invalid TrackAudioSamplingFrequency %lf", num);
918 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
919 audiocontext->samplerate = num;
924 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
927 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
931 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
935 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
937 audiocontext->bitdepth = num;
942 case GST_MATROSKA_ID_AUDIOCHANNELS:{
945 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
949 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
953 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
955 audiocontext->channels = num;
960 GST_WARNING_OBJECT (demux,
961 "Unknown TrackAudio subelement 0x%x - ignoring", id);
963 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
964 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
965 ret = gst_ebml_read_skip (ebml);
970 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
975 /* codec identifier */
976 case GST_MATROSKA_ID_CODECID:{
979 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
982 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
983 context->codec_id = text;
987 /* codec private data */
988 case GST_MATROSKA_ID_CODECPRIVATE:{
993 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
996 context->codec_priv = data;
997 context->codec_priv_size = size;
999 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1004 /* name of the codec */
1005 case GST_MATROSKA_ID_CODECNAME:{
1008 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1011 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1012 context->codec_name = text;
1016 /* name of this track */
1017 case GST_MATROSKA_ID_TRACKNAME:{
1020 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1023 context->name = text;
1024 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1028 /* language (matters for audio/subtitles, mostly) */
1029 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1032 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1036 context->language = text;
1039 if (strlen (context->language) >= 4 && context->language[3] == '-')
1040 context->language[3] = '\0';
1042 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1043 GST_STR_NULL (context->language));
1047 /* whether this is actually used */
1048 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1051 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1055 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1057 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1059 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1060 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1064 /* whether it's the default for this track type */
1065 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1068 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1072 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1074 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1076 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1077 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1081 /* whether the track must be used during playback */
1082 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1085 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1089 context->flags |= GST_MATROSKA_TRACK_FORCED;
1091 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1093 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1094 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1098 /* lacing (like MPEG, where blocks don't end/start on frame
1100 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1103 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1107 context->flags |= GST_MATROSKA_TRACK_LACING;
1109 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1111 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1112 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1116 /* default length (in time) of one data block in this track */
1117 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1120 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1125 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1129 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1131 context->default_duration = num;
1135 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1136 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1141 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1144 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1148 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1152 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1153 context->timecodescale = num;
1158 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1161 /* we ignore these because they're nothing useful (i.e. crap)
1162 * or simply not implemented yet. */
1163 case GST_MATROSKA_ID_TRACKMINCACHE:
1164 case GST_MATROSKA_ID_TRACKMAXCACHE:
1165 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1166 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1167 case GST_MATROSKA_ID_TRACKOVERLAY:
1168 case GST_MATROSKA_ID_TRACKTRANSLATE:
1169 case GST_MATROSKA_ID_TRACKOFFSET:
1170 case GST_MATROSKA_ID_CODECSETTINGS:
1171 case GST_MATROSKA_ID_CODECINFOURL:
1172 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1173 case GST_MATROSKA_ID_CODECDECODEALL:
1174 ret = gst_ebml_read_skip (ebml);
1179 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1181 /* Decode codec private data if necessary */
1182 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1183 && context->codec_priv_size > 0) {
1184 if (!gst_matroska_decode_data (context->encodings,
1185 &context->codec_priv, &context->codec_priv_size,
1186 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1187 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1188 ret = GST_FLOW_ERROR;
1192 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1193 && ret != GST_FLOW_EOS)) {
1194 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1195 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1197 demux->common.num_streams--;
1198 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1199 g_assert (demux->common.src->len == demux->common.num_streams);
1201 gst_matroska_track_free (context);
1207 /* now create the GStreamer connectivity */
1208 switch (context->type) {
1209 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1210 GstMatroskaTrackVideoContext *videocontext =
1211 (GstMatroskaTrackVideoContext *) context;
1213 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1214 templ = gst_element_class_get_pad_template (klass, "video_%u");
1215 caps = gst_matroska_demux_video_caps (videocontext,
1216 context->codec_id, context->codec_priv,
1217 context->codec_priv_size, &codec, &riff_fourcc);
1220 list = gst_tag_list_new (GST_TAG_VIDEO_CODEC, codec, NULL);
1226 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1227 GstMatroskaTrackAudioContext *audiocontext =
1228 (GstMatroskaTrackAudioContext *) context;
1230 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1231 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1232 caps = gst_matroska_demux_audio_caps (audiocontext,
1233 context->codec_id, context->codec_priv, context->codec_priv_size,
1234 &codec, &riff_audio_fmt);
1237 list = gst_tag_list_new (GST_TAG_AUDIO_CODEC, codec, NULL);
1243 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1244 GstMatroskaTrackSubtitleContext *subtitlecontext =
1245 (GstMatroskaTrackSubtitleContext *) context;
1247 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1248 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1249 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1250 context->codec_id, context->codec_priv, context->codec_priv_size);
1254 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1255 case GST_MATROSKA_TRACK_TYPE_LOGO:
1256 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1257 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1259 /* we should already have quit by now */
1260 g_assert_not_reached ();
1263 if ((context->language == NULL || *context->language == '\0') &&
1264 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1265 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1266 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1267 context->language = g_strdup ("eng");
1270 if (context->language) {
1274 list = gst_tag_list_new_empty ();
1276 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1277 lang = gst_tag_get_language_code (context->language);
1278 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1279 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1283 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1284 "codec_id='%s'", context->codec_id);
1285 switch (context->type) {
1286 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1287 caps = gst_caps_new_empty_simple ("video/x-unknown");
1289 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1290 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1292 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1293 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1295 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1297 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1300 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1303 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1304 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1305 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1306 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1307 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1308 GST_FOURCC_ARGS (riff_fourcc));
1309 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1314 /* the pad in here */
1315 context->pad = gst_pad_new_from_template (templ, padname);
1316 context->caps = caps;
1318 gst_pad_set_event_function (context->pad,
1319 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1320 gst_pad_set_query_function (context->pad,
1321 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1323 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1326 context->pending_tags = list;
1328 gst_pad_set_element_private (context->pad, context);
1330 gst_pad_use_fixed_caps (context->pad);
1331 gst_pad_set_active (context->pad, TRUE);
1332 gst_pad_push_event (context->pad, gst_event_new_stream_start ());
1333 gst_pad_set_caps (context->pad, context->caps);
1334 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1343 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1346 gboolean res = FALSE;
1347 GstMatroskaTrackContext *context = NULL;
1350 context = gst_pad_get_element_private (pad);
1353 switch (GST_QUERY_TYPE (query)) {
1354 case GST_QUERY_POSITION:
1358 gst_query_parse_position (query, &format, NULL);
1361 if (format == GST_FORMAT_TIME) {
1362 GST_OBJECT_LOCK (demux);
1364 gst_query_set_position (query, GST_FORMAT_TIME,
1365 MAX (context->pos, demux->stream_start_time) -
1366 demux->stream_start_time);
1368 gst_query_set_position (query, GST_FORMAT_TIME,
1369 MAX (demux->common.segment.position, demux->stream_start_time) -
1370 demux->stream_start_time);
1371 GST_OBJECT_UNLOCK (demux);
1372 } else if (format == GST_FORMAT_DEFAULT && context
1373 && context->default_duration) {
1374 GST_OBJECT_LOCK (demux);
1375 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1376 context->pos / context->default_duration);
1377 GST_OBJECT_UNLOCK (demux);
1379 GST_DEBUG_OBJECT (demux,
1380 "only position query in TIME and DEFAULT format is supported");
1386 case GST_QUERY_DURATION:
1390 gst_query_parse_duration (query, &format, NULL);
1393 if (format == GST_FORMAT_TIME) {
1394 GST_OBJECT_LOCK (demux);
1395 gst_query_set_duration (query, GST_FORMAT_TIME,
1396 demux->common.segment.duration);
1397 GST_OBJECT_UNLOCK (demux);
1398 } else if (format == GST_FORMAT_DEFAULT && context
1399 && context->default_duration) {
1400 GST_OBJECT_LOCK (demux);
1401 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1402 demux->common.segment.duration / context->default_duration);
1403 GST_OBJECT_UNLOCK (demux);
1405 GST_DEBUG_OBJECT (demux,
1406 "only duration query in TIME and DEFAULT format is supported");
1412 case GST_QUERY_SEEKING:
1416 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1417 GST_OBJECT_LOCK (demux);
1418 if (fmt == GST_FORMAT_TIME) {
1421 if (demux->streaming) {
1422 /* assuming we'll be able to get an index ... */
1423 seekable = demux->seekable;
1428 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1429 0, demux->common.segment.duration);
1432 GST_OBJECT_UNLOCK (demux);
1436 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1444 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1446 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1450 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1453 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1455 return gst_matroska_demux_query (demux, pad, query);
1458 /* returns FALSE if there are no pads to deliver event to,
1459 * otherwise TRUE (whatever the outcome of event sending),
1460 * takes ownership of the passed event! */
1462 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1464 gboolean is_segment;
1465 gboolean ret = FALSE;
1468 g_return_val_if_fail (event != NULL, FALSE);
1470 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1471 GST_EVENT_TYPE_NAME (event));
1473 is_segment = (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
1475 g_assert (demux->common.src->len == demux->common.num_streams);
1476 for (i = 0; i < demux->common.src->len; i++) {
1477 GstMatroskaTrackContext *stream;
1479 stream = g_ptr_array_index (demux->common.src, i);
1480 gst_event_ref (event);
1481 gst_pad_push_event (stream->pad, event);
1484 /* FIXME: send global tags before stream tags */
1485 if (G_UNLIKELY (is_segment && stream->pending_tags != NULL)) {
1486 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
1487 GST_PTR_FORMAT, stream->pending_tags,
1488 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
1489 gst_pad_push_event (stream->pad,
1490 gst_event_new_tag ("GstDemuxer", stream->pending_tags));
1491 stream->pending_tags = NULL;
1495 if (G_UNLIKELY (is_segment && demux->common.global_tags != NULL)) {
1496 GstEvent *tag_event;
1497 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1498 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1499 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1500 demux->common.global_tags, demux->common.global_tags);
1502 tag_event = gst_event_new_tag ("GstDemuxer", demux->common.global_tags);
1504 for (i = 0; i < demux->common.src->len; i++) {
1505 GstMatroskaTrackContext *stream;
1507 stream = g_ptr_array_index (demux->common.src, i);
1508 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1511 gst_event_unref (tag_event);
1512 demux->common.global_tags = NULL;
1515 gst_event_unref (event);
1520 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1522 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1525 g_return_val_if_fail (event != NULL, FALSE);
1527 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1528 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1530 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1531 GST_EVENT_TYPE_NAME (event));
1534 gst_event_unref (event);
1539 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1540 GstMatroskaIndex * entry, gboolean reset)
1544 GST_OBJECT_LOCK (demux);
1546 /* seek (relative to matroska segment) */
1547 /* position might be invalid; will error when streaming resumes ... */
1548 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1550 GST_DEBUG_OBJECT (demux, "Seeked to offset %" G_GUINT64_FORMAT ", block %d, "
1551 "time %" GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1552 entry->block, GST_TIME_ARGS (entry->time));
1554 /* update the time */
1555 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1556 demux->common.segment.position = entry->time;
1557 demux->seek_block = entry->block;
1558 demux->seek_first = TRUE;
1559 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1561 for (i = 0; i < demux->common.src->len; i++) {
1562 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1565 stream->to_offset = G_MAXINT64;
1567 if (stream->from_offset != -1)
1568 stream->to_offset = stream->from_offset;
1570 stream->from_offset = -1;
1573 GST_OBJECT_UNLOCK (demux);
1579 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1589 /* searches for a cluster start from @pos,
1590 * return GST_FLOW_OK and cluster position in @pos if found */
1591 static GstFlowReturn
1592 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1594 gint64 newpos = *pos;
1596 GstFlowReturn ret = GST_FLOW_OK;
1597 const guint chunk = 64 * 1024;
1598 GstBuffer *buf = NULL;
1600 gpointer data = NULL;
1606 orig_offset = demux->common.offset;
1608 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1611 if (demux->clusters) {
1614 cpos = gst_util_array_binary_search (demux->clusters->data,
1615 demux->clusters->len, sizeof (gint64),
1616 (GCompareDataFunc) gst_matroska_cluster_compare,
1617 GST_SEARCH_MODE_AFTER, pos, NULL);
1620 GST_DEBUG_OBJECT (demux,
1621 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1622 demux->common.offset = *cpos;
1623 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1624 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1625 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1632 /* read in at newpos and scan for ebml cluster id */
1634 GstByteReader reader;
1638 gst_buffer_unmap (buf, &map);
1639 gst_buffer_unref (buf);
1642 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1643 if (ret != GST_FLOW_OK)
1645 GST_DEBUG_OBJECT (demux,
1646 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1647 gst_buffer_get_size (buf), newpos);
1648 gst_buffer_map (buf, &map, GST_MAP_READ);
1651 gst_byte_reader_init (&reader, data, size);
1653 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1654 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1655 if (cluster_pos >= 0) {
1656 newpos += cluster_pos;
1657 /* prepare resuming at next byte */
1658 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1659 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1662 GST_DEBUG_OBJECT (demux,
1663 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1664 /* extra checks whether we really sync'ed to a cluster:
1665 * - either it is the first and only cluster
1666 * - either there is a cluster after this one
1667 * - either cluster length is undefined
1669 /* ok if first cluster (there may not a subsequent one) */
1670 if (newpos == demux->first_cluster_offset) {
1671 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1674 demux->common.offset = newpos;
1675 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1676 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1677 if (ret != GST_FLOW_OK) {
1678 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1681 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1682 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1684 /* ok if undefined length or first cluster */
1685 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1686 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1690 demux->common.offset += length + needed;
1691 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1692 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1693 if (ret != GST_FLOW_OK)
1695 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1696 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1697 if (id == GST_MATROSKA_ID_CLUSTER)
1699 /* not ok, resume */
1702 /* partial cluster id may have been in tail of buffer */
1703 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1708 gst_buffer_unmap (buf, &map);
1709 gst_buffer_unref (buf);
1714 demux->common.offset = orig_offset;
1719 /* bisect and scan through file for cluster starting before @time,
1720 * returns fake index entry with corresponding info on cluster */
1721 static GstMatroskaIndex *
1722 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1724 GstMatroskaIndex *entry = NULL;
1725 GstMatroskaReadState current_state;
1726 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1727 gint64 opos, newpos, startpos = 0, current_offset;
1728 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1729 const guint chunk = 64 * 1024;
1735 /* (under)estimate new position, resync using cluster ebml id,
1736 * and scan forward to appropriate cluster
1737 * (and re-estimate if need to go backward) */
1739 prev_cluster_time = GST_CLOCK_TIME_NONE;
1741 /* store some current state */
1742 current_state = demux->common.state;
1743 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1745 current_cluster_offset = demux->cluster_offset;
1746 current_cluster_time = demux->cluster_time;
1747 current_offset = demux->common.offset;
1749 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1751 /* estimate using start and current position */
1752 GST_OBJECT_LOCK (demux);
1753 opos = demux->common.offset - demux->common.ebml_segment_start;
1754 otime = demux->common.segment.position;
1755 GST_OBJECT_UNLOCK (demux);
1758 time = MAX (time, demux->stream_start_time);
1760 /* avoid division by zero in first estimation below */
1761 if (otime <= demux->stream_start_time)
1765 GST_LOG_OBJECT (demux,
1766 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1767 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1768 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1769 GST_TIME_ARGS (otime - demux->stream_start_time),
1770 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1772 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1773 time - demux->stream_start_time,
1774 otime - demux->stream_start_time) - chunk;
1777 /* favour undershoot */
1778 newpos = newpos * 90 / 100;
1779 newpos += demux->common.ebml_segment_start;
1781 GST_DEBUG_OBJECT (demux,
1782 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1783 GST_TIME_ARGS (time), newpos);
1785 /* and at least start scanning before previous scan start to avoid looping */
1786 startpos = startpos * 90 / 100;
1787 if (startpos && startpos < newpos)
1790 /* read in at newpos and scan for ebml cluster id */
1794 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1795 if (ret == GST_FLOW_EOS) {
1796 /* heuristic HACK */
1797 newpos = startpos * 80 / 100;
1798 GST_DEBUG_OBJECT (demux, "EOS; "
1799 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1800 GST_TIME_ARGS (time), newpos);
1803 } else if (ret != GST_FLOW_OK) {
1810 /* then start scanning and parsing for cluster time,
1811 * re-estimate if overshoot, otherwise next cluster and so on */
1812 demux->common.offset = newpos;
1813 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1815 guint64 cluster_size = 0;
1817 /* peek and parse some elements */
1818 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1819 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1820 if (ret != GST_FLOW_OK)
1822 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1823 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1825 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1826 if (ret != GST_FLOW_OK)
1829 if (id == GST_MATROSKA_ID_CLUSTER) {
1830 cluster_time = GST_CLOCK_TIME_NONE;
1831 if (length == G_MAXUINT64)
1834 cluster_size = length + needed;
1836 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1837 cluster_time == GST_CLOCK_TIME_NONE) {
1838 cluster_time = demux->cluster_time * demux->common.time_scale;
1839 cluster_offset = demux->cluster_offset;
1840 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1841 " with time %" GST_TIME_FORMAT, cluster_offset,
1842 GST_TIME_ARGS (cluster_time));
1843 if (cluster_time > time) {
1844 GST_DEBUG_OBJECT (demux, "overshot target");
1845 /* cluster overshoots */
1846 if (cluster_offset == demux->first_cluster_offset) {
1847 /* but no prev one */
1848 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1849 prev_cluster_time = cluster_time;
1850 prev_cluster_offset = cluster_offset;
1853 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1854 /* prev cluster did not overshoot, so prev cluster is target */
1857 /* re-estimate using this new position info */
1858 opos = cluster_offset;
1859 otime = cluster_time;
1863 /* cluster undershoots, goto next one */
1864 prev_cluster_time = cluster_time;
1865 prev_cluster_offset = cluster_offset;
1866 /* skip cluster if length is defined,
1867 * otherwise will be skippingly parsed into */
1869 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1870 demux->common.offset = cluster_offset + cluster_size;
1871 demux->cluster_time = GST_CLOCK_TIME_NONE;
1873 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1880 if (ret == GST_FLOW_EOS) {
1881 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1887 entry = g_new0 (GstMatroskaIndex, 1);
1888 entry->time = prev_cluster_time;
1889 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1890 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1891 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1895 /* restore some state */
1896 demux->cluster_offset = current_cluster_offset;
1897 demux->cluster_time = current_cluster_time;
1898 demux->common.offset = current_offset;
1899 demux->common.state = current_state;
1905 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1906 GstPad * pad, GstEvent * event)
1908 GstMatroskaIndex *entry = NULL;
1909 GstMatroskaIndex scan_entry;
1911 GstSeekType cur_type, stop_type;
1913 gboolean flush, keyunit, before, after, snap_next;
1916 GstMatroskaTrackContext *track = NULL;
1917 GstSegment seeksegment = { 0, };
1918 gboolean update = TRUE;
1919 gboolean pad_locked = FALSE;
1922 track = gst_pad_get_element_private (pad);
1924 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1927 /* we can only seek on time */
1928 if (format != GST_FORMAT_TIME) {
1929 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1933 /* copy segment, we need this because we still need the old
1934 * segment when we close the current segment. */
1935 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1937 /* pull mode without index means that the actual duration is not known,
1938 * we might be playing a file that's still being recorded
1939 * so, invalidate our current duration, which is only a moving target,
1940 * and should not be used to clamp anything */
1941 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
1942 seeksegment.duration = GST_CLOCK_TIME_NONE;
1946 GST_DEBUG_OBJECT (demux, "configuring seek");
1947 gst_segment_do_seek (&seeksegment, rate, format, flags,
1948 cur_type, cur, stop_type, stop, &update);
1949 /* compensate for clip start time */
1950 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1951 seeksegment.position += demux->stream_start_time;
1952 seeksegment.start += demux->stream_start_time;
1953 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1954 seeksegment.stop += demux->stream_start_time;
1955 /* note that time should stay at indicated position */
1959 /* restore segment duration (if any effect),
1960 * would be determined again when parsing, but anyway ... */
1961 seeksegment.duration = demux->common.segment.duration;
1963 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
1964 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
1965 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
1966 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
1968 /* always do full update if flushing,
1969 * otherwise problems might arise downstream with missing keyframes etc */
1970 update = update || flush;
1972 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1975 /* only have to update some segment,
1976 * but also still have to honour flush and so on */
1977 GST_DEBUG_OBJECT (demux, "... no update");
1978 /* bad goto, bad ... */
1982 /* check sanity before we start flushing and all that */
1983 snap_next = after && !before;
1984 if (seeksegment.rate < 0)
1985 snap_next = !snap_next;
1986 GST_OBJECT_LOCK (demux);
1987 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
1988 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
1989 seeksegment.position, &demux->seek_index, &demux->seek_entry,
1990 snap_next)) == NULL) {
1991 /* pull mode without index can scan later on */
1992 if (demux->streaming) {
1993 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
1994 GST_OBJECT_UNLOCK (demux);
1998 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
1999 GST_OBJECT_UNLOCK (demux);
2001 if (demux->streaming) {
2002 GST_OBJECT_LOCK (demux);
2003 /* now update the real segment info */
2004 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2005 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2006 GST_OBJECT_UNLOCK (demux);
2007 /* need to seek to cluster start to pick up cluster time */
2008 /* upstream takes care of flushing and all that
2009 * ... and segment event handling takes care of the rest */
2010 return perform_seek_to_offset (demux,
2011 entry->pos + demux->common.ebml_segment_start);
2016 GST_DEBUG_OBJECT (demux, "Starting flush");
2017 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_start ());
2018 gst_matroska_demux_send_event (demux, gst_event_new_flush_start ());
2020 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2021 gst_pad_pause_task (demux->common.sinkpad);
2027 /* now grab the stream lock so that streaming cannot continue, for
2028 * non flushing seeks when the element is in PAUSED this could block
2030 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2031 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2034 /* pull mode without index can do some scanning */
2035 if (!demux->streaming && !entry) {
2036 /* need to stop flushing upstream as we need it next */
2038 gst_pad_push_event (demux->common.sinkpad,
2039 gst_event_new_flush_stop (TRUE));
2040 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2041 /* keep local copy */
2043 scan_entry = *entry;
2045 entry = &scan_entry;
2047 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2049 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop (TRUE));
2055 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2056 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2057 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2058 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2059 seeksegment.position = seeksegment.start;
2060 seeksegment.time = seeksegment.start - demux->stream_start_time;
2065 GST_DEBUG_OBJECT (demux, "Stopping flush");
2066 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_stop (TRUE));
2067 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop (TRUE));
2070 GST_OBJECT_LOCK (demux);
2071 /* now update the real segment info */
2072 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2073 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2074 GST_OBJECT_UNLOCK (demux);
2076 /* update some (segment) state */
2077 if (update && !gst_matroska_demux_move_to_entry (demux, entry, TRUE))
2080 /* notify start of new segment */
2081 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2084 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2085 GST_FORMAT_TIME, demux->common.segment.start);
2086 gst_element_post_message (GST_ELEMENT (demux), msg);
2089 GST_OBJECT_LOCK (demux);
2090 if (demux->new_segment)
2091 gst_event_unref (demux->new_segment);
2092 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2093 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2094 GST_OBJECT_UNLOCK (demux);
2096 /* restart our task since it might have been stopped when we did the
2098 gst_pad_start_task (demux->common.sinkpad,
2099 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2101 /* streaming can continue now */
2103 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2111 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2113 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2119 * Handle whether we can perform the seek event or if we have to let the chain
2120 * function handle seeks to build the seek indexes first.
2123 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2127 GstSeekType cur_type, stop_type;
2132 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2137 /* we can only seek on time */
2138 if (format != GST_FORMAT_TIME) {
2139 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2143 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2144 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2148 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2149 GST_DEBUG_OBJECT (demux,
2150 "Non-flushing seek not supported in streaming mode");
2154 if (flags & GST_SEEK_FLAG_SEGMENT) {
2155 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2159 /* check for having parsed index already */
2160 if (!demux->common.index_parsed) {
2161 gboolean building_index;
2164 if (!demux->index_offset) {
2165 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2169 GST_OBJECT_LOCK (demux);
2170 /* handle the seek event in the chain function */
2171 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2172 /* no more seek can be issued until state reset to _DATA */
2174 /* copy the event */
2175 if (demux->seek_event)
2176 gst_event_unref (demux->seek_event);
2177 demux->seek_event = gst_event_ref (event);
2179 /* set the building_index flag so that only one thread can setup the
2180 * structures for index seeking. */
2181 building_index = demux->building_index;
2182 if (!building_index) {
2183 demux->building_index = TRUE;
2184 offset = demux->index_offset;
2186 GST_OBJECT_UNLOCK (demux);
2188 if (!building_index) {
2189 /* seek to the first subindex or legacy index */
2190 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2191 return perform_seek_to_offset (demux, offset);
2194 /* well, we are handling it already */
2198 /* delegate to tweaked regular seek */
2199 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2203 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2206 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2207 gboolean res = TRUE;
2209 switch (GST_EVENT_TYPE (event)) {
2210 case GST_EVENT_SEEK:
2211 /* no seeking until we are (safely) ready */
2212 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2213 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2216 if (!demux->streaming)
2217 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2219 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2220 gst_event_unref (event);
2225 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2226 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2227 GstMatroskaTrackVideoContext *videocontext =
2228 (GstMatroskaTrackVideoContext *) context;
2230 GstClockTimeDiff diff;
2231 GstClockTime timestamp;
2233 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2235 GST_OBJECT_LOCK (demux);
2236 videocontext->earliest_time = timestamp + diff;
2237 GST_OBJECT_UNLOCK (demux);
2240 gst_event_unref (event);
2244 case GST_EVENT_TOC_SELECT:
2247 GstTocEntry *entry = NULL;
2248 GstEvent *seek_event;
2251 if (!demux->common.toc) {
2252 GST_DEBUG_OBJECT (demux, "no TOC to select");
2255 gst_event_parse_toc_select (event, &uid);
2257 GST_OBJECT_LOCK (demux);
2258 entry = gst_toc_find_entry (demux->common.toc, uid);
2259 if (entry == NULL) {
2260 GST_OBJECT_UNLOCK (demux);
2261 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2264 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2265 GST_OBJECT_UNLOCK (demux);
2266 seek_event = gst_event_new_seek (1.0,
2268 GST_SEEK_FLAG_FLUSH,
2269 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2270 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2271 gst_event_unref (seek_event);
2275 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2279 gst_event_unref (event);
2283 /* events we don't need to handle */
2284 case GST_EVENT_NAVIGATION:
2285 gst_event_unref (event);
2289 case GST_EVENT_LATENCY:
2291 res = gst_pad_push_event (demux->common.sinkpad, event);
2298 static GstFlowReturn
2299 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2301 GstFlowReturn ret = GST_FLOW_EOS;
2302 gboolean done = TRUE;
2305 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2306 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2309 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2311 if (!demux->seek_entry) {
2312 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2316 for (i = 0; i < demux->common.src->len; i++) {
2317 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2319 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2320 ", stream %d at %" GST_TIME_FORMAT,
2321 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2322 GST_TIME_ARGS (stream->from_time));
2323 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2324 if (stream->from_time > demux->common.segment.start) {
2325 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2329 /* nothing pushed for this stream;
2330 * likely seek entry did not start at keyframe, so all was skipped.
2331 * So we need an earlier entry */
2337 GstMatroskaIndex *entry;
2339 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2340 --demux->seek_entry);
2341 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE))
2351 static GstFlowReturn
2352 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2354 GstFlowReturn ret = GST_FLOW_OK;
2357 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2359 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2360 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2364 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2365 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2369 /* one track within the "all-tracks" header */
2370 case GST_MATROSKA_ID_TRACKENTRY:
2371 ret = gst_matroska_demux_add_stream (demux, ebml);
2375 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2380 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2382 demux->tracks_parsed = TRUE;
2388 * Read signed/unsigned "EBML" numbers.
2389 * Return: number of bytes processed.
2393 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2395 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2403 while (read <= 8 && !(total & len_mask)) {
2410 if ((total &= (len_mask - 1)) == len_mask - 1)
2415 if (data[n] == 0xff)
2417 total = (total << 8) | data[n];
2421 if (read == num_ffs && total != 0)
2430 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2435 /* read as unsigned number first */
2436 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2440 if (unum == G_MAXUINT64)
2443 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2449 * Mostly used for subtitles. We add void filler data for each
2450 * lagging stream to make sure we don't deadlock.
2454 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2458 GST_OBJECT_LOCK (demux);
2460 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2461 GST_TIME_ARGS (demux->common.segment.position));
2463 g_assert (demux->common.num_streams == demux->common.src->len);
2464 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2465 GstMatroskaTrackContext *context;
2467 context = g_ptr_array_index (demux->common.src, stream_nr);
2469 GST_LOG_OBJECT (demux,
2470 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2471 GST_TIME_ARGS (context->pos));
2473 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2474 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2478 /* does it lag? 0.5 seconds is a random threshold...
2479 * lag need only be considered if we have advanced into requested segment */
2480 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2481 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2482 demux->common.segment.position > demux->common.segment.start &&
2483 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2486 guint64 start = context->pos;
2487 guint64 stop = demux->common.segment.position - (GST_SECOND / 2);
2489 GST_DEBUG_OBJECT (demux,
2490 "Synchronizing stream %d with other by advancing time from %"
2491 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2492 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2494 context->pos = stop;
2496 event = gst_event_new_gap (start, stop - start);
2497 GST_OBJECT_UNLOCK (demux);
2498 gst_pad_push_event (context->pad, event);
2499 GST_OBJECT_LOCK (demux);
2503 GST_OBJECT_UNLOCK (demux);
2506 static GstFlowReturn
2507 gst_matroska_demux_push_hdr_buf (GstMatroskaDemux * demux,
2508 GstMatroskaTrackContext * stream, guint8 * data, guint len)
2510 GstFlowReturn ret, cret;
2511 GstBuffer *header_buf;
2513 header_buf = gst_buffer_new_wrapped (g_memdup (data, len), len);
2515 if (stream->set_discont) {
2516 GST_BUFFER_FLAG_SET (header_buf, GST_BUFFER_FLAG_DISCONT);
2517 stream->set_discont = FALSE;
2520 ret = gst_pad_push (stream->pad, header_buf);
2523 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
2528 static GstFlowReturn
2529 gst_matroska_demux_push_flac_codec_priv_data (GstMatroskaDemux * demux,
2530 GstMatroskaTrackContext * stream)
2536 GST_LOG_OBJECT (demux, "priv data size = %" G_GSIZE_FORMAT,
2537 stream->codec_priv_size);
2539 pdata = (guint8 *) stream->codec_priv;
2541 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2542 if (stream->codec_priv_size < ((4) + (4 + 34))) {
2543 GST_WARNING_OBJECT (demux, "not enough codec priv data for flac headers");
2544 return GST_FLOW_ERROR;
2547 if (memcmp (pdata, "fLaC", 4) != 0) {
2548 GST_WARNING_OBJECT (demux, "no flac marker at start of stream headers");
2549 return GST_FLOW_ERROR;
2552 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 4);
2553 if (ret != GST_FLOW_OK)
2556 off = 4; /* skip fLaC marker */
2557 while (off < stream->codec_priv_size) {
2558 len = GST_READ_UINT8 (pdata + off + 1) << 16;
2559 len |= GST_READ_UINT8 (pdata + off + 2) << 8;
2560 len |= GST_READ_UINT8 (pdata + off + 3);
2562 GST_DEBUG_OBJECT (demux, "header packet: len=%u bytes, flags=0x%02x",
2563 len, (guint) pdata[off]);
2565 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata + off, len + 4);
2566 if (ret != GST_FLOW_OK)
2574 static GstFlowReturn
2575 gst_matroska_demux_push_speex_codec_priv_data (GstMatroskaDemux * demux,
2576 GstMatroskaTrackContext * stream)
2579 guint8 *pdata = stream->codec_priv;
2581 GST_LOG_OBJECT (demux, "priv data size = %" G_GSIZE_FORMAT,
2582 stream->codec_priv_size);
2584 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2585 if (stream->codec_priv_size < 80) {
2586 GST_WARNING_OBJECT (demux, "not enough codec priv data for speex headers");
2587 return GST_FLOW_ERROR;
2590 if (memcmp (pdata, "Speex ", 8) != 0) {
2591 GST_WARNING_OBJECT (demux, "no Speex marker at start of stream headers");
2592 return GST_FLOW_ERROR;
2595 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 80);
2596 if (ret != GST_FLOW_OK)
2599 if (stream->codec_priv_size == 80)
2602 return gst_matroska_demux_push_hdr_buf (demux, stream, pdata + 80,
2603 stream->codec_priv_size - 80);
2606 static GstFlowReturn
2607 gst_matroska_demux_push_xiph_codec_priv_data (GstMatroskaDemux * demux,
2608 GstMatroskaTrackContext * stream)
2611 guint8 *p = stream->codec_priv;
2612 gint i, offset, num_packets;
2613 guint *length, last;
2615 if (stream->codec_priv == NULL || stream->codec_priv_size == 0) {
2616 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
2617 ("Missing codec private data for xiph headers, broken file"));
2618 return GST_FLOW_ERROR;
2621 /* start of the stream and vorbis audio or theora video, need to
2622 * send the codec_priv data as first three packets */
2623 num_packets = p[0] + 1;
2624 GST_DEBUG_OBJECT (demux,
2625 "%u stream headers, total length=%" G_GSIZE_FORMAT " bytes",
2626 (guint) num_packets, stream->codec_priv_size);
2628 length = g_alloca (num_packets * sizeof (guint));
2632 /* first packets, read length values */
2633 for (i = 0; i < num_packets - 1; i++) {
2635 while (offset < stream->codec_priv_size) {
2636 length[i] += p[offset];
2637 if (p[offset++] != 0xff)
2642 if (offset + last > stream->codec_priv_size)
2643 return GST_FLOW_ERROR;
2645 /* last packet is the remaining size */
2646 length[i] = stream->codec_priv_size - offset - last;
2648 for (i = 0; i < num_packets; i++) {
2649 GST_DEBUG_OBJECT (demux, "buffer %d: length=%u bytes", i,
2651 if (offset + length[i] > stream->codec_priv_size)
2652 return GST_FLOW_ERROR;
2655 gst_matroska_demux_push_hdr_buf (demux, stream, p + offset, length[i]);
2656 if (ret != GST_FLOW_OK)
2659 offset += length[i];
2665 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2666 GstMatroskaTrackContext * stream)
2670 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2672 if (!stream->codec_priv)
2675 /* ideally, VobSub private data should be parsed and stored more convenient
2676 * elsewhere, but for now, only interested in a small part */
2678 /* make sure we have terminating 0 */
2679 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2681 /* just locate and parse palette part */
2682 start = strstr (buf, "palette:");
2687 guint8 r, g, b, y, u, v;
2690 while (g_ascii_isspace (*start))
2692 for (i = 0; i < 16; i++) {
2693 if (sscanf (start, "%06x", &col) != 1)
2696 while ((*start == ',') || g_ascii_isspace (*start))
2698 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2699 r = (col >> 16) & 0xff;
2700 g = (col >> 8) & 0xff;
2702 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2704 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2705 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2706 clut[i] = (y << 16) | (u << 8) | v;
2709 /* got them all without problems; build and send event */
2713 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2714 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2715 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2716 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2717 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2718 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2719 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2720 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2721 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2722 G_TYPE_INT, clut[15], NULL);
2724 gst_pad_push_event (stream->pad,
2725 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
2731 static GstFlowReturn
2732 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2733 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2736 guint seq_header_len;
2737 guint32 header, tmp;
2739 if (stream->codec_state) {
2740 seq_header = stream->codec_state;
2741 seq_header_len = stream->codec_state_size;
2742 } else if (stream->codec_priv) {
2743 seq_header = stream->codec_priv;
2744 seq_header_len = stream->codec_priv_size;
2749 /* Sequence header only needed for keyframes */
2750 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2753 if (gst_buffer_get_size (*buf) < 4)
2756 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2757 header = GUINT32_FROM_BE (tmp);
2759 /* Sequence start code, if not found prepend */
2760 if (header != 0x000001b3) {
2763 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2765 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2768 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2769 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2770 gst_buffer_get_size (*buf));
2772 gst_buffer_unref (*buf);
2779 static GstFlowReturn
2780 gst_matroska_demux_add_wvpk_header (GstElement * element,
2781 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2783 GstMatroskaTrackAudioContext *audiocontext =
2784 (GstMatroskaTrackAudioContext *) stream;
2785 GstBuffer *newbuf = NULL;
2786 GstMapInfo map, outmap;
2787 guint8 *buf_data, *data;
2795 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2798 wvh.total_samples = -1;
2799 wvh.block_index = audiocontext->wvpk_block_index;
2801 if (audiocontext->channels <= 2) {
2802 guint32 block_samples, tmp;
2803 gsize size = gst_buffer_get_size (*buf);
2805 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2806 block_samples = GUINT32_FROM_LE (tmp);
2807 /* we need to reconstruct the header of the wavpack block */
2809 /* -20 because ck_size is the size of the wavpack block -8
2810 * and lace_size is the size of the wavpack block + 12
2811 * (the three guint32 of the header that already are in the buffer) */
2812 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2814 /* block_samples, flags and crc are already in the buffer */
2815 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2817 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2823 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2824 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2825 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2826 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2827 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2828 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2830 /* Append data from buf: */
2831 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2832 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2834 gst_buffer_unref (*buf);
2836 audiocontext->wvpk_block_index += block_samples;
2838 guint8 *outdata = NULL;
2840 gsize buf_size, size, out_size = 0;
2841 guint32 block_samples, flags, crc, blocksize;
2843 gst_buffer_map (*buf, &map, GST_MAP_READ);
2844 buf_data = map.data;
2845 buf_size = map.size;
2848 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2849 gst_buffer_unmap (*buf, &map);
2850 return GST_FLOW_ERROR;
2856 block_samples = GST_READ_UINT32_LE (data);
2861 flags = GST_READ_UINT32_LE (data);
2864 crc = GST_READ_UINT32_LE (data);
2867 blocksize = GST_READ_UINT32_LE (data);
2871 if (blocksize == 0 || size < blocksize)
2874 g_assert ((newbuf == NULL) == (outdata == NULL));
2876 if (newbuf == NULL) {
2877 out_size = sizeof (Wavpack4Header) + blocksize;
2878 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2880 gst_buffer_copy_into (newbuf, *buf,
2881 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2884 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2885 outdata = outmap.data;
2887 gst_buffer_unmap (newbuf, &outmap);
2888 out_size += sizeof (Wavpack4Header) + blocksize;
2889 gst_buffer_set_size (newbuf, out_size);
2890 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2891 outdata = outmap.data;
2894 outdata[outpos] = 'w';
2895 outdata[outpos + 1] = 'v';
2896 outdata[outpos + 2] = 'p';
2897 outdata[outpos + 3] = 'k';
2900 GST_WRITE_UINT32_LE (outdata + outpos,
2901 blocksize + sizeof (Wavpack4Header) - 8);
2902 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2903 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2904 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2905 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2906 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2907 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2908 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2909 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2912 g_memmove (outdata + outpos, data, blocksize);
2913 outpos += blocksize;
2917 gst_buffer_unmap (*buf, &map);
2918 gst_buffer_unref (*buf);
2921 gst_buffer_unmap (newbuf, &outmap);
2924 audiocontext->wvpk_block_index += block_samples;
2930 /* @text must be null-terminated */
2932 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2937 /* yes, this might all lead to false positives ... */
2938 tag = (gchar *) text;
2939 while ((tag = strchr (tag, '<'))) {
2941 if (*tag != '\0' && *(tag + 1) == '>') {
2942 /* some common convenience ones */
2943 /* maybe any character will do here ? */
2956 if (strstr (text, "<span"))
2962 static GstFlowReturn
2963 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2964 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2966 GstMatroskaTrackSubtitleContext *sub_stream;
2967 const gchar *encoding;
2973 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
2975 if (!gst_buffer_map (*buf, &map, GST_MAP_READ))
2978 if (!sub_stream->invalid_utf8) {
2979 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
2982 GST_WARNING_OBJECT (element, "subtitle stream %d is not valid UTF-8, this "
2983 "is broken according to the matroska specification", stream->num);
2984 sub_stream->invalid_utf8 = TRUE;
2987 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
2988 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
2989 if (encoding == NULL || *encoding == '\0') {
2990 /* if local encoding is UTF-8 and no encoding specified
2991 * via the environment variable, assume ISO-8859-15 */
2992 if (g_get_charset (&encoding)) {
2993 encoding = "ISO-8859-15";
2998 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
2999 (char *) "*", NULL, NULL, &err);
3002 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3003 encoding, err->message);
3007 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3008 encoding = "ISO-8859-15";
3010 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3011 encoding, (char *) "*", NULL, NULL, NULL);
3014 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3015 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3018 utf8 = g_strdup ("invalid subtitle");
3020 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3021 gst_buffer_copy_into (newbuf, *buf,
3022 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3024 gst_buffer_unmap (*buf, &map);
3025 gst_buffer_unref (*buf);
3028 gst_buffer_map (*buf, &map, GST_MAP_READ);
3031 if (sub_stream->check_markup) {
3032 /* caps claim markup text, so we need to escape text,
3033 * except if text is already markup and then needs no further escaping */
3034 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3035 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3037 if (!sub_stream->seen_markup_tag) {
3038 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3040 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3041 gst_buffer_copy_into (newbuf, *buf,
3042 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3043 GST_BUFFER_COPY_META, 0, -1);
3044 gst_buffer_unmap (*buf, &map);
3045 gst_buffer_unref (*buf);
3054 static GstFlowReturn
3055 gst_matroska_demux_check_aac (GstElement * element,
3056 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3061 gst_buffer_extract (*buf, 0, data, 2);
3062 size = gst_buffer_get_size (*buf);
3064 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3067 /* tss, ADTS data, remove codec_data
3068 * still assume it is at least parsed */
3069 stream->caps = gst_caps_make_writable (stream->caps);
3070 s = gst_caps_get_structure (stream->caps, 0);
3072 gst_structure_remove_field (s, "codec_data");
3073 gst_pad_set_caps (stream->pad, stream->caps);
3074 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3075 "new caps: %" GST_PTR_FORMAT, stream->caps);
3078 /* disable subsequent checking */
3079 stream->postprocess_frame = NULL;
3085 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3086 GstBuffer * buffer, gsize alignment)
3090 gst_buffer_map (buffer, &map, GST_MAP_READ);
3092 if (map.size < sizeof (guintptr)) {
3093 gst_buffer_unmap (buffer, &map);
3097 if (((guintptr) map.data) & (alignment - 1)) {
3098 GstBuffer *new_buffer;
3099 GstAllocationParams params = { 0, 0, 0, alignment - 1, };
3101 new_buffer = gst_buffer_new_allocate (NULL,
3102 gst_buffer_get_size (buffer), ¶ms);
3104 /* Copy data "by hand", so ensure alignment is kept: */
3105 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3107 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3108 GST_DEBUG_OBJECT (demux,
3109 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3112 gst_buffer_unmap (buffer, &map);
3113 gst_buffer_unref (buffer);
3118 gst_buffer_unmap (buffer, &map);
3122 static GstFlowReturn
3123 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3124 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3125 gboolean is_simpleblock)
3127 GstMatroskaTrackContext *stream = NULL;
3128 GstFlowReturn ret = GST_FLOW_OK;
3129 gboolean readblock = FALSE;
3131 guint64 block_duration = -1;
3132 GstBuffer *buf = NULL;
3134 gint stream_num = -1, n, laces = 0;
3136 gint *lace_size = NULL;
3139 gint64 referenceblock = 0;
3142 offset = gst_ebml_read_get_offset (ebml);
3144 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3145 if (!is_simpleblock) {
3146 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3150 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3154 /* one block inside the group. Note, block parsing is one
3155 * of the harder things, so this code is a bit complicated.
3156 * See http://www.matroska.org/ for documentation. */
3157 case GST_MATROSKA_ID_SIMPLEBLOCK:
3158 case GST_MATROSKA_ID_BLOCK:
3164 gst_buffer_unmap (buf, &map);
3165 gst_buffer_unref (buf);
3168 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3171 gst_buffer_map (buf, &map, GST_MAP_READ);
3175 /* first byte(s): blocknum */
3176 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3181 /* fetch stream from num */
3182 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3184 if (G_UNLIKELY (size < 3)) {
3185 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3186 /* non-fatal, try next block(group) */
3189 } else if (G_UNLIKELY (stream_num < 0 ||
3190 stream_num >= demux->common.num_streams)) {
3191 /* let's not give up on a stray invalid track number */
3192 GST_WARNING_OBJECT (demux,
3193 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3194 "; ignoring block", stream_num, num);
3198 stream = g_ptr_array_index (demux->common.src, stream_num);
3200 /* time (relative to cluster time) */
3201 time = ((gint16) GST_READ_UINT16_BE (data));
3204 flags = GST_READ_UINT8 (data);
3208 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3211 switch ((flags & 0x06) >> 1) {
3212 case 0x0: /* no lacing */
3214 lace_size = g_new (gint, 1);
3215 lace_size[0] = size;
3218 case 0x1: /* xiph lacing */
3219 case 0x2: /* fixed-size lacing */
3220 case 0x3: /* EBML lacing */
3222 goto invalid_lacing;
3223 laces = GST_READ_UINT8 (data) + 1;
3226 lace_size = g_new0 (gint, laces);
3228 switch ((flags & 0x06) >> 1) {
3229 case 0x1: /* xiph lacing */ {
3230 guint temp, total = 0;
3232 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3235 goto invalid_lacing;
3236 temp = GST_READ_UINT8 (data);
3237 lace_size[n] += temp;
3243 total += lace_size[n];
3245 lace_size[n] = size - total;
3249 case 0x2: /* fixed-size lacing */
3250 for (n = 0; n < laces; n++)
3251 lace_size[n] = size / laces;
3254 case 0x3: /* EBML lacing */ {
3257 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3261 total = lace_size[0] = num;
3262 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3266 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3270 lace_size[n] = lace_size[n - 1] + snum;
3271 total += lace_size[n];
3274 lace_size[n] = size - total;
3281 if (stream->send_xiph_headers) {
3282 ret = gst_matroska_demux_push_xiph_codec_priv_data (demux, stream);
3283 stream->send_xiph_headers = FALSE;
3286 if (stream->send_flac_headers) {
3287 ret = gst_matroska_demux_push_flac_codec_priv_data (demux, stream);
3288 stream->send_flac_headers = FALSE;
3291 if (stream->send_speex_headers) {
3292 ret = gst_matroska_demux_push_speex_codec_priv_data (demux, stream);
3293 stream->send_speex_headers = FALSE;
3296 if (stream->send_dvd_event) {
3297 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
3298 /* FIXME: should we send this event again after (flushing) seek ? */
3299 stream->send_dvd_event = FALSE;
3302 if (ret != GST_FLOW_OK)
3309 case GST_MATROSKA_ID_BLOCKDURATION:{
3310 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3311 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3316 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3317 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3318 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3323 case GST_MATROSKA_ID_CODECSTATE:{
3325 guint64 data_len = 0;
3328 gst_ebml_read_binary (ebml, &id, &data,
3329 &data_len)) != GST_FLOW_OK)
3332 if (G_UNLIKELY (stream == NULL)) {
3333 GST_WARNING_OBJECT (demux,
3334 "Unexpected CodecState subelement - ignoring");
3338 g_free (stream->codec_state);
3339 stream->codec_state = data;
3340 stream->codec_state_size = data_len;
3342 /* Decode if necessary */
3343 if (stream->encodings && stream->encodings->len > 0
3344 && stream->codec_state && stream->codec_state_size > 0) {
3345 if (!gst_matroska_decode_data (stream->encodings,
3346 &stream->codec_state, &stream->codec_state_size,
3347 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3348 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3352 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3353 stream->codec_state_size);
3358 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3362 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3363 case GST_MATROSKA_ID_BLOCKADDITIONS:
3364 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3365 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3366 case GST_MATROSKA_ID_SLICES:
3367 GST_DEBUG_OBJECT (demux,
3368 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3369 ret = gst_ebml_read_skip (ebml);
3377 /* reading a number or so could have failed */
3378 if (ret != GST_FLOW_OK)
3381 if (ret == GST_FLOW_OK && readblock) {
3382 guint64 duration = 0;
3383 gint64 lace_time = 0;
3384 gboolean delta_unit;
3386 stream = g_ptr_array_index (demux->common.src, stream_num);
3388 if (cluster_time != GST_CLOCK_TIME_NONE) {
3389 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3390 * Drop unless the lace contains timestamp 0? */
3391 if (time < 0 && (-time) > cluster_time) {
3394 if (stream->timecodescale == 1.0)
3395 lace_time = (cluster_time + time) * demux->common.time_scale;
3398 gst_util_guint64_to_gdouble ((cluster_time + time) *
3399 demux->common.time_scale) * stream->timecodescale;
3402 lace_time = GST_CLOCK_TIME_NONE;
3405 /* need to refresh segment info ASAP */
3406 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3407 GstSegment *segment = &demux->common.segment;
3408 guint64 segment_duration = 0;
3410 GST_DEBUG_OBJECT (demux,
3411 "generating segment starting at %" GST_TIME_FORMAT,
3412 GST_TIME_ARGS (lace_time));
3413 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3414 demux->stream_start_time = lace_time;
3415 GST_DEBUG_OBJECT (demux,
3416 "Setting stream start time to %" GST_TIME_FORMAT,
3417 GST_TIME_ARGS (lace_time));
3419 if (demux->common.segment.start == 0) {
3420 /* set segment fields only if they weren't already set by seek handling
3423 if (GST_CLOCK_TIME_IS_VALID (segment->stop))
3424 segment_duration = segment->stop - segment->start;
3425 else if (GST_CLOCK_TIME_IS_VALID (segment->position))
3426 segment_duration = segment->position - segment->start;
3427 segment->base += segment_duration / fabs (segment->rate);
3428 segment->start = MAX (lace_time, demux->stream_start_time);
3429 segment->stop = GST_CLOCK_TIME_NONE;
3430 segment->position = segment->start - demux->stream_start_time;
3432 /* now convey our segment notion downstream */
3433 gst_matroska_demux_send_event (demux, gst_event_new_segment (segment));
3434 demux->need_segment = FALSE;
3437 if (block_duration != -1) {
3438 if (stream->timecodescale == 1.0)
3439 duration = gst_util_uint64_scale (block_duration,
3440 demux->common.time_scale, 1);
3443 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3444 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3445 1)) * stream->timecodescale);
3446 } else if (stream->default_duration) {
3447 duration = stream->default_duration * laces;
3449 /* else duration is diff between timecode of this and next block */
3451 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3452 a ReferenceBlock implies that this is not a keyframe. In either
3453 case, it only makes sense for video streams. */
3454 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3455 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
3457 if (delta_unit && stream->set_discont) {
3458 /* When doing seeks or such, we need to restart on key frames or
3459 * decoders might choke. */
3460 GST_DEBUG_OBJECT (demux, "skipping delta unit");
3464 for (n = 0; n < laces; n++) {
3467 if (G_UNLIKELY (lace_size[n] > size)) {
3468 GST_WARNING_OBJECT (demux, "Invalid lace size");
3472 /* QoS for video track with an index. the assumption is that
3473 index entries point to keyframes, but if that is not true we
3474 will instad skip until the next keyframe. */
3475 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3476 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3477 stream->index_table && demux->common.segment.rate > 0.0) {
3478 GstMatroskaTrackVideoContext *videocontext =
3479 (GstMatroskaTrackVideoContext *) stream;
3480 GstClockTime earliest_time;
3481 GstClockTime earliest_stream_time;
3483 GST_OBJECT_LOCK (demux);
3484 earliest_time = videocontext->earliest_time;
3485 GST_OBJECT_UNLOCK (demux);
3486 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3487 GST_FORMAT_TIME, earliest_time);
3489 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3490 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3491 lace_time <= earliest_stream_time) {
3492 /* find index entry (keyframe) <= earliest_stream_time */
3493 GstMatroskaIndex *entry =
3494 gst_util_array_binary_search (stream->index_table->data,
3495 stream->index_table->len, sizeof (GstMatroskaIndex),
3496 (GCompareDataFunc) gst_matroska_index_seek_find,
3497 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3499 /* if that entry (keyframe) is after the current the current
3500 buffer, we can skip pushing (and thus decoding) all
3501 buffers until that keyframe. */
3502 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3503 entry->time > lace_time) {
3504 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3505 stream->set_discont = TRUE;
3511 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3512 gst_buffer_get_size (buf) - size, lace_size[n]);
3513 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3516 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3518 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3520 if (stream->encodings != NULL && stream->encodings->len > 0)
3521 sub = gst_matroska_decode_buffer (stream, sub);
3524 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3528 GST_BUFFER_TIMESTAMP (sub) = lace_time;
3530 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3531 GstClockTime last_stop_end;
3533 /* Check if this stream is after segment stop */
3534 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3535 lace_time >= demux->common.segment.stop) {
3536 GST_DEBUG_OBJECT (demux,
3537 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3538 GST_TIME_ARGS (demux->common.segment.stop));
3539 gst_buffer_unref (sub);
3542 if (offset >= stream->to_offset) {
3543 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3545 gst_buffer_unref (sub);
3549 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3550 * that landed us with timestamps not quite intended */
3551 GST_OBJECT_LOCK (demux);
3552 if (demux->max_gap_time &&
3553 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3554 demux->common.segment.rate > 0.0) {
3555 GstClockTimeDiff diff;
3557 /* only send segments with increasing start times,
3558 * otherwise if these go back and forth downstream (sinks) increase
3559 * accumulated time and running_time */
3560 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3561 if (diff > 0 && diff > demux->max_gap_time
3562 && lace_time > demux->common.segment.start
3563 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3564 || lace_time < demux->common.segment.stop)) {
3566 GstEvent *event1, *event2;
3567 GST_DEBUG_OBJECT (demux,
3568 "Gap of %" G_GINT64_FORMAT " ns detected in"
3569 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3570 "Sending updated SEGMENT events", diff,
3571 stream->index, GST_TIME_ARGS (stream->pos),
3572 GST_TIME_ARGS (lace_time));
3573 /* send segment events such that the gap is not accounted in
3574 * segment base time, hence running_time */
3575 /* close ahead of gap */
3576 segment = demux->common.segment;
3577 segment.start = demux->last_stop_end;
3578 segment.stop = demux->last_stop_end;
3579 segment.position = demux->last_stop_end;
3580 event1 = gst_event_new_segment (&segment);
3582 segment.start = lace_time;
3583 segment.stop = demux->common.segment.stop;
3584 segment.position = lace_time;
3585 event2 = gst_event_new_segment (&segment);
3586 GST_OBJECT_UNLOCK (demux);
3587 gst_matroska_demux_send_event (demux, event1);
3588 gst_matroska_demux_send_event (demux, event2);
3589 GST_OBJECT_LOCK (demux);
3590 /* align segment view with downstream,
3591 * prevents double-counting base time when closing segment */
3592 /* FIXME: in 0.10, the segment base/accum got updated here, but
3593 * maybe we don't need that because of the double accounting
3594 * mentioned above? */
3595 demux->common.segment = segment;
3599 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3600 || demux->common.segment.position < lace_time) {
3601 demux->common.segment.position = lace_time;
3603 GST_OBJECT_UNLOCK (demux);
3605 last_stop_end = lace_time;
3607 GST_BUFFER_DURATION (sub) = duration / laces;
3608 last_stop_end += GST_BUFFER_DURATION (sub);
3611 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3612 demux->last_stop_end < last_stop_end)
3613 demux->last_stop_end = last_stop_end;
3615 GST_OBJECT_LOCK (demux);
3616 if (demux->common.segment.duration == -1 ||
3617 demux->stream_start_time + demux->common.segment.duration <
3619 demux->common.segment.duration =
3620 last_stop_end - demux->stream_start_time;
3621 GST_OBJECT_UNLOCK (demux);
3622 if (!demux->invalid_duration) {
3623 gst_element_post_message (GST_ELEMENT_CAST (demux),
3624 gst_message_new_duration (GST_OBJECT_CAST (demux),
3625 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
3626 demux->invalid_duration = TRUE;
3629 GST_OBJECT_UNLOCK (demux);
3633 stream->pos = lace_time;
3635 gst_matroska_demux_sync_streams (demux);
3637 if (stream->set_discont) {
3638 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3639 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3640 stream->set_discont = FALSE;
3643 /* reverse playback book-keeping */
3644 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3645 stream->from_time = lace_time;
3646 if (stream->from_offset == -1)
3647 stream->from_offset = offset;
3649 GST_DEBUG_OBJECT (demux,
3650 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3651 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3652 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3653 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
3654 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3657 if (demux->common.element_index) {
3658 if (stream->index_writer_id == -1)
3659 gst_index_get_writer_id (demux->common.element_index,
3660 GST_OBJECT (stream->pad), &stream->index_writer_id);
3662 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3663 G_GUINT64_FORMAT " for writer id %d",
3664 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
3665 stream->index_writer_id);
3666 gst_index_add_association (demux->common.element_index,
3667 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3668 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3669 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
3670 cluster_offset, NULL);
3674 /* Postprocess the buffers depending on the codec used */
3675 if (stream->postprocess_frame) {
3676 GST_LOG_OBJECT (demux, "running post process");
3677 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3680 /* At this point, we have a sub-buffer pointing at data within a larger
3681 buffer. This data might not be aligned with anything. If the data is
3682 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3683 for 32 bit samples, etc), or bad things will happen downstream as
3684 elements typically assume minimal alignment.
3685 Therefore, create an aligned copy if necessary. */
3686 g_assert (stream->alignment <= G_MEM_ALIGN);
3687 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3689 ret = gst_pad_push (stream->pad, sub);
3690 if (demux->common.segment.rate < 0) {
3691 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3692 /* In reverse playback we can get a GST_FLOW_EOS when
3693 * we are at the end of the segment, so we just need to jump
3694 * back to the previous section. */
3695 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3700 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3703 size -= lace_size[n];
3704 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3705 lace_time += duration / laces;
3707 lace_time = GST_CLOCK_TIME_NONE;
3713 gst_buffer_unmap (buf, &map);
3714 gst_buffer_unref (buf);
3726 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3731 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3732 /* non-fatal, try next block(group) */
3738 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3739 /* non-fatal, try next block(group) */
3745 /* return FALSE if block(group) should be skipped (due to a seek) */
3746 static inline gboolean
3747 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3749 if (G_UNLIKELY (demux->seek_block)) {
3750 if (!(--demux->seek_block)) {
3753 GST_LOG_OBJECT (demux, "should skip block due to seek");
3761 static GstFlowReturn
3762 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3766 guint64 seek_pos = (guint64) - 1;
3767 guint32 seek_id = 0;
3770 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3772 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3773 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3777 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3778 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3782 case GST_MATROSKA_ID_SEEKID:
3786 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3789 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3794 case GST_MATROSKA_ID_SEEKPOSITION:
3798 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3801 if (t > G_MAXINT64) {
3802 GST_WARNING_OBJECT (demux,
3803 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3807 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3813 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3819 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3822 if (!seek_id || seek_pos == (guint64) - 1) {
3823 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3824 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3829 case GST_MATROSKA_ID_SEEKHEAD:
3832 case GST_MATROSKA_ID_CUES:
3833 case GST_MATROSKA_ID_TAGS:
3834 case GST_MATROSKA_ID_TRACKS:
3835 case GST_MATROSKA_ID_SEGMENTINFO:
3836 case GST_MATROSKA_ID_ATTACHMENTS:
3837 case GST_MATROSKA_ID_CHAPTERS:
3839 guint64 before_pos, length;
3843 length = gst_matroska_read_common_get_length (&demux->common);
3844 before_pos = demux->common.offset;
3846 if (length == (guint64) - 1) {
3847 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3851 /* check for validity */
3852 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3853 GST_WARNING_OBJECT (demux,
3854 "SeekHead reference lies outside file!" " (%"
3855 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3856 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3861 /* only pick up index location when streaming */
3862 if (demux->streaming) {
3863 if (seek_id == GST_MATROSKA_ID_CUES) {
3864 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3865 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3866 demux->index_offset);
3872 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3875 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3876 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3880 if (id != seek_id) {
3881 GST_WARNING_OBJECT (demux,
3882 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3883 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3886 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3891 demux->common.offset = before_pos;
3895 case GST_MATROSKA_ID_CLUSTER:
3897 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3899 GST_LOG_OBJECT (demux, "Cluster position");
3900 if (G_UNLIKELY (!demux->clusters))
3901 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3902 g_array_append_val (demux->clusters, pos);
3907 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3910 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3915 static GstFlowReturn
3916 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3918 GstFlowReturn ret = GST_FLOW_OK;
3921 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3923 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3924 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3928 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3929 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3933 case GST_MATROSKA_ID_SEEKENTRY:
3935 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3936 /* Ignore EOS and errors here */
3937 if (ret != GST_FLOW_OK) {
3938 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3945 ret = gst_matroska_read_common_parse_skip (&demux->common,
3946 ebml, "SeekHead", id);
3951 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3953 /* Sort clusters by position for easier searching */
3954 if (demux->clusters)
3955 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3960 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3962 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3964 static inline GstFlowReturn
3965 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
3967 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
3968 /* only a few blocks are expected/allowed to be large,
3969 * and will be recursed into, whereas others will be read and must fit */
3970 if (demux->streaming) {
3971 /* fatal in streaming case, as we can't step over easily */
3972 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3973 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
3974 "file might be corrupt.", bytes));
3975 return GST_FLOW_ERROR;
3977 /* indicate higher level to quietly give up */
3978 GST_DEBUG_OBJECT (demux,
3979 "too large block of size %" G_GUINT64_FORMAT, bytes);
3980 return GST_FLOW_ERROR;
3987 /* returns TRUE if we truely are in error state, and should give up */
3988 static inline gboolean
3989 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
3991 if (!demux->streaming && demux->next_cluster_offset > 0) {
3992 /* just repositioning to where next cluster should be and try from there */
3993 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
3994 G_GUINT64_FORMAT, demux->next_cluster_offset);
3995 demux->common.offset = demux->next_cluster_offset;
3996 demux->next_cluster_offset = 0;
4001 /* sigh, one last attempt above and beyond call of duty ...;
4002 * search for cluster mark following current pos */
4003 pos = demux->common.offset;
4004 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4005 if (gst_matroska_demux_search_cluster (demux, &pos) != GST_FLOW_OK) {
4006 /* did not work, give up */
4009 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4010 /* try that position */
4011 demux->common.offset = pos;
4017 static inline GstFlowReturn
4018 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4020 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4021 demux->common.offset += flush;
4022 if (demux->streaming) {
4025 /* hard to skip large blocks when streaming */
4026 ret = gst_matroska_demux_check_read_size (demux, flush);
4027 if (ret != GST_FLOW_OK)
4029 if (flush <= gst_adapter_available (demux->common.adapter))
4030 gst_adapter_flush (demux->common.adapter, flush);
4032 return GST_FLOW_EOS;
4037 /* initializes @ebml with @bytes from input stream at current offset.
4038 * Returns EOS if insufficient available,
4039 * ERROR if too much was attempted to read. */
4040 static inline GstFlowReturn
4041 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4044 GstBuffer *buffer = NULL;
4045 GstFlowReturn ret = GST_FLOW_OK;
4047 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4049 ret = gst_matroska_demux_check_read_size (demux, bytes);
4050 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4051 if (!demux->streaming) {
4052 /* in pull mode, we can skip */
4053 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4054 ret = GST_FLOW_OVERFLOW;
4056 /* otherwise fatal */
4057 ret = GST_FLOW_ERROR;
4061 if (demux->streaming) {
4062 if (gst_adapter_available (demux->common.adapter) >= bytes)
4063 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4067 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4068 demux->common.offset, bytes, &buffer, NULL);
4069 if (G_LIKELY (buffer)) {
4070 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4071 demux->common.offset);
4072 demux->common.offset += bytes;
4079 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4082 gboolean seekable = FALSE;
4083 gint64 start = -1, stop = -1;
4085 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4086 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4087 GST_DEBUG_OBJECT (demux, "seeking query failed");
4091 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4093 /* try harder to query upstream size if we didn't get it the first time */
4094 if (seekable && stop == -1) {
4095 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4096 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4100 /* if upstream doesn't know the size, it's likely that it's not seekable in
4101 * practice even if it technically may be seekable */
4102 if (seekable && (start != 0 || stop <= start)) {
4103 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4108 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4109 G_GUINT64_FORMAT ")", seekable, start, stop);
4110 demux->seekable = seekable;
4112 gst_query_unref (query);
4115 static GstFlowReturn
4116 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4122 GstFlowReturn ret = GST_FLOW_OK;
4124 GST_WARNING_OBJECT (demux,
4125 "Found Cluster element before Tracks, searching Tracks");
4128 before_pos = demux->common.offset;
4130 /* Search Tracks element */
4132 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4133 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4134 if (ret != GST_FLOW_OK)
4137 if (id != GST_MATROSKA_ID_TRACKS) {
4138 /* we may be skipping large cluster here, so forego size check etc */
4139 /* ... but we can't skip undefined size; force error */
4140 if (length == G_MAXUINT64) {
4141 ret = gst_matroska_demux_check_read_size (demux, length);
4144 demux->common.offset += needed;
4145 demux->common.offset += length;
4150 /* will lead to track parsing ... */
4151 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4156 demux->common.offset = before_pos;
4161 #define GST_READ_CHECK(stmt) \
4163 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4164 if (ret == GST_FLOW_OVERFLOW) { \
4165 ret = GST_FLOW_OK; \
4171 static GstFlowReturn
4172 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4173 guint64 length, guint needed)
4175 GstEbmlRead ebml = { 0, };
4176 GstFlowReturn ret = GST_FLOW_OK;
4179 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4180 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4182 /* if we plan to read and parse this element, we need prefix (id + length)
4183 * and the contents */
4184 /* mind about overflow wrap-around when dealing with undefined size */
4186 if (G_LIKELY (length != G_MAXUINT64))
4189 switch (demux->common.state) {
4190 case GST_MATROSKA_READ_STATE_START:
4192 case GST_EBML_ID_HEADER:
4193 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4194 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4195 if (ret != GST_FLOW_OK)
4197 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4198 gst_matroska_demux_check_seekability (demux);
4201 goto invalid_header;
4205 case GST_MATROSKA_READ_STATE_SEGMENT:
4207 case GST_MATROSKA_ID_SEGMENT:
4208 /* eat segment prefix */
4209 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4210 GST_DEBUG_OBJECT (demux,
4211 "Found Segment start at offset %" G_GUINT64_FORMAT,
4212 demux->common.offset);
4213 /* seeks are from the beginning of the segment,
4214 * after the segment ID/length */
4215 demux->common.ebml_segment_start = demux->common.offset;
4216 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4219 GST_WARNING_OBJECT (demux,
4220 "Expected a Segment ID (0x%x), but received 0x%x!",
4221 GST_MATROSKA_ID_SEGMENT, id);
4222 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4226 case GST_MATROSKA_READ_STATE_SCANNING:
4227 if (id != GST_MATROSKA_ID_CLUSTER &&
4228 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4231 case GST_MATROSKA_READ_STATE_HEADER:
4232 case GST_MATROSKA_READ_STATE_DATA:
4233 case GST_MATROSKA_READ_STATE_SEEK:
4235 case GST_MATROSKA_ID_SEGMENTINFO:
4236 if (!demux->common.segmentinfo_parsed) {
4237 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4238 ret = gst_matroska_read_common_parse_info (&demux->common,
4239 GST_ELEMENT_CAST (demux), &ebml);
4241 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4244 case GST_MATROSKA_ID_TRACKS:
4245 if (!demux->tracks_parsed) {
4246 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4247 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4249 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4252 case GST_MATROSKA_ID_CLUSTER:
4253 if (G_UNLIKELY (!demux->tracks_parsed)) {
4254 if (demux->streaming) {
4255 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4256 goto not_streamable;
4258 ret = gst_matroska_demux_find_tracks (demux);
4259 if (!demux->tracks_parsed)
4263 if (G_UNLIKELY (demux->common.state
4264 == GST_MATROSKA_READ_STATE_HEADER)) {
4265 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4266 demux->first_cluster_offset = demux->common.offset;
4267 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4268 gst_element_no_more_pads (GST_ELEMENT (demux));
4269 /* send initial segment - we wait till we know the first
4270 incoming timestamp, so we can properly set the start of
4272 demux->need_segment = TRUE;
4274 demux->cluster_time = GST_CLOCK_TIME_NONE;
4275 demux->cluster_offset = demux->common.offset;
4276 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4277 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4278 " not found in Cluster, trying next Cluster's first block instead",
4280 demux->seek_block = 0;
4282 demux->seek_first = FALSE;
4283 /* record next cluster for recovery */
4284 if (read != G_MAXUINT64)
4285 demux->next_cluster_offset = demux->cluster_offset + read;
4286 /* eat cluster prefix */
4287 gst_matroska_demux_flush (demux, needed);
4289 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4293 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4294 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4296 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4297 demux->cluster_time = num;
4299 if (demux->common.element_index) {
4300 if (demux->common.element_index_writer_id == -1)
4301 gst_index_get_writer_id (demux->common.element_index,
4302 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4303 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4304 G_GUINT64_FORMAT " for writer id %d",
4305 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4306 demux->common.element_index_writer_id);
4307 gst_index_add_association (demux->common.element_index,
4308 demux->common.element_index_writer_id,
4309 GST_ASSOCIATION_FLAG_KEY_UNIT,
4310 GST_FORMAT_TIME, demux->cluster_time,
4311 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4316 case GST_MATROSKA_ID_BLOCKGROUP:
4317 if (!gst_matroska_demux_seek_block (demux))
4319 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4320 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4321 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4322 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4323 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4325 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4327 case GST_MATROSKA_ID_SIMPLEBLOCK:
4328 if (!gst_matroska_demux_seek_block (demux))
4330 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4331 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4332 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4333 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4334 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4336 case GST_MATROSKA_ID_ATTACHMENTS:
4337 if (!demux->common.attachments_parsed) {
4338 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4339 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4340 GST_ELEMENT_CAST (demux), &ebml);
4342 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4345 case GST_MATROSKA_ID_TAGS:
4346 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4347 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4348 GST_ELEMENT_CAST (demux), &ebml);
4350 case GST_MATROSKA_ID_CHAPTERS:
4351 if (!demux->common.chapters_parsed) {
4352 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4354 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4356 if (demux->common.toc) {
4357 gst_matroska_demux_send_event (demux,
4358 gst_event_new_toc (demux->common.toc, FALSE));
4361 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4363 case GST_MATROSKA_ID_SEEKHEAD:
4364 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4365 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4367 case GST_MATROSKA_ID_CUES:
4368 if (demux->common.index_parsed) {
4369 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4372 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4373 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4374 /* only push based; delayed index building */
4375 if (ret == GST_FLOW_OK
4376 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4379 GST_OBJECT_LOCK (demux);
4380 event = demux->seek_event;
4381 demux->seek_event = NULL;
4382 GST_OBJECT_UNLOCK (demux);
4385 /* unlikely to fail, since we managed to seek to this point */
4386 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4388 /* resume data handling, main thread clear to seek again */
4389 GST_OBJECT_LOCK (demux);
4390 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4391 GST_OBJECT_UNLOCK (demux);
4394 case GST_MATROSKA_ID_POSITION:
4395 case GST_MATROSKA_ID_PREVSIZE:
4396 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4397 case GST_MATROSKA_ID_SILENTTRACKS:
4398 GST_DEBUG_OBJECT (demux,
4399 "Skipping Cluster subelement 0x%x - ignoring", id);
4403 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4404 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4410 if (ret == GST_FLOW_PARSE)
4414 gst_ebml_read_clear (&ebml);
4420 /* simply exit, maybe not enough data yet */
4421 /* no ebml to clear if read error */
4426 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4427 ("Failed to parse Element 0x%x", id));
4428 ret = GST_FLOW_ERROR;
4433 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4434 ("File layout does not permit streaming"));
4435 ret = GST_FLOW_ERROR;
4440 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4441 ("No Tracks element found"));
4442 ret = GST_FLOW_ERROR;
4447 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4448 ret = GST_FLOW_ERROR;
4453 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4454 ret = GST_FLOW_ERROR;
4460 gst_matroska_demux_loop (GstPad * pad)
4462 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4468 /* If we have to close a segment, send a new segment to do this now */
4469 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4470 if (G_UNLIKELY (demux->new_segment)) {
4471 gst_matroska_demux_send_event (demux, demux->new_segment);
4472 demux->new_segment = NULL;
4476 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4477 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4478 if (ret == GST_FLOW_EOS)
4480 if (ret != GST_FLOW_OK) {
4481 if (gst_matroska_demux_check_parse_error (demux))
4487 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4488 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4491 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4492 if (ret == GST_FLOW_EOS)
4494 if (ret != GST_FLOW_OK)
4497 /* check if we're at the end of a configured segment */
4498 if (G_LIKELY (demux->common.src->len)) {
4501 g_assert (demux->common.num_streams == demux->common.src->len);
4502 for (i = 0; i < demux->common.src->len; i++) {
4503 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4505 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4506 GST_TIME_ARGS (context->pos));
4507 if (context->eos == FALSE)
4511 GST_INFO_OBJECT (demux, "All streams are EOS");
4517 if (G_UNLIKELY (demux->common.offset ==
4518 gst_matroska_read_common_get_length (&demux->common))) {
4519 GST_LOG_OBJECT (demux, "Reached end of stream");
4529 if (demux->common.segment.rate < 0.0) {
4530 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4531 if (ret == GST_FLOW_OK)
4538 const gchar *reason = gst_flow_get_name (ret);
4539 gboolean push_eos = FALSE;
4541 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4542 gst_pad_pause_task (demux->common.sinkpad);
4544 if (ret == GST_FLOW_EOS) {
4545 /* perform EOS logic */
4547 /* If we were in the headers, make sure we send no-more-pads.
4548 This will ensure decodebin2 does not get stuck thinking
4549 the chain is not complete yet, and waiting indefinitely. */
4550 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4551 if (demux->common.src->len == 0) {
4552 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4553 ("No pads created"));
4555 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4556 ("Failed to finish reading headers"));
4558 gst_element_no_more_pads (GST_ELEMENT (demux));
4561 /* Close the segment, i.e. update segment stop with the duration
4562 * if no stop was set */
4563 if (GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
4564 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
4565 GST_CLOCK_TIME_IS_VALID (demux->common.segment.start) &&
4566 demux->last_stop_end > demux->common.segment.start) {
4567 GstSegment segment = demux->common.segment;
4570 segment.stop = demux->last_stop_end;
4571 event = gst_event_new_segment (&segment);
4572 gst_matroska_demux_send_event (demux, event);
4575 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4578 /* for segment playback we need to post when (in stream time)
4579 * we stopped, this is either stop (when set) or the duration. */
4580 if ((stop = demux->common.segment.stop) == -1)
4581 stop = demux->last_stop_end;
4583 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4584 gst_element_post_message (GST_ELEMENT (demux),
4585 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4587 gst_matroska_demux_send_event (demux,
4588 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4592 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4593 /* for fatal errors we post an error message */
4594 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4595 ("stream stopped, reason %s", reason));
4599 /* send EOS, and prevent hanging if no streams yet */
4600 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4601 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4602 (ret == GST_FLOW_EOS)) {
4603 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4604 (NULL), ("got eos but no streams (yet)"));
4612 * Create and push a flushing seek event upstream
4615 perform_seek_to_offset (GstMatroskaDemux * demux, guint64 offset)
4620 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4623 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
4624 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4625 GST_SEEK_TYPE_NONE, -1);
4627 res = gst_pad_push_event (demux->common.sinkpad, event);
4629 /* segment event will update offset */
4633 static GstFlowReturn
4634 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4636 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4638 GstFlowReturn ret = GST_FLOW_OK;
4643 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4644 GST_DEBUG_OBJECT (demux, "got DISCONT");
4645 gst_adapter_clear (demux->common.adapter);
4646 GST_OBJECT_LOCK (demux);
4647 gst_matroska_read_common_reset_streams (&demux->common,
4648 GST_CLOCK_TIME_NONE, FALSE);
4649 GST_OBJECT_UNLOCK (demux);
4652 gst_adapter_push (demux->common.adapter, buffer);
4656 available = gst_adapter_available (demux->common.adapter);
4658 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4659 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4660 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS))
4663 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4664 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4665 demux->common.offset, id, length, needed, available);
4667 if (needed > available)
4670 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4671 if (ret == GST_FLOW_EOS) {
4672 /* need more data */
4674 } else if (ret != GST_FLOW_OK) {
4681 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4684 gboolean res = TRUE;
4685 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4687 GST_DEBUG_OBJECT (demux,
4688 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4690 switch (GST_EVENT_TYPE (event)) {
4691 case GST_EVENT_SEGMENT:
4693 const GstSegment *segment;
4695 /* some debug output */
4696 gst_event_parse_segment (event, &segment);
4697 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4698 GST_DEBUG_OBJECT (demux,
4699 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4702 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4703 GST_DEBUG_OBJECT (demux, "still starting");
4707 /* we only expect a BYTE segment, e.g. following a seek */
4708 if (segment->format != GST_FORMAT_BYTES) {
4709 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4713 GST_DEBUG_OBJECT (demux, "clearing segment state");
4714 GST_OBJECT_LOCK (demux);
4715 /* clear current segment leftover */
4716 gst_adapter_clear (demux->common.adapter);
4717 /* and some streaming setup */
4718 demux->common.offset = segment->start;
4719 /* do not know where we are;
4720 * need to come across a cluster and generate segment */
4721 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4722 demux->cluster_time = GST_CLOCK_TIME_NONE;
4723 demux->cluster_offset = 0;
4724 demux->need_segment = TRUE;
4725 /* but keep some of the upstream segment */
4726 demux->common.segment.rate = segment->rate;
4727 GST_OBJECT_UNLOCK (demux);
4729 /* chain will send initial segment after pads have been added,
4730 * or otherwise come up with one */
4731 GST_DEBUG_OBJECT (demux, "eating event");
4732 gst_event_unref (event);
4738 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4739 gst_event_unref (event);
4740 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4741 (NULL), ("got eos and didn't receive a complete header object"));
4742 } else if (demux->common.num_streams == 0) {
4743 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4744 (NULL), ("got eos but no streams (yet)"));
4746 gst_matroska_demux_send_event (demux, event);
4750 case GST_EVENT_FLUSH_STOP:
4754 gst_adapter_clear (demux->common.adapter);
4755 GST_OBJECT_LOCK (demux);
4756 gst_matroska_read_common_reset_streams (&demux->common,
4757 GST_CLOCK_TIME_NONE, TRUE);
4758 dur = demux->common.segment.duration;
4759 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4760 demux->common.segment.duration = dur;
4761 demux->cluster_time = GST_CLOCK_TIME_NONE;
4762 demux->cluster_offset = 0;
4763 GST_OBJECT_UNLOCK (demux);
4767 res = gst_pad_event_default (pad, parent, event);
4775 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4777 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4779 gboolean pull_mode = FALSE;
4781 query = gst_query_new_scheduling ();
4783 if (gst_pad_peer_query (sinkpad, query))
4784 pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL);
4786 gst_query_unref (query);
4789 GST_DEBUG ("going to pull mode");
4790 demux->streaming = FALSE;
4791 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4793 GST_DEBUG ("going to push (streaming) mode");
4794 demux->streaming = TRUE;
4795 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4800 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4801 GstPadMode mode, gboolean active)
4804 case GST_PAD_MODE_PULL:
4806 /* if we have a scheduler we can start the task */
4807 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4810 gst_pad_stop_task (sinkpad);
4813 case GST_PAD_MODE_PUSH:
4821 gst_duration_to_fraction (guint64 duration, gint * dest_n, gint * dest_d)
4823 static const int common_den[] = { 1, 2, 3, 4, 1001 };
4828 for (i = 0; i < G_N_ELEMENTS (common_den); i++) {
4830 n = floor (0.5 + (d * 1e9) / duration);
4831 a = gst_util_uint64_scale_int (1000000000, d, n);
4832 if (duration >= a - 1 && duration <= a + 1) {
4837 gst_util_double_to_fraction (1e9 / duration, &n, &d);
4846 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4847 videocontext, const gchar * codec_id, guint8 * data, guint size,
4848 gchar ** codec_name, guint32 * riff_fourcc)
4850 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4851 GstCaps *caps = NULL;
4853 g_assert (videocontext != NULL);
4854 g_assert (codec_name != NULL);
4856 context->send_xiph_headers = FALSE;
4857 context->send_flac_headers = FALSE;
4858 context->send_speex_headers = FALSE;
4863 /* TODO: check if we have all codec types from matroska-ids.h
4864 * check if we have to do more special things with codec_private
4867 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4868 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4871 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4872 gst_riff_strf_vids *vids = NULL;
4875 GstBuffer *buf = NULL;
4877 vids = (gst_riff_strf_vids *) data;
4879 /* assure size is big enough */
4881 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4884 if (size < sizeof (gst_riff_strf_vids)) {
4885 vids = g_new (gst_riff_strf_vids, 1);
4886 memcpy (vids, data, size);
4889 /* little-endian -> byte-order */
4890 vids->size = GUINT32_FROM_LE (vids->size);
4891 vids->width = GUINT32_FROM_LE (vids->width);
4892 vids->height = GUINT32_FROM_LE (vids->height);
4893 vids->planes = GUINT16_FROM_LE (vids->planes);
4894 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4895 vids->compression = GUINT32_FROM_LE (vids->compression);
4896 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4897 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4898 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4899 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4900 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4902 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4903 gsize offset = sizeof (gst_riff_strf_vids);
4906 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
4907 size - offset), size - offset);
4911 *riff_fourcc = vids->compression;
4913 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4914 buf, NULL, codec_name);
4917 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4918 GST_FOURCC_ARGS (vids->compression));
4922 gst_buffer_unref (buf);
4924 if (vids != (gst_riff_strf_vids *) data)
4927 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4928 const gchar *format = NULL;
4930 switch (videocontext->fourcc) {
4931 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4932 *codec_name = g_strdup ("Raw planar YUV 4:2:0");
4935 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4936 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
4939 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4940 *codec_name = g_strdup ("Raw packed YUV 4:2:0");
4943 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4944 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
4947 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4948 *codec_name = g_strdup ("Raw packed YUV 4:4:4 with alpha channel");
4953 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
4954 GST_FOURCC_ARGS (videocontext->fourcc));
4958 caps = gst_caps_new_simple ("video/x-raw",
4959 "format", G_TYPE_STRING, format, NULL);
4960 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
4961 caps = gst_caps_new_simple ("video/x-divx",
4962 "divxversion", G_TYPE_INT, 4, NULL);
4963 *codec_name = g_strdup ("MPEG-4 simple profile");
4964 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
4965 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
4967 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4968 "divxversion", G_TYPE_INT, 5, NULL),
4969 gst_structure_new ("video/x-xvid", NULL),
4970 gst_structure_new ("video/mpeg",
4971 "mpegversion", G_TYPE_INT, 4,
4972 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
4974 caps = gst_caps_new_simple ("video/mpeg",
4975 "mpegversion", G_TYPE_INT, 4,
4976 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
4980 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4981 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4982 gst_buffer_unref (priv);
4984 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
4985 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
4987 *codec_name = g_strdup ("MPEG-4 advanced profile");
4988 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
4990 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4991 "divxversion", G_TYPE_INT, 3, NULL),
4992 gst_structure_new ("video/x-msmpeg",
4993 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
4995 caps = gst_caps_new_simple ("video/x-msmpeg",
4996 "msmpegversion", G_TYPE_INT, 43, NULL);
4997 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
4998 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
4999 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5002 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5007 caps = gst_caps_new_simple ("video/mpeg",
5008 "systemstream", G_TYPE_BOOLEAN, FALSE,
5009 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5010 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5011 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5012 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5013 caps = gst_caps_new_empty_simple ("image/jpeg");
5014 *codec_name = g_strdup ("Motion-JPEG");
5015 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5016 caps = gst_caps_new_empty_simple ("video/x-h264");
5020 /* First byte is the version, second is the profile indication, and third
5021 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5022 * level indication. */
5023 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5026 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5027 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5028 gst_buffer_unref (priv);
5030 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5031 "alignment", G_TYPE_STRING, "au", NULL);
5033 GST_WARNING ("No codec data found, assuming output is byte-stream");
5034 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5037 *codec_name = g_strdup ("H264");
5038 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5039 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5040 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5041 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5042 gint rmversion = -1;
5044 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5046 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5048 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5050 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5053 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5054 "rmversion", G_TYPE_INT, rmversion, NULL);
5055 GST_DEBUG ("data:%p, size:0x%x", data, size);
5056 /* We need to extract the extradata ! */
5057 if (data && (size >= 0x22)) {
5062 subformat = GST_READ_UINT32_BE (data + 0x1a);
5063 rformat = GST_READ_UINT32_BE (data + 0x1e);
5066 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5068 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5069 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5070 gst_buffer_unref (priv);
5073 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5074 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5075 caps = gst_caps_new_empty_simple ("video/x-theora");
5076 context->send_xiph_headers = TRUE;
5077 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5078 caps = gst_caps_new_empty_simple ("video/x-dirac");
5079 *codec_name = g_strdup_printf ("Dirac");
5080 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5081 caps = gst_caps_new_empty_simple ("video/x-vp8");
5082 *codec_name = g_strdup_printf ("On2 VP8");
5084 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5090 GstStructure *structure;
5092 for (i = 0; i < gst_caps_get_size (caps); i++) {
5093 structure = gst_caps_get_structure (caps, i);
5095 /* FIXME: use the real unit here! */
5096 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5097 videocontext->pixel_width,
5098 videocontext->pixel_height,
5099 videocontext->display_width, videocontext->display_height);
5101 /* pixel width and height are the w and h of the video in pixels */
5102 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5103 gint w = videocontext->pixel_width;
5104 gint h = videocontext->pixel_height;
5106 gst_structure_set (structure,
5107 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5110 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5113 if (videocontext->display_width <= 0)
5114 videocontext->display_width = videocontext->pixel_width;
5115 if (videocontext->display_height <= 0)
5116 videocontext->display_height = videocontext->pixel_height;
5118 /* calculate the pixel aspect ratio using the display and pixel w/h */
5119 n = videocontext->display_width * videocontext->pixel_height;
5120 d = videocontext->display_height * videocontext->pixel_width;
5121 GST_DEBUG ("setting PAR to %d/%d", n, d);
5122 gst_structure_set (structure, "pixel-aspect-ratio",
5124 videocontext->display_width * videocontext->pixel_height,
5125 videocontext->display_height * videocontext->pixel_width, NULL);
5128 if (videocontext->default_fps > 0.0) {
5129 GValue fps_double = { 0, };
5130 GValue fps_fraction = { 0, };
5132 g_value_init (&fps_double, G_TYPE_DOUBLE);
5133 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
5134 g_value_set_double (&fps_double, videocontext->default_fps);
5135 g_value_transform (&fps_double, &fps_fraction);
5137 GST_DEBUG ("using default fps %f", videocontext->default_fps);
5139 gst_structure_set_value (structure, "framerate", &fps_fraction);
5140 g_value_unset (&fps_double);
5141 g_value_unset (&fps_fraction);
5142 } else if (context->default_duration > 0) {
5145 gst_duration_to_fraction (context->default_duration, &fps_n, &fps_d);
5147 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5148 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5150 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5151 fps_n, fps_d, NULL);
5153 /* sort of a hack to get most codecs to support,
5154 * even if the default_duration is missing */
5155 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5159 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5160 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5164 caps = gst_caps_simplify (caps);
5171 * Some AAC specific code... *sigh*
5172 * FIXME: maybe we should use '15' and code the sample rate explicitly
5173 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5177 aac_rate_idx (gint rate)
5181 else if (75132 <= rate)
5183 else if (55426 <= rate)
5185 else if (46009 <= rate)
5187 else if (37566 <= rate)
5189 else if (27713 <= rate)
5191 else if (23004 <= rate)
5193 else if (18783 <= rate)
5195 else if (13856 <= rate)
5197 else if (11502 <= rate)
5199 else if (9391 <= rate)
5206 aac_profile_idx (const gchar * codec_id)
5210 if (strlen (codec_id) <= 12)
5212 else if (!strncmp (&codec_id[12], "MAIN", 4))
5214 else if (!strncmp (&codec_id[12], "LC", 2))
5216 else if (!strncmp (&codec_id[12], "SSR", 3))
5224 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5227 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5228 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5229 gchar ** codec_name, guint16 * riff_audio_fmt)
5231 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5232 GstCaps *caps = NULL;
5234 g_assert (audiocontext != NULL);
5235 g_assert (codec_name != NULL);
5238 *riff_audio_fmt = 0;
5240 context->send_xiph_headers = FALSE;
5241 context->send_flac_headers = FALSE;
5242 context->send_speex_headers = FALSE;
5244 /* TODO: check if we have all codec types from matroska-ids.h
5245 * check if we have to do more special things with codec_private
5246 * check if we need bitdepth in different places too
5247 * implement channel position magic
5249 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5250 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5251 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5252 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5255 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5256 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5257 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5260 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5262 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5267 caps = gst_caps_new_simple ("audio/mpeg",
5268 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5269 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5270 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5271 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5274 GstAudioFormat format;
5276 sign = (audiocontext->bitdepth != 8);
5277 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5278 endianness = G_BIG_ENDIAN;
5280 endianness = G_LITTLE_ENDIAN;
5282 format = gst_audio_format_build_integer (sign, endianness,
5283 audiocontext->bitdepth, audiocontext->bitdepth);
5285 /* FIXME: Channel mask and reordering */
5286 caps = gst_caps_new_simple ("audio/x-raw",
5287 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5288 "layout", G_TYPE_STRING, "interleaved", NULL);
5290 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5291 audiocontext->bitdepth);
5292 context->alignment = audiocontext->bitdepth / 8;
5293 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5294 const gchar *format;
5295 if (audiocontext->bitdepth == 32)
5299 /* FIXME: Channel mask and reordering */
5300 caps = gst_caps_new_simple ("audio/x-raw",
5301 "format", G_TYPE_STRING, format,
5302 "layout", G_TYPE_STRING, "interleaved", NULL);
5303 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5304 audiocontext->bitdepth);
5305 context->alignment = audiocontext->bitdepth / 8;
5306 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5307 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5308 caps = gst_caps_new_simple ("audio/x-ac3",
5309 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5310 *codec_name = g_strdup ("AC-3 audio");
5311 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5312 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5313 caps = gst_caps_new_simple ("audio/x-eac3",
5314 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5315 *codec_name = g_strdup ("E-AC-3 audio");
5316 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5317 caps = gst_caps_new_empty_simple ("audio/x-dts");
5318 *codec_name = g_strdup ("DTS audio");
5319 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5320 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5321 context->send_xiph_headers = TRUE;
5322 /* vorbis decoder does tags */
5323 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5324 caps = gst_caps_new_empty_simple ("audio/x-flac");
5325 context->send_flac_headers = TRUE;
5326 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5327 caps = gst_caps_new_empty_simple ("audio/x-speex");
5328 context->send_speex_headers = TRUE;
5329 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5330 gst_riff_strf_auds auds;
5333 GstBuffer *codec_data;
5335 /* little-endian -> byte-order */
5336 auds.format = GST_READ_UINT16_LE (data);
5337 auds.channels = GST_READ_UINT16_LE (data + 2);
5338 auds.rate = GST_READ_UINT32_LE (data + 4);
5339 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5340 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5341 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5343 /* 18 is the waveformatex size */
5344 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5345 data + 18, auds.bits_per_sample, 0, auds.bits_per_sample, NULL, NULL);
5348 *riff_audio_fmt = auds.format;
5350 /* FIXME: Handle reorder map */
5351 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5352 codec_data, codec_name, NULL);
5353 gst_buffer_unref (codec_data);
5356 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5359 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5360 GstBuffer *priv = NULL;
5362 gint rate_idx, profile;
5363 guint8 *data = NULL;
5365 /* unspecified AAC profile with opaque private codec data */
5366 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5367 if (context->codec_priv_size >= 2) {
5368 guint obj_type, freq_index, explicit_freq_bytes = 0;
5370 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5372 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5373 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5374 if (freq_index == 15)
5375 explicit_freq_bytes = 3;
5376 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5377 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5378 context->codec_priv_size), context->codec_priv_size);
5379 /* assume SBR if samplerate <= 24kHz */
5380 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5381 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5382 audiocontext->samplerate *= 2;
5385 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5386 /* this is pretty broken;
5387 * maybe we need to make up some default private,
5388 * or maybe ADTS data got dumped in.
5389 * Let's set up some private data now, and check actual data later */
5390 /* just try this and see what happens ... */
5391 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5392 context->postprocess_frame = gst_matroska_demux_check_aac;
5396 /* make up decoder-specific data if it is not supplied */
5400 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5401 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5403 rate_idx = aac_rate_idx (audiocontext->samplerate);
5404 profile = aac_profile_idx (codec_id);
5406 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5407 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5409 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5410 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5412 gst_buffer_unmap (priv, &map);
5413 gst_buffer_set_size (priv, 2);
5414 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5415 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5418 if (g_strrstr (codec_id, "SBR")) {
5419 /* HE-AAC (aka SBR AAC) */
5420 audiocontext->samplerate *= 2;
5421 rate_idx = aac_rate_idx (audiocontext->samplerate);
5422 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5423 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5424 data[4] = (1 << 7) | (rate_idx << 3);
5425 gst_buffer_unmap (priv, &map);
5427 gst_buffer_unmap (priv, &map);
5428 gst_buffer_set_size (priv, 2);
5431 gst_buffer_unmap (priv, &map);
5432 gst_buffer_unref (priv);
5434 GST_ERROR ("Unknown AAC profile and no codec private data");
5439 caps = gst_caps_new_simple ("audio/mpeg",
5440 "mpegversion", G_TYPE_INT, mpegversion,
5441 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5442 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5443 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5444 gst_buffer_unref (priv);
5446 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5447 caps = gst_caps_new_simple ("audio/x-tta",
5448 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5449 *codec_name = g_strdup ("TTA audio");
5450 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5451 caps = gst_caps_new_simple ("audio/x-wavpack",
5452 "width", G_TYPE_INT, audiocontext->bitdepth,
5453 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5454 *codec_name = g_strdup ("Wavpack audio");
5455 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5456 audiocontext->wvpk_block_index = 0;
5457 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5458 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5459 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5460 gint raversion = -1;
5462 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5464 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5469 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5470 "raversion", G_TYPE_INT, raversion, NULL);
5471 /* Extract extra information from caps, mapping varies based on codec */
5472 if (data && (size >= 0x50)) {
5479 guint extra_data_size;
5481 GST_ERROR ("real audio raversion:%d", raversion);
5482 if (raversion == 8) {
5484 flavor = GST_READ_UINT16_BE (data + 22);
5485 packet_size = GST_READ_UINT32_BE (data + 24);
5486 height = GST_READ_UINT16_BE (data + 40);
5487 leaf_size = GST_READ_UINT16_BE (data + 44);
5488 sample_width = GST_READ_UINT16_BE (data + 58);
5489 extra_data_size = GST_READ_UINT32_BE (data + 74);
5492 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5493 flavor, packet_size, height, leaf_size, sample_width,
5495 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5496 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5497 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5499 if ((size - 78) >= extra_data_size) {
5500 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5502 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5503 gst_buffer_unref (priv);
5508 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5509 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5510 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5511 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5512 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5513 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5514 *codec_name = g_strdup ("Real Audio Lossless");
5515 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5516 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5517 *codec_name = g_strdup ("Sony ATRAC3");
5519 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5524 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5527 for (i = 0; i < gst_caps_get_size (caps); i++) {
5528 gst_structure_set (gst_caps_get_structure (caps, i),
5529 "channels", G_TYPE_INT, audiocontext->channels,
5530 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5534 caps = gst_caps_simplify (caps);
5541 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5542 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5544 GstCaps *caps = NULL;
5545 GstMatroskaTrackContext *context =
5546 (GstMatroskaTrackContext *) subtitlecontext;
5548 /* for backwards compatibility */
5549 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5550 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5551 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5552 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5553 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5554 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5555 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5556 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5558 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5559 * Check if we have to do something with codec_private */
5560 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5561 /* well, plain text simply does not have a lot of markup ... */
5562 caps = gst_caps_new_empty_simple ("text/x-pango-markup");
5563 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5564 subtitlecontext->check_markup = TRUE;
5565 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5566 caps = gst_caps_new_empty_simple ("application/x-ssa");
5567 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5568 subtitlecontext->check_markup = FALSE;
5569 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5570 caps = gst_caps_new_empty_simple ("application/x-ass");
5571 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5572 subtitlecontext->check_markup = FALSE;
5573 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5574 caps = gst_caps_new_empty_simple ("application/x-usf");
5575 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5576 subtitlecontext->check_markup = FALSE;
5577 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5578 caps = gst_caps_new_empty_simple ("video/x-dvd-subpicture");
5579 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5580 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5581 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5582 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5583 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5584 context->send_xiph_headers = TRUE;
5586 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5587 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5590 if (data != NULL && size > 0) {
5593 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5594 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5595 gst_buffer_unref (buf);
5603 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5605 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5607 GST_OBJECT_LOCK (demux);
5608 if (demux->common.element_index)
5609 gst_object_unref (demux->common.element_index);
5610 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5611 GST_OBJECT_UNLOCK (demux);
5612 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5613 demux->common.element_index);
5617 gst_matroska_demux_get_index (GstElement * element)
5619 GstIndex *result = NULL;
5620 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5622 GST_OBJECT_LOCK (demux);
5623 if (demux->common.element_index)
5624 result = gst_object_ref (demux->common.element_index);
5625 GST_OBJECT_UNLOCK (demux);
5627 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5633 static GstStateChangeReturn
5634 gst_matroska_demux_change_state (GstElement * element,
5635 GstStateChange transition)
5637 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5638 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5640 /* handle upwards state changes here */
5641 switch (transition) {
5646 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5648 /* handle downwards state changes */
5649 switch (transition) {
5650 case GST_STATE_CHANGE_PAUSED_TO_READY:
5651 gst_matroska_demux_reset (GST_ELEMENT (demux));
5661 gst_matroska_demux_set_property (GObject * object,
5662 guint prop_id, const GValue * value, GParamSpec * pspec)
5664 GstMatroskaDemux *demux;
5666 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5667 demux = GST_MATROSKA_DEMUX (object);
5670 case ARG_MAX_GAP_TIME:
5671 GST_OBJECT_LOCK (demux);
5672 demux->max_gap_time = g_value_get_uint64 (value);
5673 GST_OBJECT_UNLOCK (demux);
5676 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5682 gst_matroska_demux_get_property (GObject * object,
5683 guint prop_id, GValue * value, GParamSpec * pspec)
5685 GstMatroskaDemux *demux;
5687 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5688 demux = GST_MATROSKA_DEMUX (object);
5691 case ARG_MAX_GAP_TIME:
5692 GST_OBJECT_LOCK (demux);
5693 g_value_set_uint64 (value, demux->max_gap_time);
5694 GST_OBJECT_UNLOCK (demux);
5697 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5703 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5707 /* parser helper separate debug */
5708 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5709 0, "EBML stream helper class");
5711 /* create an elementfactory for the matroska_demux element */
5712 if (!gst_element_register (plugin, "matroskademux",
5713 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))