1 /* GStreamer Matroska muxer/demuxer
2 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3 * (c) 2006 Tim-Philipp Müller <tim centricular net>
4 * (c) 2008 Sebastian Dröge <slomo@circular-chaos.org>
5 * (c) 2011 Debarshi Ray <rishi@gnu.org>
7 * matroska-demux.c: matroska file/stream demuxer
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
25 /* TODO: check CRC32 if present
26 * TODO: there can be a segment after the first segment. Handle like
27 * chained oggs. Fixes #334082
28 * TODO: Test samples: http://www.matroska.org/samples/matrix/index.html
29 * http://samples.mplayerhq.hu/Matroska/
30 * TODO: check if demuxing is done correct for all codecs according to spec
31 * TODO: seeking with incomplete or without CUE
35 * SECTION:element-matroskademux
37 * matroskademux demuxes a Matroska file into the different contained streams.
40 * <title>Example launch line</title>
42 * gst-launch -v filesrc location=/path/to/mkv ! matroskademux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
43 * ]| This pipeline demuxes a Matroska file and outputs the contained Vorbis audio.
54 #include <glib/gprintf.h>
56 /* For AVI compatibility mode
57 and for fourcc stuff */
58 #include <gst/riff/riff-read.h>
59 #include <gst/riff/riff-ids.h>
60 #include <gst/riff/riff-media.h>
62 #include <gst/audio/audio.h>
63 #include <gst/tag/tag.h>
64 #include <gst/pbutils/pbutils.h>
66 #include "matroska-demux.h"
67 #include "matroska-ids.h"
69 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
70 #define GST_CAT_DEFAULT matroskademux_debug
72 #define DEBUG_ELEMENT_START(demux, ebml, element) \
73 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
74 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
76 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
77 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
78 " finished with '%s'", gst_flow_get_name (ret))
88 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
90 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
93 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
94 "video/x-matroska-3d; audio/webm; video/webm")
97 /* TODO: fill in caps! */
99 static GstStaticPadTemplate audio_src_templ =
100 GST_STATIC_PAD_TEMPLATE ("audio_%u",
103 GST_STATIC_CAPS ("ANY")
106 static GstStaticPadTemplate video_src_templ =
107 GST_STATIC_PAD_TEMPLATE ("video_%u",
110 GST_STATIC_CAPS ("ANY")
113 static GstStaticPadTemplate subtitle_src_templ =
114 GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
117 GST_STATIC_CAPS ("text/x-pango-markup; application/x-ssa; "
118 "application/x-ass;application/x-usf; video/x-dvd-subpicture; "
119 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
122 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
123 guint32 id, guint64 length, guint needed);
125 /* element functions */
126 static void gst_matroska_demux_loop (GstPad * pad);
128 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
130 static gboolean gst_matroska_demux_element_query (GstElement * element,
134 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad,
136 static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
137 GstObject * parent, GstPadMode mode, gboolean active);
139 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
140 GstPad * pad, GstEvent * event);
141 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
142 GstObject * parent, GstEvent * event);
143 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
144 GstObject * parent, GstQuery * query);
146 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
147 GstObject * parent, GstEvent * event);
148 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
149 GstObject * object, GstBuffer * buffer);
151 static GstStateChangeReturn
152 gst_matroska_demux_change_state (GstElement * element,
153 GstStateChange transition);
156 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
157 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
161 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
162 * videocontext, const gchar * codec_id, guint8 * data, guint size,
163 gchar ** codec_name, guint32 * riff_fourcc);
164 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
165 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
166 gchar ** codec_name, guint16 * riff_audio_fmt);
168 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
169 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
172 static void gst_matroska_demux_reset (GstElement * element);
173 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
176 /* gobject functions */
177 static void gst_matroska_demux_set_property (GObject * object,
178 guint prop_id, const GValue * value, GParamSpec * pspec);
179 static void gst_matroska_demux_get_property (GObject * object,
180 guint prop_id, GValue * value, GParamSpec * pspec);
182 GType gst_matroska_demux_get_type (void);
183 #define parent_class gst_matroska_demux_parent_class
184 G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
187 gst_matroska_demux_finalize (GObject * object)
189 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
191 if (demux->common.src) {
192 g_ptr_array_free (demux->common.src, TRUE);
193 demux->common.src = NULL;
196 if (demux->common.global_tags) {
197 gst_tag_list_free (demux->common.global_tags);
198 demux->common.global_tags = NULL;
201 g_object_unref (demux->common.adapter);
203 G_OBJECT_CLASS (parent_class)->finalize (object);
207 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
209 GObjectClass *gobject_class = (GObjectClass *) klass;
210 GstElementClass *gstelement_class = (GstElementClass *) klass;
212 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
215 gobject_class->finalize = gst_matroska_demux_finalize;
217 gobject_class->get_property = gst_matroska_demux_get_property;
218 gobject_class->set_property = gst_matroska_demux_set_property;
220 g_object_class_install_property (gobject_class, ARG_MAX_GAP_TIME,
221 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
222 "The demuxer sends out segment events for skipping "
223 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
224 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
226 gstelement_class->change_state =
227 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
228 gstelement_class->send_event =
229 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
230 gstelement_class->query =
231 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
233 gstelement_class->set_index =
234 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
235 gstelement_class->get_index =
236 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
239 gst_element_class_add_pad_template (gstelement_class,
240 gst_static_pad_template_get (&video_src_templ));
241 gst_element_class_add_pad_template (gstelement_class,
242 gst_static_pad_template_get (&audio_src_templ));
243 gst_element_class_add_pad_template (gstelement_class,
244 gst_static_pad_template_get (&subtitle_src_templ));
245 gst_element_class_add_pad_template (gstelement_class,
246 gst_static_pad_template_get (&sink_templ));
248 gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
250 "Demuxes Matroska/WebM streams into video/audio/subtitles",
251 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
255 gst_matroska_demux_init (GstMatroskaDemux * demux)
257 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
259 gst_pad_set_activate_function (demux->common.sinkpad,
260 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
261 gst_pad_set_activatemode_function (demux->common.sinkpad,
262 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
263 gst_pad_set_chain_function (demux->common.sinkpad,
264 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
265 gst_pad_set_event_function (demux->common.sinkpad,
266 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
267 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
269 /* initial stream no. */
270 demux->common.src = NULL;
272 demux->common.writing_app = NULL;
273 demux->common.muxing_app = NULL;
274 demux->common.index = NULL;
275 demux->common.global_tags = NULL;
277 demux->common.adapter = gst_adapter_new ();
279 /* property defaults */
280 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
282 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
285 gst_matroska_demux_reset (GST_ELEMENT (demux));
289 gst_matroska_track_free (GstMatroskaTrackContext * track)
291 g_free (track->codec_id);
292 g_free (track->codec_name);
293 g_free (track->name);
294 g_free (track->language);
295 g_free (track->codec_priv);
296 g_free (track->codec_state);
298 if (track->encodings != NULL) {
301 for (i = 0; i < track->encodings->len; ++i) {
302 GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
303 GstMatroskaTrackEncoding,
306 g_free (enc->comp_settings);
308 g_array_free (track->encodings, TRUE);
311 if (track->pending_tags)
312 gst_tag_list_free (track->pending_tags);
314 if (track->index_table)
315 g_array_free (track->index_table, TRUE);
321 * Returns the aggregated GstFlowReturn.
324 gst_matroska_demux_combine_flows (GstMatroskaDemux * demux,
325 GstMatroskaTrackContext * track, GstFlowReturn ret)
329 /* store the value */
330 track->last_flow = ret;
332 /* any other error that is not-linked can be returned right away */
333 if (ret != GST_FLOW_NOT_LINKED)
336 /* only return NOT_LINKED if all other pads returned NOT_LINKED */
337 g_assert (demux->common.src->len == demux->common.num_streams);
338 for (i = 0; i < demux->common.src->len; i++) {
339 GstMatroskaTrackContext *ostream = g_ptr_array_index (demux->common.src,
345 ret = ostream->last_flow;
346 /* some other return value (must be SUCCESS but we can return
347 * other values as well) */
348 if (ret != GST_FLOW_NOT_LINKED)
351 /* if we get here, all other pads were unlinked and we return
354 GST_LOG_OBJECT (demux, "combined return %s", gst_flow_get_name (ret));
359 gst_matroska_demux_free_parsed_el (gpointer mem, gpointer user_data)
361 g_slice_free (guint64, mem);
365 gst_matroska_demux_reset (GstElement * element)
367 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
370 GST_DEBUG_OBJECT (demux, "Resetting state");
373 demux->common.state = GST_MATROSKA_READ_STATE_START;
375 /* clean up existing streams */
376 if (demux->common.src) {
377 g_assert (demux->common.src->len == demux->common.num_streams);
378 for (i = 0; i < demux->common.src->len; i++) {
379 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
382 if (context->pad != NULL)
383 gst_element_remove_pad (GST_ELEMENT (demux), context->pad);
385 gst_caps_replace (&context->caps, NULL);
386 gst_matroska_track_free (context);
388 g_ptr_array_free (demux->common.src, TRUE);
390 demux->common.src = g_ptr_array_new ();
392 demux->common.num_streams = 0;
393 demux->num_a_streams = 0;
394 demux->num_t_streams = 0;
395 demux->num_v_streams = 0;
397 /* reset media info */
398 g_free (demux->common.writing_app);
399 demux->common.writing_app = NULL;
400 g_free (demux->common.muxing_app);
401 demux->common.muxing_app = NULL;
404 if (demux->common.index) {
405 g_array_free (demux->common.index, TRUE);
406 demux->common.index = NULL;
409 if (demux->clusters) {
410 g_array_free (demux->clusters, TRUE);
411 demux->clusters = NULL;
416 demux->common.time_scale = 1000000;
417 demux->common.created = G_MININT64;
419 demux->common.index_parsed = FALSE;
420 demux->tracks_parsed = FALSE;
421 demux->common.segmentinfo_parsed = FALSE;
422 demux->common.attachments_parsed = FALSE;
423 demux->common.chapters_parsed = FALSE;
425 g_list_foreach (demux->common.tags_parsed,
426 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
427 g_list_free (demux->common.tags_parsed);
428 demux->common.tags_parsed = NULL;
430 g_list_foreach (demux->seek_parsed,
431 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
432 g_list_free (demux->seek_parsed);
433 demux->seek_parsed = NULL;
435 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
436 demux->last_stop_end = GST_CLOCK_TIME_NONE;
437 demux->seek_block = 0;
438 demux->stream_start_time = GST_CLOCK_TIME_NONE;
440 demux->common.offset = 0;
441 demux->cluster_time = GST_CLOCK_TIME_NONE;
442 demux->cluster_offset = 0;
443 demux->next_cluster_offset = 0;
444 demux->index_offset = 0;
445 demux->seekable = FALSE;
446 demux->need_segment = FALSE;
447 demux->building_index = FALSE;
448 if (demux->seek_event) {
449 gst_event_unref (demux->seek_event);
450 demux->seek_event = NULL;
453 demux->seek_index = NULL;
454 demux->seek_entry = 0;
456 if (demux->new_segment) {
457 gst_event_unref (demux->new_segment);
458 demux->new_segment = NULL;
461 if (demux->common.element_index) {
462 gst_object_unref (demux->common.element_index);
463 demux->common.element_index = NULL;
465 demux->common.element_index_writer_id = -1;
468 if (demux->common.global_tags) {
469 gst_tag_list_free (demux->common.global_tags);
471 demux->common.global_tags = gst_tag_list_new_empty ();
473 if (demux->common.cached_buffer) {
474 if (demux->common.cached_data) {
475 gst_buffer_unmap (demux->common.cached_buffer, &demux->common.cached_map);
476 demux->common.cached_data = NULL;
478 gst_buffer_unref (demux->common.cached_buffer);
479 demux->common.cached_buffer = NULL;
482 /* free chapters TOC if any */
483 if (demux->common.toc) {
484 gst_toc_free (demux->common.toc);
485 demux->common.toc = NULL;
488 demux->invalid_duration = FALSE;
492 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
498 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
500 GST_DEBUG ("decoding buffer %p", buf);
502 gst_buffer_map (buf, &map, GST_MAP_READ);
506 g_return_val_if_fail (size > 0, buf);
508 if (gst_matroska_decode_data (context->encodings, &data, &size,
509 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
510 gst_buffer_unmap (buf, &map);
511 gst_buffer_unref (buf);
512 return gst_buffer_new_wrapped (data, size);
514 GST_DEBUG ("decode data failed");
515 gst_buffer_unmap (buf, &map);
516 gst_buffer_unref (buf);
522 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
524 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
525 GstMatroskaTrackContext *context;
526 GstPadTemplate *templ = NULL;
527 GstCaps *caps = NULL;
528 gchar *padname = NULL;
530 guint32 id, riff_fourcc = 0;
531 guint16 riff_audio_fmt = 0;
532 GstTagList *list = NULL;
535 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
537 /* start with the master */
538 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
539 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
543 /* allocate generic... if we know the type, we'll g_renew()
544 * with the precise type */
545 context = g_new0 (GstMatroskaTrackContext, 1);
546 g_ptr_array_add (demux->common.src, context);
547 context->index = demux->common.num_streams;
548 context->index_writer_id = -1;
549 context->type = 0; /* no type yet */
550 context->default_duration = 0;
552 context->set_discont = TRUE;
553 context->timecodescale = 1.0;
555 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
556 GST_MATROSKA_TRACK_LACING;
557 context->last_flow = GST_FLOW_OK;
558 context->to_offset = G_MAXINT64;
559 context->alignment = 1;
560 demux->common.num_streams++;
561 g_assert (demux->common.src->len == demux->common.num_streams);
563 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
565 /* try reading the trackentry headers */
566 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
567 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
571 /* track number (unique stream ID) */
572 case GST_MATROSKA_ID_TRACKNUMBER:{
575 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
579 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
580 ret = GST_FLOW_ERROR;
582 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
584 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
585 " is not unique", num);
586 ret = GST_FLOW_ERROR;
590 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
594 /* track UID (unique identifier) */
595 case GST_MATROSKA_ID_TRACKUID:{
598 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
602 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
603 ret = GST_FLOW_ERROR;
607 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
612 /* track type (video, audio, combined, subtitle, etc.) */
613 case GST_MATROSKA_ID_TRACKTYPE:{
616 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
620 if (context->type != 0 && context->type != track_type) {
621 GST_WARNING_OBJECT (demux,
622 "More than one tracktype defined in a TrackEntry - skipping");
624 } else if (track_type < 1 || track_type > 254) {
625 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
630 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
632 /* ok, so we're actually going to reallocate this thing */
633 switch (track_type) {
634 case GST_MATROSKA_TRACK_TYPE_VIDEO:
635 gst_matroska_track_init_video_context (&context);
637 case GST_MATROSKA_TRACK_TYPE_AUDIO:
638 gst_matroska_track_init_audio_context (&context);
640 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
641 gst_matroska_track_init_subtitle_context (&context);
643 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
644 case GST_MATROSKA_TRACK_TYPE_LOGO:
645 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
646 case GST_MATROSKA_TRACK_TYPE_CONTROL:
648 GST_WARNING_OBJECT (demux,
649 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
654 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
659 /* tracktype specific stuff for video */
660 case GST_MATROSKA_ID_TRACKVIDEO:{
661 GstMatroskaTrackVideoContext *videocontext;
663 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
665 if (!gst_matroska_track_init_video_context (&context)) {
666 GST_WARNING_OBJECT (demux,
667 "TrackVideo element in non-video track - ignoring track");
668 ret = GST_FLOW_ERROR;
670 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
673 videocontext = (GstMatroskaTrackVideoContext *) context;
674 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
677 while (ret == GST_FLOW_OK &&
678 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
679 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
683 /* Should be one level up but some broken muxers write it here. */
684 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
687 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
691 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
695 GST_DEBUG_OBJECT (demux,
696 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
697 context->default_duration = num;
701 /* video framerate */
702 /* NOTE: This one is here only for backward compatibility.
703 * Use _TRACKDEFAULDURATION one level up. */
704 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
707 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
711 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
715 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
716 if (context->default_duration == 0)
717 context->default_duration =
718 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
719 videocontext->default_fps = num;
723 /* width of the size to display the video at */
724 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
727 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
731 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
735 GST_DEBUG_OBJECT (demux,
736 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
737 videocontext->display_width = num;
741 /* height of the size to display the video at */
742 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
745 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
749 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
753 GST_DEBUG_OBJECT (demux,
754 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
755 videocontext->display_height = num;
759 /* width of the video in the file */
760 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
763 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
767 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
771 GST_DEBUG_OBJECT (demux,
772 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
773 videocontext->pixel_width = num;
777 /* height of the video in the file */
778 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
781 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
785 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
789 GST_DEBUG_OBJECT (demux,
790 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
791 videocontext->pixel_height = num;
795 /* whether the video is interlaced */
796 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
799 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
803 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
805 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
806 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
807 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
812 /* aspect ratio behaviour */
813 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
816 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
819 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
820 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
821 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
822 GST_WARNING_OBJECT (demux,
823 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
826 GST_DEBUG_OBJECT (demux,
827 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
828 videocontext->asr_mode = num;
832 /* colourspace (only matters for raw video) fourcc */
833 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
838 gst_ebml_read_binary (ebml, &id, &data,
839 &datalen)) != GST_FLOW_OK)
844 GST_WARNING_OBJECT (demux,
845 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
850 memcpy (&videocontext->fourcc, data, 4);
851 GST_DEBUG_OBJECT (demux,
852 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
853 GST_FOURCC_ARGS (videocontext->fourcc));
859 GST_WARNING_OBJECT (demux,
860 "Unknown TrackVideo subelement 0x%x - ignoring", id);
862 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
863 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
864 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
865 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
866 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
867 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
868 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
869 ret = gst_ebml_read_skip (ebml);
874 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
878 /* tracktype specific stuff for audio */
879 case GST_MATROSKA_ID_TRACKAUDIO:{
880 GstMatroskaTrackAudioContext *audiocontext;
882 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
884 if (!gst_matroska_track_init_audio_context (&context)) {
885 GST_WARNING_OBJECT (demux,
886 "TrackAudio element in non-audio track - ignoring track");
887 ret = GST_FLOW_ERROR;
891 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
894 audiocontext = (GstMatroskaTrackAudioContext *) context;
895 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
898 while (ret == GST_FLOW_OK &&
899 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
900 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
905 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
908 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
913 GST_WARNING_OBJECT (demux,
914 "Invalid TrackAudioSamplingFrequency %lf", num);
918 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
919 audiocontext->samplerate = num;
924 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
927 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
931 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
935 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
937 audiocontext->bitdepth = num;
942 case GST_MATROSKA_ID_AUDIOCHANNELS:{
945 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
949 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
953 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
955 audiocontext->channels = num;
960 GST_WARNING_OBJECT (demux,
961 "Unknown TrackAudio subelement 0x%x - ignoring", id);
963 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
964 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
965 ret = gst_ebml_read_skip (ebml);
970 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
975 /* codec identifier */
976 case GST_MATROSKA_ID_CODECID:{
979 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
982 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
983 context->codec_id = text;
987 /* codec private data */
988 case GST_MATROSKA_ID_CODECPRIVATE:{
993 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
996 context->codec_priv = data;
997 context->codec_priv_size = size;
999 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1004 /* name of the codec */
1005 case GST_MATROSKA_ID_CODECNAME:{
1008 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1011 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1012 context->codec_name = text;
1016 /* name of this track */
1017 case GST_MATROSKA_ID_TRACKNAME:{
1020 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1023 context->name = text;
1024 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1028 /* language (matters for audio/subtitles, mostly) */
1029 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1032 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1036 context->language = text;
1039 if (strlen (context->language) >= 4 && context->language[3] == '-')
1040 context->language[3] = '\0';
1042 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1043 GST_STR_NULL (context->language));
1047 /* whether this is actually used */
1048 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1051 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1055 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1057 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1059 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1060 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1064 /* whether it's the default for this track type */
1065 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1068 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1072 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1074 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1076 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1077 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1081 /* whether the track must be used during playback */
1082 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1085 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1089 context->flags |= GST_MATROSKA_TRACK_FORCED;
1091 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1093 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1094 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1098 /* lacing (like MPEG, where blocks don't end/start on frame
1100 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1103 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1107 context->flags |= GST_MATROSKA_TRACK_LACING;
1109 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1111 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1112 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1116 /* default length (in time) of one data block in this track */
1117 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1120 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1125 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1129 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1131 context->default_duration = num;
1135 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1136 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1141 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1144 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1148 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1152 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1153 context->timecodescale = num;
1158 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1161 /* we ignore these because they're nothing useful (i.e. crap)
1162 * or simply not implemented yet. */
1163 case GST_MATROSKA_ID_TRACKMINCACHE:
1164 case GST_MATROSKA_ID_TRACKMAXCACHE:
1165 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1166 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1167 case GST_MATROSKA_ID_TRACKOVERLAY:
1168 case GST_MATROSKA_ID_TRACKTRANSLATE:
1169 case GST_MATROSKA_ID_TRACKOFFSET:
1170 case GST_MATROSKA_ID_CODECSETTINGS:
1171 case GST_MATROSKA_ID_CODECINFOURL:
1172 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1173 case GST_MATROSKA_ID_CODECDECODEALL:
1174 ret = gst_ebml_read_skip (ebml);
1179 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1181 /* Decode codec private data if necessary */
1182 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1183 && context->codec_priv_size > 0) {
1184 if (!gst_matroska_decode_data (context->encodings,
1185 &context->codec_priv, &context->codec_priv_size,
1186 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1187 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1188 ret = GST_FLOW_ERROR;
1192 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1193 && ret != GST_FLOW_EOS)) {
1194 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1195 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1197 demux->common.num_streams--;
1198 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1199 g_assert (demux->common.src->len == demux->common.num_streams);
1201 gst_matroska_track_free (context);
1207 /* now create the GStreamer connectivity */
1208 switch (context->type) {
1209 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1210 GstMatroskaTrackVideoContext *videocontext =
1211 (GstMatroskaTrackVideoContext *) context;
1213 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1214 templ = gst_element_class_get_pad_template (klass, "video_%u");
1215 caps = gst_matroska_demux_video_caps (videocontext,
1216 context->codec_id, context->codec_priv,
1217 context->codec_priv_size, &codec, &riff_fourcc);
1220 list = gst_tag_list_new (GST_TAG_VIDEO_CODEC, codec, NULL);
1226 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1227 GstMatroskaTrackAudioContext *audiocontext =
1228 (GstMatroskaTrackAudioContext *) context;
1230 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1231 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1232 caps = gst_matroska_demux_audio_caps (audiocontext,
1233 context->codec_id, context->codec_priv, context->codec_priv_size,
1234 &codec, &riff_audio_fmt);
1237 list = gst_tag_list_new (GST_TAG_AUDIO_CODEC, codec, NULL);
1243 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1244 GstMatroskaTrackSubtitleContext *subtitlecontext =
1245 (GstMatroskaTrackSubtitleContext *) context;
1247 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1248 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1249 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1250 context->codec_id, context->codec_priv, context->codec_priv_size);
1254 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1255 case GST_MATROSKA_TRACK_TYPE_LOGO:
1256 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1257 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1259 /* we should already have quit by now */
1260 g_assert_not_reached ();
1263 if ((context->language == NULL || *context->language == '\0') &&
1264 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1265 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1266 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1267 context->language = g_strdup ("eng");
1270 if (context->language) {
1274 list = gst_tag_list_new_empty ();
1276 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1277 lang = gst_tag_get_language_code (context->language);
1278 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1279 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1283 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1284 "codec_id='%s'", context->codec_id);
1285 switch (context->type) {
1286 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1287 caps = gst_caps_new_empty_simple ("video/x-unknown");
1289 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1290 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1292 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1293 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1295 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1297 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1300 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1303 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1304 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1305 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1306 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1307 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1308 GST_FOURCC_ARGS (riff_fourcc));
1309 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1314 /* the pad in here */
1315 context->pad = gst_pad_new_from_template (templ, padname);
1316 context->caps = caps;
1318 gst_pad_set_event_function (context->pad,
1319 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1320 gst_pad_set_query_function (context->pad,
1321 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1323 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1326 context->pending_tags = list;
1328 gst_pad_set_element_private (context->pad, context);
1330 gst_pad_use_fixed_caps (context->pad);
1331 gst_pad_set_active (context->pad, TRUE);
1332 gst_pad_set_caps (context->pad, context->caps);
1333 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1342 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1345 gboolean res = FALSE;
1346 GstMatroskaTrackContext *context = NULL;
1349 context = gst_pad_get_element_private (pad);
1352 switch (GST_QUERY_TYPE (query)) {
1353 case GST_QUERY_POSITION:
1357 gst_query_parse_position (query, &format, NULL);
1359 if (format == GST_FORMAT_TIME) {
1360 GST_OBJECT_LOCK (demux);
1362 gst_query_set_position (query, GST_FORMAT_TIME,
1363 MAX (context->pos, demux->stream_start_time) -
1364 demux->stream_start_time);
1366 gst_query_set_position (query, GST_FORMAT_TIME,
1367 MAX (demux->common.segment.position, demux->stream_start_time) -
1368 demux->stream_start_time);
1369 GST_OBJECT_UNLOCK (demux);
1370 } else if (format == GST_FORMAT_DEFAULT && context
1371 && context->default_duration) {
1372 GST_OBJECT_LOCK (demux);
1373 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1374 context->pos / context->default_duration);
1375 GST_OBJECT_UNLOCK (demux);
1377 GST_DEBUG_OBJECT (demux,
1378 "only position query in TIME and DEFAULT format is supported");
1384 case GST_QUERY_DURATION:
1388 gst_query_parse_duration (query, &format, NULL);
1390 if (format == GST_FORMAT_TIME) {
1391 GST_OBJECT_LOCK (demux);
1392 gst_query_set_duration (query, GST_FORMAT_TIME,
1393 demux->common.segment.duration);
1394 GST_OBJECT_UNLOCK (demux);
1395 } else if (format == GST_FORMAT_DEFAULT && context
1396 && context->default_duration) {
1397 GST_OBJECT_LOCK (demux);
1398 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1399 demux->common.segment.duration / context->default_duration);
1400 GST_OBJECT_UNLOCK (demux);
1402 GST_DEBUG_OBJECT (demux,
1403 "only duration query in TIME and DEFAULT format is supported");
1410 case GST_QUERY_SEEKING:
1414 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1415 GST_OBJECT_LOCK (demux);
1416 if (fmt == GST_FORMAT_TIME) {
1419 if (demux->streaming) {
1420 /* assuming we'll be able to get an index ... */
1421 seekable = demux->seekable;
1426 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1427 0, demux->common.segment.duration);
1430 GST_OBJECT_UNLOCK (demux);
1438 GST_OBJECT_LOCK (demux);
1439 if (demux->common.toc)
1440 toc = demux->common.toc;
1442 toc = gst_toc_new ();
1443 gst_query_set_toc (query, toc, 0);
1445 if (!demux->common.toc)
1447 GST_OBJECT_UNLOCK (demux);
1451 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1459 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1461 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1465 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1468 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1470 return gst_matroska_demux_query (demux, pad, query);
1473 /* returns FALSE if there are no pads to deliver event to,
1474 * otherwise TRUE (whatever the outcome of event sending),
1475 * takes ownership of the passed event! */
1477 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1479 gboolean is_segment;
1480 gboolean ret = FALSE;
1483 g_return_val_if_fail (event != NULL, FALSE);
1485 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1486 GST_EVENT_TYPE_NAME (event));
1488 is_segment = (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
1490 g_assert (demux->common.src->len == demux->common.num_streams);
1491 for (i = 0; i < demux->common.src->len; i++) {
1492 GstMatroskaTrackContext *stream;
1494 stream = g_ptr_array_index (demux->common.src, i);
1495 gst_event_ref (event);
1496 gst_pad_push_event (stream->pad, event);
1499 /* FIXME: send global tags before stream tags */
1500 if (G_UNLIKELY (is_segment && stream->pending_tags != NULL)) {
1501 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
1502 GST_PTR_FORMAT, stream->pending_tags,
1503 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
1504 gst_pad_push_event (stream->pad,
1505 gst_event_new_tag ("GstDemuxer", stream->pending_tags));
1506 stream->pending_tags = NULL;
1510 if (G_UNLIKELY (is_segment && demux->common.global_tags != NULL)) {
1511 GstEvent *tag_event;
1512 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1513 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1514 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1515 demux->common.global_tags, demux->common.global_tags);
1517 tag_event = gst_event_new_tag ("GstDemuxer", demux->common.global_tags);
1519 for (i = 0; i < demux->common.src->len; i++) {
1520 GstMatroskaTrackContext *stream;
1522 stream = g_ptr_array_index (demux->common.src, i);
1523 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1526 gst_event_unref (tag_event);
1527 demux->common.global_tags = NULL;
1530 gst_event_unref (event);
1535 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1537 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1540 g_return_val_if_fail (event != NULL, FALSE);
1542 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1543 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1545 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1546 GST_EVENT_TYPE_NAME (event));
1549 gst_event_unref (event);
1554 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1555 GstMatroskaIndex * entry, gboolean reset)
1559 GST_OBJECT_LOCK (demux);
1561 /* seek (relative to matroska segment) */
1562 /* position might be invalid; will error when streaming resumes ... */
1563 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1565 GST_DEBUG_OBJECT (demux, "Seeked to offset %" G_GUINT64_FORMAT ", block %d, "
1566 "time %" GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1567 entry->block, GST_TIME_ARGS (entry->time));
1569 /* update the time */
1570 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1571 demux->common.segment.position = entry->time;
1572 demux->seek_block = entry->block;
1573 demux->seek_first = TRUE;
1574 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1576 for (i = 0; i < demux->common.src->len; i++) {
1577 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1580 stream->to_offset = G_MAXINT64;
1582 if (stream->from_offset != -1)
1583 stream->to_offset = stream->from_offset;
1585 stream->from_offset = -1;
1588 GST_OBJECT_UNLOCK (demux);
1594 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1604 /* searches for a cluster start from @pos,
1605 * return GST_FLOW_OK and cluster position in @pos if found */
1606 static GstFlowReturn
1607 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1609 gint64 newpos = *pos;
1611 GstFlowReturn ret = GST_FLOW_OK;
1612 const guint chunk = 64 * 1024;
1613 GstBuffer *buf = NULL;
1615 gpointer data = NULL;
1621 orig_offset = demux->common.offset;
1623 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1626 if (demux->clusters) {
1629 cpos = gst_util_array_binary_search (demux->clusters->data,
1630 demux->clusters->len, sizeof (gint64),
1631 (GCompareDataFunc) gst_matroska_cluster_compare,
1632 GST_SEARCH_MODE_AFTER, pos, NULL);
1635 GST_DEBUG_OBJECT (demux,
1636 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1637 demux->common.offset = *cpos;
1638 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1639 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1640 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1647 /* read in at newpos and scan for ebml cluster id */
1649 GstByteReader reader;
1653 gst_buffer_unmap (buf, &map);
1654 gst_buffer_unref (buf);
1657 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1658 if (ret != GST_FLOW_OK)
1660 GST_DEBUG_OBJECT (demux,
1661 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1662 gst_buffer_get_size (buf), newpos);
1663 gst_buffer_map (buf, &map, GST_MAP_READ);
1666 gst_byte_reader_init (&reader, data, size);
1668 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1669 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1670 if (cluster_pos >= 0) {
1671 newpos += cluster_pos;
1672 /* prepare resuming at next byte */
1673 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1674 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1677 GST_DEBUG_OBJECT (demux,
1678 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1679 /* extra checks whether we really sync'ed to a cluster:
1680 * - either it is the first and only cluster
1681 * - either there is a cluster after this one
1682 * - either cluster length is undefined
1684 /* ok if first cluster (there may not a subsequent one) */
1685 if (newpos == demux->first_cluster_offset) {
1686 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1689 demux->common.offset = newpos;
1690 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1691 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1692 if (ret != GST_FLOW_OK) {
1693 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1696 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1697 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1699 /* ok if undefined length or first cluster */
1700 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1701 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1705 demux->common.offset += length + needed;
1706 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1707 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1708 if (ret != GST_FLOW_OK)
1710 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1711 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1712 if (id == GST_MATROSKA_ID_CLUSTER)
1714 /* not ok, resume */
1717 /* partial cluster id may have been in tail of buffer */
1718 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1723 gst_buffer_unmap (buf, &map);
1724 gst_buffer_unref (buf);
1729 demux->common.offset = orig_offset;
1734 /* bisect and scan through file for cluster starting before @time,
1735 * returns fake index entry with corresponding info on cluster */
1736 static GstMatroskaIndex *
1737 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1739 GstMatroskaIndex *entry = NULL;
1740 GstMatroskaReadState current_state;
1741 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1742 gint64 opos, newpos, startpos = 0, current_offset;
1743 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1744 const guint chunk = 64 * 1024;
1750 /* (under)estimate new position, resync using cluster ebml id,
1751 * and scan forward to appropriate cluster
1752 * (and re-estimate if need to go backward) */
1754 prev_cluster_time = GST_CLOCK_TIME_NONE;
1756 /* store some current state */
1757 current_state = demux->common.state;
1758 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1760 current_cluster_offset = demux->cluster_offset;
1761 current_cluster_time = demux->cluster_time;
1762 current_offset = demux->common.offset;
1764 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1766 /* estimate using start and current position */
1767 GST_OBJECT_LOCK (demux);
1768 opos = demux->common.offset - demux->common.ebml_segment_start;
1769 otime = demux->common.segment.position;
1770 GST_OBJECT_UNLOCK (demux);
1773 time = MAX (time, demux->stream_start_time);
1775 /* avoid division by zero in first estimation below */
1776 if (otime <= demux->stream_start_time)
1780 GST_LOG_OBJECT (demux,
1781 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1782 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1783 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1784 GST_TIME_ARGS (otime - demux->stream_start_time),
1785 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1787 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1788 time - demux->stream_start_time,
1789 otime - demux->stream_start_time) - chunk;
1792 /* favour undershoot */
1793 newpos = newpos * 90 / 100;
1794 newpos += demux->common.ebml_segment_start;
1796 GST_DEBUG_OBJECT (demux,
1797 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1798 GST_TIME_ARGS (time), newpos);
1800 /* and at least start scanning before previous scan start to avoid looping */
1801 startpos = startpos * 90 / 100;
1802 if (startpos && startpos < newpos)
1805 /* read in at newpos and scan for ebml cluster id */
1809 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1810 if (ret == GST_FLOW_EOS) {
1811 /* heuristic HACK */
1812 newpos = startpos * 80 / 100;
1813 GST_DEBUG_OBJECT (demux, "EOS; "
1814 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1815 GST_TIME_ARGS (time), newpos);
1818 } else if (ret != GST_FLOW_OK) {
1825 /* then start scanning and parsing for cluster time,
1826 * re-estimate if overshoot, otherwise next cluster and so on */
1827 demux->common.offset = newpos;
1828 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1830 guint64 cluster_size = 0;
1832 /* peek and parse some elements */
1833 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1834 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1835 if (ret != GST_FLOW_OK)
1837 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1838 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1840 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1841 if (ret != GST_FLOW_OK)
1844 if (id == GST_MATROSKA_ID_CLUSTER) {
1845 cluster_time = GST_CLOCK_TIME_NONE;
1846 if (length == G_MAXUINT64)
1849 cluster_size = length + needed;
1851 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1852 cluster_time == GST_CLOCK_TIME_NONE) {
1853 cluster_time = demux->cluster_time * demux->common.time_scale;
1854 cluster_offset = demux->cluster_offset;
1855 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1856 " with time %" GST_TIME_FORMAT, cluster_offset,
1857 GST_TIME_ARGS (cluster_time));
1858 if (cluster_time > time) {
1859 GST_DEBUG_OBJECT (demux, "overshot target");
1860 /* cluster overshoots */
1861 if (cluster_offset == demux->first_cluster_offset) {
1862 /* but no prev one */
1863 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1864 prev_cluster_time = cluster_time;
1865 prev_cluster_offset = cluster_offset;
1868 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1869 /* prev cluster did not overshoot, so prev cluster is target */
1872 /* re-estimate using this new position info */
1873 opos = cluster_offset;
1874 otime = cluster_time;
1878 /* cluster undershoots, goto next one */
1879 prev_cluster_time = cluster_time;
1880 prev_cluster_offset = cluster_offset;
1881 /* skip cluster if length is defined,
1882 * otherwise will be skippingly parsed into */
1884 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1885 demux->common.offset = cluster_offset + cluster_size;
1886 demux->cluster_time = GST_CLOCK_TIME_NONE;
1888 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1895 if (ret == GST_FLOW_EOS) {
1896 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1902 entry = g_new0 (GstMatroskaIndex, 1);
1903 entry->time = prev_cluster_time;
1904 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1905 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1906 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1910 /* restore some state */
1911 demux->cluster_offset = current_cluster_offset;
1912 demux->cluster_time = current_cluster_time;
1913 demux->common.offset = current_offset;
1914 demux->common.state = current_state;
1920 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1921 GstPad * pad, GstEvent * event)
1923 GstMatroskaIndex *entry = NULL;
1924 GstMatroskaIndex scan_entry;
1926 GstSeekType cur_type, stop_type;
1928 gboolean flush, keyunit, before, after, snap_next;
1931 GstMatroskaTrackContext *track = NULL;
1932 GstSegment seeksegment = { 0, };
1933 gboolean update = TRUE;
1934 gboolean pad_locked = FALSE;
1937 track = gst_pad_get_element_private (pad);
1939 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1942 /* we can only seek on time */
1943 if (format != GST_FORMAT_TIME) {
1944 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1948 /* copy segment, we need this because we still need the old
1949 * segment when we close the current segment. */
1950 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1952 /* pull mode without index means that the actual duration is not known,
1953 * we might be playing a file that's still being recorded
1954 * so, invalidate our current duration, which is only a moving target,
1955 * and should not be used to clamp anything */
1956 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
1957 seeksegment.duration = GST_CLOCK_TIME_NONE;
1961 GST_DEBUG_OBJECT (demux, "configuring seek");
1962 gst_segment_do_seek (&seeksegment, rate, format, flags,
1963 cur_type, cur, stop_type, stop, &update);
1964 /* compensate for clip start time */
1965 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1966 seeksegment.position += demux->stream_start_time;
1967 seeksegment.start += demux->stream_start_time;
1968 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
1969 seeksegment.stop += demux->stream_start_time;
1970 /* note that time should stay at indicated position */
1974 /* restore segment duration (if any effect),
1975 * would be determined again when parsing, but anyway ... */
1976 seeksegment.duration = demux->common.segment.duration;
1978 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
1979 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
1980 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
1981 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
1983 /* always do full update if flushing,
1984 * otherwise problems might arise downstream with missing keyframes etc */
1985 update = update || flush;
1987 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1990 /* only have to update some segment,
1991 * but also still have to honour flush and so on */
1992 GST_DEBUG_OBJECT (demux, "... no update");
1993 /* bad goto, bad ... */
1997 /* check sanity before we start flushing and all that */
1998 snap_next = after && !before;
1999 if (seeksegment.rate < 0)
2000 snap_next = !snap_next;
2001 GST_OBJECT_LOCK (demux);
2002 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2003 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2004 seeksegment.position, &demux->seek_index, &demux->seek_entry,
2005 snap_next)) == NULL) {
2006 /* pull mode without index can scan later on */
2007 if (demux->streaming) {
2008 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2009 GST_OBJECT_UNLOCK (demux);
2013 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2014 GST_OBJECT_UNLOCK (demux);
2016 if (demux->streaming) {
2017 GST_OBJECT_LOCK (demux);
2018 /* now update the real segment info */
2019 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2020 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2021 GST_OBJECT_UNLOCK (demux);
2022 /* need to seek to cluster start to pick up cluster time */
2023 /* upstream takes care of flushing and all that
2024 * ... and segment event handling takes care of the rest */
2025 return perform_seek_to_offset (demux,
2026 entry->pos + demux->common.ebml_segment_start);
2031 GST_DEBUG_OBJECT (demux, "Starting flush");
2032 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_start ());
2033 gst_matroska_demux_send_event (demux, gst_event_new_flush_start ());
2035 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2036 gst_pad_pause_task (demux->common.sinkpad);
2042 /* now grab the stream lock so that streaming cannot continue, for
2043 * non flushing seeks when the element is in PAUSED this could block
2045 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2046 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2049 /* pull mode without index can do some scanning */
2050 if (!demux->streaming && !entry) {
2051 /* need to stop flushing upstream as we need it next */
2053 gst_pad_push_event (demux->common.sinkpad,
2054 gst_event_new_flush_stop (TRUE));
2055 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2056 /* keep local copy */
2058 scan_entry = *entry;
2060 entry = &scan_entry;
2062 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2064 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop (TRUE));
2070 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2071 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2072 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2073 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2074 seeksegment.position = seeksegment.start;
2075 seeksegment.time = seeksegment.start - demux->stream_start_time;
2080 GST_DEBUG_OBJECT (demux, "Stopping flush");
2081 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_stop (TRUE));
2082 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop (TRUE));
2085 GST_OBJECT_LOCK (demux);
2086 /* now update the real segment info */
2087 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2088 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2089 GST_OBJECT_UNLOCK (demux);
2091 /* update some (segment) state */
2092 if (update && !gst_matroska_demux_move_to_entry (demux, entry, TRUE))
2095 /* notify start of new segment */
2096 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2099 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2100 GST_FORMAT_TIME, demux->common.segment.start);
2101 gst_element_post_message (GST_ELEMENT (demux), msg);
2104 GST_OBJECT_LOCK (demux);
2105 if (demux->new_segment)
2106 gst_event_unref (demux->new_segment);
2107 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2108 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2109 GST_OBJECT_UNLOCK (demux);
2111 /* restart our task since it might have been stopped when we did the
2113 gst_pad_start_task (demux->common.sinkpad,
2114 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2116 /* streaming can continue now */
2118 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2126 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2128 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2134 * Handle whether we can perform the seek event or if we have to let the chain
2135 * function handle seeks to build the seek indexes first.
2138 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2142 GstSeekType cur_type, stop_type;
2147 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2152 /* we can only seek on time */
2153 if (format != GST_FORMAT_TIME) {
2154 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2158 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2159 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2163 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2164 GST_DEBUG_OBJECT (demux,
2165 "Non-flushing seek not supported in streaming mode");
2169 if (flags & GST_SEEK_FLAG_SEGMENT) {
2170 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2174 /* check for having parsed index already */
2175 if (!demux->common.index_parsed) {
2176 gboolean building_index;
2179 if (!demux->index_offset) {
2180 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2184 GST_OBJECT_LOCK (demux);
2185 /* handle the seek event in the chain function */
2186 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2187 /* no more seek can be issued until state reset to _DATA */
2189 /* copy the event */
2190 if (demux->seek_event)
2191 gst_event_unref (demux->seek_event);
2192 demux->seek_event = gst_event_ref (event);
2194 /* set the building_index flag so that only one thread can setup the
2195 * structures for index seeking. */
2196 building_index = demux->building_index;
2197 if (!building_index) {
2198 demux->building_index = TRUE;
2199 offset = demux->index_offset;
2201 GST_OBJECT_UNLOCK (demux);
2203 if (!building_index) {
2204 /* seek to the first subindex or legacy index */
2205 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2206 return perform_seek_to_offset (demux, offset);
2209 /* well, we are handling it already */
2213 /* delegate to tweaked regular seek */
2214 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2218 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2221 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2222 gboolean res = TRUE;
2224 switch (GST_EVENT_TYPE (event)) {
2225 case GST_EVENT_SEEK:
2226 /* no seeking until we are (safely) ready */
2227 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2228 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2231 if (!demux->streaming)
2232 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2234 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2235 gst_event_unref (event);
2240 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2241 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2242 GstMatroskaTrackVideoContext *videocontext =
2243 (GstMatroskaTrackVideoContext *) context;
2245 GstClockTimeDiff diff;
2246 GstClockTime timestamp;
2248 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2250 GST_OBJECT_LOCK (demux);
2251 videocontext->earliest_time = timestamp + diff;
2252 GST_OBJECT_UNLOCK (demux);
2255 gst_event_unref (event);
2259 case GST_EVENT_TOC_SELECT:
2262 GstTocEntry *entry = NULL;
2263 GstEvent *seek_event;
2266 if (!demux->common.toc) {
2267 GST_DEBUG_OBJECT (demux, "no TOC to select");
2270 gst_event_parse_toc_select (event, &uid);
2272 GST_OBJECT_LOCK (demux);
2273 entry = gst_toc_find_entry (demux->common.toc, uid);
2274 if (entry == NULL) {
2275 GST_OBJECT_UNLOCK (demux);
2276 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2279 gst_toc_entry_get_start_stop (entry, &start_pos, NULL);
2280 GST_OBJECT_UNLOCK (demux);
2281 seek_event = gst_event_new_seek (1.0,
2283 GST_SEEK_FLAG_FLUSH,
2284 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2285 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2286 gst_event_unref (seek_event);
2290 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2294 gst_event_unref (event);
2298 /* events we don't need to handle */
2299 case GST_EVENT_NAVIGATION:
2300 gst_event_unref (event);
2304 case GST_EVENT_LATENCY:
2306 res = gst_pad_push_event (demux->common.sinkpad, event);
2313 static GstFlowReturn
2314 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2316 GstFlowReturn ret = GST_FLOW_EOS;
2317 gboolean done = TRUE;
2320 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2321 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2324 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2326 if (!demux->seek_entry) {
2327 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2331 for (i = 0; i < demux->common.src->len; i++) {
2332 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2334 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2335 ", stream %d at %" GST_TIME_FORMAT,
2336 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2337 GST_TIME_ARGS (stream->from_time));
2338 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2339 if (stream->from_time > demux->common.segment.start) {
2340 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2344 /* nothing pushed for this stream;
2345 * likely seek entry did not start at keyframe, so all was skipped.
2346 * So we need an earlier entry */
2352 GstMatroskaIndex *entry;
2354 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2355 --demux->seek_entry);
2356 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE))
2366 static GstFlowReturn
2367 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2369 GstFlowReturn ret = GST_FLOW_OK;
2372 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2374 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2375 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2379 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2380 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2384 /* one track within the "all-tracks" header */
2385 case GST_MATROSKA_ID_TRACKENTRY:
2386 ret = gst_matroska_demux_add_stream (demux, ebml);
2390 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2395 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2397 demux->tracks_parsed = TRUE;
2403 * Read signed/unsigned "EBML" numbers.
2404 * Return: number of bytes processed.
2408 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2410 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2418 while (read <= 8 && !(total & len_mask)) {
2425 if ((total &= (len_mask - 1)) == len_mask - 1)
2430 if (data[n] == 0xff)
2432 total = (total << 8) | data[n];
2436 if (read == num_ffs && total != 0)
2445 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2450 /* read as unsigned number first */
2451 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2455 if (unum == G_MAXUINT64)
2458 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2464 * Mostly used for subtitles. We add void filler data for each
2465 * lagging stream to make sure we don't deadlock.
2469 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2473 GST_OBJECT_LOCK (demux);
2475 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2476 GST_TIME_ARGS (demux->common.segment.position));
2478 g_assert (demux->common.num_streams == demux->common.src->len);
2479 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2480 GstMatroskaTrackContext *context;
2482 context = g_ptr_array_index (demux->common.src, stream_nr);
2484 GST_LOG_OBJECT (demux,
2485 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2486 GST_TIME_ARGS (context->pos));
2488 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2489 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2493 /* does it lag? 0.5 seconds is a random threshold...
2494 * lag need only be considered if we have advanced into requested segment */
2495 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2496 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2497 demux->common.segment.position > demux->common.segment.start &&
2498 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2501 guint64 start = context->pos;
2502 guint64 stop = demux->common.segment.position - (GST_SECOND / 2);
2504 GST_DEBUG_OBJECT (demux,
2505 "Synchronizing stream %d with other by advancing time from %"
2506 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2507 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2509 context->pos = stop;
2511 event = gst_event_new_gap (start, stop - start);
2512 GST_OBJECT_UNLOCK (demux);
2513 gst_pad_push_event (context->pad, event);
2514 GST_OBJECT_LOCK (demux);
2518 GST_OBJECT_UNLOCK (demux);
2521 static GstFlowReturn
2522 gst_matroska_demux_push_hdr_buf (GstMatroskaDemux * demux,
2523 GstMatroskaTrackContext * stream, guint8 * data, guint len)
2525 GstFlowReturn ret, cret;
2526 GstBuffer *header_buf;
2528 header_buf = gst_buffer_new_wrapped (g_memdup (data, len), len);
2530 if (stream->set_discont) {
2531 GST_BUFFER_FLAG_SET (header_buf, GST_BUFFER_FLAG_DISCONT);
2532 stream->set_discont = FALSE;
2535 ret = gst_pad_push (stream->pad, header_buf);
2538 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
2543 static GstFlowReturn
2544 gst_matroska_demux_push_flac_codec_priv_data (GstMatroskaDemux * demux,
2545 GstMatroskaTrackContext * stream)
2551 GST_LOG_OBJECT (demux, "priv data size = %" G_GSIZE_FORMAT,
2552 stream->codec_priv_size);
2554 pdata = (guint8 *) stream->codec_priv;
2556 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2557 if (stream->codec_priv_size < ((4) + (4 + 34))) {
2558 GST_WARNING_OBJECT (demux, "not enough codec priv data for flac headers");
2559 return GST_FLOW_ERROR;
2562 if (memcmp (pdata, "fLaC", 4) != 0) {
2563 GST_WARNING_OBJECT (demux, "no flac marker at start of stream headers");
2564 return GST_FLOW_ERROR;
2567 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 4);
2568 if (ret != GST_FLOW_OK)
2571 off = 4; /* skip fLaC marker */
2572 while (off < stream->codec_priv_size) {
2573 len = GST_READ_UINT8 (pdata + off + 1) << 16;
2574 len |= GST_READ_UINT8 (pdata + off + 2) << 8;
2575 len |= GST_READ_UINT8 (pdata + off + 3);
2577 GST_DEBUG_OBJECT (demux, "header packet: len=%u bytes, flags=0x%02x",
2578 len, (guint) pdata[off]);
2580 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata + off, len + 4);
2581 if (ret != GST_FLOW_OK)
2589 static GstFlowReturn
2590 gst_matroska_demux_push_speex_codec_priv_data (GstMatroskaDemux * demux,
2591 GstMatroskaTrackContext * stream)
2594 guint8 *pdata = stream->codec_priv;
2596 GST_LOG_OBJECT (demux, "priv data size = %" G_GSIZE_FORMAT,
2597 stream->codec_priv_size);
2599 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2600 if (stream->codec_priv_size < 80) {
2601 GST_WARNING_OBJECT (demux, "not enough codec priv data for speex headers");
2602 return GST_FLOW_ERROR;
2605 if (memcmp (pdata, "Speex ", 8) != 0) {
2606 GST_WARNING_OBJECT (demux, "no Speex marker at start of stream headers");
2607 return GST_FLOW_ERROR;
2610 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 80);
2611 if (ret != GST_FLOW_OK)
2614 if (stream->codec_priv_size == 80)
2617 return gst_matroska_demux_push_hdr_buf (demux, stream, pdata + 80,
2618 stream->codec_priv_size - 80);
2621 static GstFlowReturn
2622 gst_matroska_demux_push_xiph_codec_priv_data (GstMatroskaDemux * demux,
2623 GstMatroskaTrackContext * stream)
2626 guint8 *p = stream->codec_priv;
2627 gint i, offset, num_packets;
2628 guint *length, last;
2630 if (stream->codec_priv == NULL || stream->codec_priv_size == 0) {
2631 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
2632 ("Missing codec private data for xiph headers, broken file"));
2633 return GST_FLOW_ERROR;
2636 /* start of the stream and vorbis audio or theora video, need to
2637 * send the codec_priv data as first three packets */
2638 num_packets = p[0] + 1;
2639 GST_DEBUG_OBJECT (demux,
2640 "%u stream headers, total length=%" G_GSIZE_FORMAT " bytes",
2641 (guint) num_packets, stream->codec_priv_size);
2643 length = g_alloca (num_packets * sizeof (guint));
2647 /* first packets, read length values */
2648 for (i = 0; i < num_packets - 1; i++) {
2650 while (offset < stream->codec_priv_size) {
2651 length[i] += p[offset];
2652 if (p[offset++] != 0xff)
2657 if (offset + last > stream->codec_priv_size)
2658 return GST_FLOW_ERROR;
2660 /* last packet is the remaining size */
2661 length[i] = stream->codec_priv_size - offset - last;
2663 for (i = 0; i < num_packets; i++) {
2664 GST_DEBUG_OBJECT (demux, "buffer %d: length=%u bytes", i,
2666 if (offset + length[i] > stream->codec_priv_size)
2667 return GST_FLOW_ERROR;
2670 gst_matroska_demux_push_hdr_buf (demux, stream, p + offset, length[i]);
2671 if (ret != GST_FLOW_OK)
2674 offset += length[i];
2680 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2681 GstMatroskaTrackContext * stream)
2685 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2687 if (!stream->codec_priv)
2690 /* ideally, VobSub private data should be parsed and stored more convenient
2691 * elsewhere, but for now, only interested in a small part */
2693 /* make sure we have terminating 0 */
2694 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2696 /* just locate and parse palette part */
2697 start = strstr (buf, "palette:");
2702 guint8 r, g, b, y, u, v;
2705 while (g_ascii_isspace (*start))
2707 for (i = 0; i < 16; i++) {
2708 if (sscanf (start, "%06x", &col) != 1)
2711 while ((*start == ',') || g_ascii_isspace (*start))
2713 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2714 r = (col >> 16) & 0xff;
2715 g = (col >> 8) & 0xff;
2717 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2719 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2720 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2721 clut[i] = (y << 16) | (u << 8) | v;
2724 /* got them all without problems; build and send event */
2728 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2729 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2730 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2731 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2732 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2733 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2734 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2735 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2736 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2737 G_TYPE_INT, clut[15], NULL);
2739 gst_pad_push_event (stream->pad,
2740 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
2746 static GstFlowReturn
2747 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2748 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2751 guint seq_header_len;
2752 guint32 header, tmp;
2754 if (stream->codec_state) {
2755 seq_header = stream->codec_state;
2756 seq_header_len = stream->codec_state_size;
2757 } else if (stream->codec_priv) {
2758 seq_header = stream->codec_priv;
2759 seq_header_len = stream->codec_priv_size;
2764 /* Sequence header only needed for keyframes */
2765 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2768 if (gst_buffer_get_size (*buf) < 4)
2771 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2772 header = GUINT32_FROM_BE (tmp);
2774 /* Sequence start code, if not found prepend */
2775 if (header != 0x000001b3) {
2778 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2780 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2783 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2784 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2785 gst_buffer_get_size (*buf));
2787 gst_buffer_unref (*buf);
2794 static GstFlowReturn
2795 gst_matroska_demux_add_wvpk_header (GstElement * element,
2796 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2798 GstMatroskaTrackAudioContext *audiocontext =
2799 (GstMatroskaTrackAudioContext *) stream;
2800 GstBuffer *newbuf = NULL;
2801 GstMapInfo map, outmap;
2802 guint8 *buf_data, *data;
2810 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2813 wvh.total_samples = -1;
2814 wvh.block_index = audiocontext->wvpk_block_index;
2816 if (audiocontext->channels <= 2) {
2817 guint32 block_samples, tmp;
2818 gsize size = gst_buffer_get_size (*buf);
2820 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2821 block_samples = GUINT32_FROM_LE (tmp);
2822 /* we need to reconstruct the header of the wavpack block */
2824 /* -20 because ck_size is the size of the wavpack block -8
2825 * and lace_size is the size of the wavpack block + 12
2826 * (the three guint32 of the header that already are in the buffer) */
2827 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2829 /* block_samples, flags and crc are already in the buffer */
2830 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2832 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2838 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2839 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2840 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2841 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2842 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2843 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2845 /* Append data from buf: */
2846 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2847 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2849 gst_buffer_unref (*buf);
2851 audiocontext->wvpk_block_index += block_samples;
2853 guint8 *outdata = NULL;
2855 gsize buf_size, size, out_size = 0;
2856 guint32 block_samples, flags, crc, blocksize;
2858 gst_buffer_map (*buf, &map, GST_MAP_READ);
2859 buf_data = map.data;
2860 buf_size = map.size;
2863 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2864 gst_buffer_unmap (*buf, &map);
2865 return GST_FLOW_ERROR;
2871 block_samples = GST_READ_UINT32_LE (data);
2876 flags = GST_READ_UINT32_LE (data);
2879 crc = GST_READ_UINT32_LE (data);
2882 blocksize = GST_READ_UINT32_LE (data);
2886 if (blocksize == 0 || size < blocksize)
2889 g_assert ((newbuf == NULL) == (outdata == NULL));
2891 if (newbuf == NULL) {
2892 out_size = sizeof (Wavpack4Header) + blocksize;
2893 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2895 gst_buffer_copy_into (newbuf, *buf,
2896 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2899 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2900 outdata = outmap.data;
2902 gst_buffer_unmap (newbuf, &outmap);
2903 out_size += sizeof (Wavpack4Header) + blocksize;
2904 gst_buffer_set_size (newbuf, out_size);
2905 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2906 outdata = outmap.data;
2909 outdata[outpos] = 'w';
2910 outdata[outpos + 1] = 'v';
2911 outdata[outpos + 2] = 'p';
2912 outdata[outpos + 3] = 'k';
2915 GST_WRITE_UINT32_LE (outdata + outpos,
2916 blocksize + sizeof (Wavpack4Header) - 8);
2917 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2918 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2919 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2920 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2921 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2922 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2923 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2924 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2927 g_memmove (outdata + outpos, data, blocksize);
2928 outpos += blocksize;
2932 gst_buffer_unmap (*buf, &map);
2933 gst_buffer_unref (*buf);
2936 gst_buffer_unmap (newbuf, &outmap);
2939 audiocontext->wvpk_block_index += block_samples;
2945 /* @text must be null-terminated */
2947 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2952 /* yes, this might all lead to false positives ... */
2953 tag = (gchar *) text;
2954 while ((tag = strchr (tag, '<'))) {
2956 if (*tag != '\0' && *(tag + 1) == '>') {
2957 /* some common convenience ones */
2958 /* maybe any character will do here ? */
2971 if (strstr (text, "<span"))
2977 static GstFlowReturn
2978 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2979 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2981 GstMatroskaTrackSubtitleContext *sub_stream;
2982 const gchar *encoding;
2988 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
2990 if (!gst_buffer_map (*buf, &map, GST_MAP_READ))
2993 if (!sub_stream->invalid_utf8) {
2994 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
2997 GST_WARNING_OBJECT (element, "subtitle stream %d is not valid UTF-8, this "
2998 "is broken according to the matroska specification", stream->num);
2999 sub_stream->invalid_utf8 = TRUE;
3002 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3003 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3004 if (encoding == NULL || *encoding == '\0') {
3005 /* if local encoding is UTF-8 and no encoding specified
3006 * via the environment variable, assume ISO-8859-15 */
3007 if (g_get_charset (&encoding)) {
3008 encoding = "ISO-8859-15";
3013 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3014 (char *) "*", NULL, NULL, &err);
3017 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3018 encoding, err->message);
3022 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3023 encoding = "ISO-8859-15";
3025 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3026 encoding, (char *) "*", NULL, NULL, NULL);
3029 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3030 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3033 utf8 = g_strdup ("invalid subtitle");
3035 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3036 gst_buffer_copy_into (newbuf, *buf,
3037 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3039 gst_buffer_unmap (*buf, &map);
3040 gst_buffer_unref (*buf);
3043 gst_buffer_map (*buf, &map, GST_MAP_READ);
3046 if (sub_stream->check_markup) {
3047 /* caps claim markup text, so we need to escape text,
3048 * except if text is already markup and then needs no further escaping */
3049 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3050 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3052 if (!sub_stream->seen_markup_tag) {
3053 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3055 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3056 gst_buffer_copy_into (newbuf, *buf,
3057 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3058 GST_BUFFER_COPY_META, 0, -1);
3059 gst_buffer_unmap (*buf, &map);
3060 gst_buffer_unref (*buf);
3069 static GstFlowReturn
3070 gst_matroska_demux_check_aac (GstElement * element,
3071 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3076 gst_buffer_extract (*buf, 0, data, 2);
3077 size = gst_buffer_get_size (*buf);
3079 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3082 /* tss, ADTS data, remove codec_data
3083 * still assume it is at least parsed */
3084 stream->caps = gst_caps_make_writable (stream->caps);
3085 s = gst_caps_get_structure (stream->caps, 0);
3087 gst_structure_remove_field (s, "codec_data");
3088 gst_pad_set_caps (stream->pad, stream->caps);
3089 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3090 "new caps: %" GST_PTR_FORMAT, stream->caps);
3093 /* disable subsequent checking */
3094 stream->postprocess_frame = NULL;
3100 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3101 GstBuffer * buffer, gsize alignment)
3105 gst_buffer_map (buffer, &map, GST_MAP_READ);
3107 if (map.size < sizeof (guintptr)) {
3108 gst_buffer_unmap (buffer, &map);
3112 if (((guintptr) map.data) & (alignment - 1)) {
3113 GstBuffer *new_buffer;
3114 GstAllocationParams params = { 0, 0, 0, alignment - 1, };
3116 new_buffer = gst_buffer_new_allocate (NULL,
3117 gst_buffer_get_size (buffer), ¶ms);
3119 /* Copy data "by hand", so ensure alignment is kept: */
3120 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3122 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3123 GST_DEBUG_OBJECT (demux,
3124 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3127 gst_buffer_unmap (buffer, &map);
3128 gst_buffer_unref (buffer);
3133 gst_buffer_unmap (buffer, &map);
3137 static GstFlowReturn
3138 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3139 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3140 gboolean is_simpleblock)
3142 GstMatroskaTrackContext *stream = NULL;
3143 GstFlowReturn ret = GST_FLOW_OK;
3144 gboolean readblock = FALSE;
3146 guint64 block_duration = -1;
3147 GstBuffer *buf = NULL;
3149 gint stream_num = -1, n, laces = 0;
3151 gint *lace_size = NULL;
3154 gint64 referenceblock = 0;
3157 offset = gst_ebml_read_get_offset (ebml);
3159 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3160 if (!is_simpleblock) {
3161 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3165 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3169 /* one block inside the group. Note, block parsing is one
3170 * of the harder things, so this code is a bit complicated.
3171 * See http://www.matroska.org/ for documentation. */
3172 case GST_MATROSKA_ID_SIMPLEBLOCK:
3173 case GST_MATROSKA_ID_BLOCK:
3179 gst_buffer_unmap (buf, &map);
3180 gst_buffer_unref (buf);
3183 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3186 gst_buffer_map (buf, &map, GST_MAP_READ);
3190 /* first byte(s): blocknum */
3191 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3196 /* fetch stream from num */
3197 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3199 if (G_UNLIKELY (size < 3)) {
3200 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3201 /* non-fatal, try next block(group) */
3204 } else if (G_UNLIKELY (stream_num < 0 ||
3205 stream_num >= demux->common.num_streams)) {
3206 /* let's not give up on a stray invalid track number */
3207 GST_WARNING_OBJECT (demux,
3208 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3209 "; ignoring block", stream_num, num);
3213 stream = g_ptr_array_index (demux->common.src, stream_num);
3215 /* time (relative to cluster time) */
3216 time = ((gint16) GST_READ_UINT16_BE (data));
3219 flags = GST_READ_UINT8 (data);
3223 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3226 switch ((flags & 0x06) >> 1) {
3227 case 0x0: /* no lacing */
3229 lace_size = g_new (gint, 1);
3230 lace_size[0] = size;
3233 case 0x1: /* xiph lacing */
3234 case 0x2: /* fixed-size lacing */
3235 case 0x3: /* EBML lacing */
3237 goto invalid_lacing;
3238 laces = GST_READ_UINT8 (data) + 1;
3241 lace_size = g_new0 (gint, laces);
3243 switch ((flags & 0x06) >> 1) {
3244 case 0x1: /* xiph lacing */ {
3245 guint temp, total = 0;
3247 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3250 goto invalid_lacing;
3251 temp = GST_READ_UINT8 (data);
3252 lace_size[n] += temp;
3258 total += lace_size[n];
3260 lace_size[n] = size - total;
3264 case 0x2: /* fixed-size lacing */
3265 for (n = 0; n < laces; n++)
3266 lace_size[n] = size / laces;
3269 case 0x3: /* EBML lacing */ {
3272 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3276 total = lace_size[0] = num;
3277 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3281 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3285 lace_size[n] = lace_size[n - 1] + snum;
3286 total += lace_size[n];
3289 lace_size[n] = size - total;
3296 if (stream->send_xiph_headers) {
3297 ret = gst_matroska_demux_push_xiph_codec_priv_data (demux, stream);
3298 stream->send_xiph_headers = FALSE;
3301 if (stream->send_flac_headers) {
3302 ret = gst_matroska_demux_push_flac_codec_priv_data (demux, stream);
3303 stream->send_flac_headers = FALSE;
3306 if (stream->send_speex_headers) {
3307 ret = gst_matroska_demux_push_speex_codec_priv_data (demux, stream);
3308 stream->send_speex_headers = FALSE;
3311 if (stream->send_dvd_event) {
3312 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
3313 /* FIXME: should we send this event again after (flushing) seek ? */
3314 stream->send_dvd_event = FALSE;
3317 if (ret != GST_FLOW_OK)
3324 case GST_MATROSKA_ID_BLOCKDURATION:{
3325 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3326 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3331 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3332 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3333 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3338 case GST_MATROSKA_ID_CODECSTATE:{
3340 guint64 data_len = 0;
3343 gst_ebml_read_binary (ebml, &id, &data,
3344 &data_len)) != GST_FLOW_OK)
3347 if (G_UNLIKELY (stream == NULL)) {
3348 GST_WARNING_OBJECT (demux,
3349 "Unexpected CodecState subelement - ignoring");
3353 g_free (stream->codec_state);
3354 stream->codec_state = data;
3355 stream->codec_state_size = data_len;
3357 /* Decode if necessary */
3358 if (stream->encodings && stream->encodings->len > 0
3359 && stream->codec_state && stream->codec_state_size > 0) {
3360 if (!gst_matroska_decode_data (stream->encodings,
3361 &stream->codec_state, &stream->codec_state_size,
3362 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3363 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3367 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3368 stream->codec_state_size);
3373 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3377 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3378 case GST_MATROSKA_ID_BLOCKADDITIONS:
3379 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3380 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3381 case GST_MATROSKA_ID_SLICES:
3382 GST_DEBUG_OBJECT (demux,
3383 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3384 ret = gst_ebml_read_skip (ebml);
3392 /* reading a number or so could have failed */
3393 if (ret != GST_FLOW_OK)
3396 if (ret == GST_FLOW_OK && readblock) {
3397 guint64 duration = 0;
3398 gint64 lace_time = 0;
3399 gboolean delta_unit;
3401 stream = g_ptr_array_index (demux->common.src, stream_num);
3403 if (cluster_time != GST_CLOCK_TIME_NONE) {
3404 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3405 * Drop unless the lace contains timestamp 0? */
3406 if (time < 0 && (-time) > cluster_time) {
3409 if (stream->timecodescale == 1.0)
3410 lace_time = (cluster_time + time) * demux->common.time_scale;
3413 gst_util_guint64_to_gdouble ((cluster_time + time) *
3414 demux->common.time_scale) * stream->timecodescale;
3417 lace_time = GST_CLOCK_TIME_NONE;
3420 /* need to refresh segment info ASAP */
3421 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3422 GstSegment *segment = &demux->common.segment;
3423 guint64 segment_duration = 0;
3425 GST_DEBUG_OBJECT (demux,
3426 "generating segment starting at %" GST_TIME_FORMAT,
3427 GST_TIME_ARGS (lace_time));
3428 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3429 demux->stream_start_time = lace_time;
3430 GST_DEBUG_OBJECT (demux,
3431 "Setting stream start time to %" GST_TIME_FORMAT,
3432 GST_TIME_ARGS (lace_time));
3434 if (demux->common.segment.start == 0) {
3435 /* set segment fields only if they weren't already set by seek handling
3438 if (GST_CLOCK_TIME_IS_VALID (segment->stop))
3439 segment_duration = segment->stop - segment->start;
3440 else if (GST_CLOCK_TIME_IS_VALID (segment->position))
3441 segment_duration = segment->position - segment->start;
3442 segment->base += segment_duration / fabs (segment->rate);
3443 segment->start = MAX (lace_time, demux->stream_start_time);
3444 segment->stop = GST_CLOCK_TIME_NONE;
3445 segment->position = segment->start - demux->stream_start_time;
3447 /* now convey our segment notion downstream */
3448 gst_matroska_demux_send_event (demux, gst_event_new_segment (segment));
3449 demux->need_segment = FALSE;
3452 if (block_duration != -1) {
3453 if (stream->timecodescale == 1.0)
3454 duration = gst_util_uint64_scale (block_duration,
3455 demux->common.time_scale, 1);
3458 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3459 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3460 1)) * stream->timecodescale);
3461 } else if (stream->default_duration) {
3462 duration = stream->default_duration * laces;
3464 /* else duration is diff between timecode of this and next block */
3466 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3467 a ReferenceBlock implies that this is not a keyframe. In either
3468 case, it only makes sense for video streams. */
3469 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3470 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
3472 if (delta_unit && stream->set_discont) {
3473 /* When doing seeks or such, we need to restart on key frames or
3474 * decoders might choke. */
3475 GST_DEBUG_OBJECT (demux, "skipping delta unit");
3479 for (n = 0; n < laces; n++) {
3482 if (G_UNLIKELY (lace_size[n] > size)) {
3483 GST_WARNING_OBJECT (demux, "Invalid lace size");
3487 /* QoS for video track with an index. the assumption is that
3488 index entries point to keyframes, but if that is not true we
3489 will instad skip until the next keyframe. */
3490 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3491 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3492 stream->index_table && demux->common.segment.rate > 0.0) {
3493 GstMatroskaTrackVideoContext *videocontext =
3494 (GstMatroskaTrackVideoContext *) stream;
3495 GstClockTime earliest_time;
3496 GstClockTime earliest_stream_time;
3498 GST_OBJECT_LOCK (demux);
3499 earliest_time = videocontext->earliest_time;
3500 GST_OBJECT_UNLOCK (demux);
3501 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3502 GST_FORMAT_TIME, earliest_time);
3504 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3505 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3506 lace_time <= earliest_stream_time) {
3507 /* find index entry (keyframe) <= earliest_stream_time */
3508 GstMatroskaIndex *entry =
3509 gst_util_array_binary_search (stream->index_table->data,
3510 stream->index_table->len, sizeof (GstMatroskaIndex),
3511 (GCompareDataFunc) gst_matroska_index_seek_find,
3512 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3514 /* if that entry (keyframe) is after the current the current
3515 buffer, we can skip pushing (and thus decoding) all
3516 buffers until that keyframe. */
3517 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3518 entry->time > lace_time) {
3519 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3520 stream->set_discont = TRUE;
3526 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3527 gst_buffer_get_size (buf) - size, lace_size[n]);
3528 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3531 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3533 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3535 if (stream->encodings != NULL && stream->encodings->len > 0)
3536 sub = gst_matroska_decode_buffer (stream, sub);
3539 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3543 GST_BUFFER_TIMESTAMP (sub) = lace_time;
3545 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3546 GstClockTime last_stop_end;
3548 /* Check if this stream is after segment stop */
3549 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3550 lace_time >= demux->common.segment.stop) {
3551 GST_DEBUG_OBJECT (demux,
3552 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3553 GST_TIME_ARGS (demux->common.segment.stop));
3554 gst_buffer_unref (sub);
3557 if (offset >= stream->to_offset) {
3558 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3560 gst_buffer_unref (sub);
3564 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3565 * that landed us with timestamps not quite intended */
3566 GST_OBJECT_LOCK (demux);
3567 if (demux->max_gap_time &&
3568 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3569 demux->common.segment.rate > 0.0) {
3570 GstClockTimeDiff diff;
3572 /* only send segments with increasing start times,
3573 * otherwise if these go back and forth downstream (sinks) increase
3574 * accumulated time and running_time */
3575 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3576 if (diff > 0 && diff > demux->max_gap_time
3577 && lace_time > demux->common.segment.start
3578 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3579 || lace_time < demux->common.segment.stop)) {
3581 GstEvent *event1, *event2;
3582 GST_DEBUG_OBJECT (demux,
3583 "Gap of %" G_GINT64_FORMAT " ns detected in"
3584 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3585 "Sending updated SEGMENT events", diff,
3586 stream->index, GST_TIME_ARGS (stream->pos),
3587 GST_TIME_ARGS (lace_time));
3588 /* send segment events such that the gap is not accounted in
3589 * segment base time, hence running_time */
3590 /* close ahead of gap */
3591 segment = demux->common.segment;
3592 segment.start = demux->last_stop_end;
3593 segment.stop = demux->last_stop_end;
3594 segment.position = demux->last_stop_end;
3595 event1 = gst_event_new_segment (&segment);
3597 segment.start = lace_time;
3598 segment.stop = demux->common.segment.stop;
3599 segment.position = lace_time;
3600 event2 = gst_event_new_segment (&segment);
3601 GST_OBJECT_UNLOCK (demux);
3602 gst_matroska_demux_send_event (demux, event1);
3603 gst_matroska_demux_send_event (demux, event2);
3604 GST_OBJECT_LOCK (demux);
3605 /* align segment view with downstream,
3606 * prevents double-counting base time when closing segment */
3607 /* FIXME: in 0.10, the segment base/accum got updated here, but
3608 * maybe we don't need that because of the double accounting
3609 * mentioned above? */
3610 demux->common.segment = segment;
3614 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3615 || demux->common.segment.position < lace_time) {
3616 demux->common.segment.position = lace_time;
3618 GST_OBJECT_UNLOCK (demux);
3620 last_stop_end = lace_time;
3622 GST_BUFFER_DURATION (sub) = duration / laces;
3623 last_stop_end += GST_BUFFER_DURATION (sub);
3626 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3627 demux->last_stop_end < last_stop_end)
3628 demux->last_stop_end = last_stop_end;
3630 GST_OBJECT_LOCK (demux);
3631 if (demux->common.segment.duration == -1 ||
3632 demux->stream_start_time + demux->common.segment.duration <
3634 demux->common.segment.duration =
3635 last_stop_end - demux->stream_start_time;
3636 GST_OBJECT_UNLOCK (demux);
3637 if (!demux->invalid_duration) {
3638 gst_element_post_message (GST_ELEMENT_CAST (demux),
3639 gst_message_new_duration (GST_OBJECT_CAST (demux),
3640 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
3641 demux->invalid_duration = TRUE;
3644 GST_OBJECT_UNLOCK (demux);
3648 stream->pos = lace_time;
3650 gst_matroska_demux_sync_streams (demux);
3652 if (stream->set_discont) {
3653 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3654 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3655 stream->set_discont = FALSE;
3658 /* reverse playback book-keeping */
3659 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3660 stream->from_time = lace_time;
3661 if (stream->from_offset == -1)
3662 stream->from_offset = offset;
3664 GST_DEBUG_OBJECT (demux,
3665 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3666 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3667 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3668 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
3669 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3672 if (demux->common.element_index) {
3673 if (stream->index_writer_id == -1)
3674 gst_index_get_writer_id (demux->common.element_index,
3675 GST_OBJECT (stream->pad), &stream->index_writer_id);
3677 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3678 G_GUINT64_FORMAT " for writer id %d",
3679 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
3680 stream->index_writer_id);
3681 gst_index_add_association (demux->common.element_index,
3682 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3683 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3684 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
3685 cluster_offset, NULL);
3689 /* Postprocess the buffers depending on the codec used */
3690 if (stream->postprocess_frame) {
3691 GST_LOG_OBJECT (demux, "running post process");
3692 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3695 /* At this point, we have a sub-buffer pointing at data within a larger
3696 buffer. This data might not be aligned with anything. If the data is
3697 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3698 for 32 bit samples, etc), or bad things will happen downstream as
3699 elements typically assume minimal alignment.
3700 Therefore, create an aligned copy if necessary. */
3701 g_assert (stream->alignment <= G_MEM_ALIGN);
3702 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3704 ret = gst_pad_push (stream->pad, sub);
3705 if (demux->common.segment.rate < 0) {
3706 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3707 /* In reverse playback we can get a GST_FLOW_EOS when
3708 * we are at the end of the segment, so we just need to jump
3709 * back to the previous section. */
3710 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3715 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3718 size -= lace_size[n];
3719 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3720 lace_time += duration / laces;
3722 lace_time = GST_CLOCK_TIME_NONE;
3728 gst_buffer_unmap (buf, &map);
3729 gst_buffer_unref (buf);
3741 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3746 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3747 /* non-fatal, try next block(group) */
3753 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3754 /* non-fatal, try next block(group) */
3760 /* return FALSE if block(group) should be skipped (due to a seek) */
3761 static inline gboolean
3762 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3764 if (G_UNLIKELY (demux->seek_block)) {
3765 if (!(--demux->seek_block)) {
3768 GST_LOG_OBJECT (demux, "should skip block due to seek");
3776 static GstFlowReturn
3777 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3781 guint64 seek_pos = (guint64) - 1;
3782 guint32 seek_id = 0;
3785 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3787 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3788 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3792 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3793 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3797 case GST_MATROSKA_ID_SEEKID:
3801 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3804 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3809 case GST_MATROSKA_ID_SEEKPOSITION:
3813 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3816 if (t > G_MAXINT64) {
3817 GST_WARNING_OBJECT (demux,
3818 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3822 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3828 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3834 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3837 if (!seek_id || seek_pos == (guint64) - 1) {
3838 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3839 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3844 case GST_MATROSKA_ID_SEEKHEAD:
3847 case GST_MATROSKA_ID_CUES:
3848 case GST_MATROSKA_ID_TAGS:
3849 case GST_MATROSKA_ID_TRACKS:
3850 case GST_MATROSKA_ID_SEGMENTINFO:
3851 case GST_MATROSKA_ID_ATTACHMENTS:
3852 case GST_MATROSKA_ID_CHAPTERS:
3854 guint64 before_pos, length;
3858 length = gst_matroska_read_common_get_length (&demux->common);
3859 before_pos = demux->common.offset;
3861 if (length == (guint64) - 1) {
3862 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3866 /* check for validity */
3867 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3868 GST_WARNING_OBJECT (demux,
3869 "SeekHead reference lies outside file!" " (%"
3870 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3871 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3876 /* only pick up index location when streaming */
3877 if (demux->streaming) {
3878 if (seek_id == GST_MATROSKA_ID_CUES) {
3879 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3880 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3881 demux->index_offset);
3887 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3890 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3891 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3895 if (id != seek_id) {
3896 GST_WARNING_OBJECT (demux,
3897 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3898 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3901 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3906 demux->common.offset = before_pos;
3910 case GST_MATROSKA_ID_CLUSTER:
3912 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3914 GST_LOG_OBJECT (demux, "Cluster position");
3915 if (G_UNLIKELY (!demux->clusters))
3916 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3917 g_array_append_val (demux->clusters, pos);
3922 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3925 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3930 static GstFlowReturn
3931 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3933 GstFlowReturn ret = GST_FLOW_OK;
3936 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3938 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3939 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3943 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3944 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3948 case GST_MATROSKA_ID_SEEKENTRY:
3950 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3951 /* Ignore EOS and errors here */
3952 if (ret != GST_FLOW_OK) {
3953 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3960 ret = gst_matroska_read_common_parse_skip (&demux->common,
3961 ebml, "SeekHead", id);
3966 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3968 /* Sort clusters by position for easier searching */
3969 if (demux->clusters)
3970 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3975 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3977 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3979 static inline GstFlowReturn
3980 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
3982 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
3983 /* only a few blocks are expected/allowed to be large,
3984 * and will be recursed into, whereas others will be read and must fit */
3985 if (demux->streaming) {
3986 /* fatal in streaming case, as we can't step over easily */
3987 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3988 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
3989 "file might be corrupt.", bytes));
3990 return GST_FLOW_ERROR;
3992 /* indicate higher level to quietly give up */
3993 GST_DEBUG_OBJECT (demux,
3994 "too large block of size %" G_GUINT64_FORMAT, bytes);
3995 return GST_FLOW_ERROR;
4002 /* returns TRUE if we truely are in error state, and should give up */
4003 static inline gboolean
4004 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4006 if (!demux->streaming && demux->next_cluster_offset > 0) {
4007 /* just repositioning to where next cluster should be and try from there */
4008 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4009 G_GUINT64_FORMAT, demux->next_cluster_offset);
4010 demux->common.offset = demux->next_cluster_offset;
4011 demux->next_cluster_offset = 0;
4016 /* sigh, one last attempt above and beyond call of duty ...;
4017 * search for cluster mark following current pos */
4018 pos = demux->common.offset;
4019 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4020 if (gst_matroska_demux_search_cluster (demux, &pos) != GST_FLOW_OK) {
4021 /* did not work, give up */
4024 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4025 /* try that position */
4026 demux->common.offset = pos;
4032 static inline GstFlowReturn
4033 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4035 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4036 demux->common.offset += flush;
4037 if (demux->streaming) {
4040 /* hard to skip large blocks when streaming */
4041 ret = gst_matroska_demux_check_read_size (demux, flush);
4042 if (ret != GST_FLOW_OK)
4044 if (flush <= gst_adapter_available (demux->common.adapter))
4045 gst_adapter_flush (demux->common.adapter, flush);
4047 return GST_FLOW_EOS;
4052 /* initializes @ebml with @bytes from input stream at current offset.
4053 * Returns EOS if insufficient available,
4054 * ERROR if too much was attempted to read. */
4055 static inline GstFlowReturn
4056 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4059 GstBuffer *buffer = NULL;
4060 GstFlowReturn ret = GST_FLOW_OK;
4062 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4064 ret = gst_matroska_demux_check_read_size (demux, bytes);
4065 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4066 if (!demux->streaming) {
4067 /* in pull mode, we can skip */
4068 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4069 ret = GST_FLOW_OVERFLOW;
4071 /* otherwise fatal */
4072 ret = GST_FLOW_ERROR;
4076 if (demux->streaming) {
4077 if (gst_adapter_available (demux->common.adapter) >= bytes)
4078 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4082 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4083 demux->common.offset, bytes, &buffer, NULL);
4084 if (G_LIKELY (buffer)) {
4085 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4086 demux->common.offset);
4087 demux->common.offset += bytes;
4094 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4097 gboolean seekable = FALSE;
4098 gint64 start = -1, stop = -1;
4100 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4101 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4102 GST_DEBUG_OBJECT (demux, "seeking query failed");
4106 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4108 /* try harder to query upstream size if we didn't get it the first time */
4109 if (seekable && stop == -1) {
4110 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4111 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4115 /* if upstream doesn't know the size, it's likely that it's not seekable in
4116 * practice even if it technically may be seekable */
4117 if (seekable && (start != 0 || stop <= start)) {
4118 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4123 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4124 G_GUINT64_FORMAT ")", seekable, start, stop);
4125 demux->seekable = seekable;
4127 gst_query_unref (query);
4130 static GstFlowReturn
4131 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4137 GstFlowReturn ret = GST_FLOW_OK;
4139 GST_WARNING_OBJECT (demux,
4140 "Found Cluster element before Tracks, searching Tracks");
4143 before_pos = demux->common.offset;
4145 /* Search Tracks element */
4147 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4148 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4149 if (ret != GST_FLOW_OK)
4152 if (id != GST_MATROSKA_ID_TRACKS) {
4153 /* we may be skipping large cluster here, so forego size check etc */
4154 /* ... but we can't skip undefined size; force error */
4155 if (length == G_MAXUINT64) {
4156 ret = gst_matroska_demux_check_read_size (demux, length);
4159 demux->common.offset += needed;
4160 demux->common.offset += length;
4165 /* will lead to track parsing ... */
4166 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4171 demux->common.offset = before_pos;
4176 #define GST_READ_CHECK(stmt) \
4178 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4179 if (ret == GST_FLOW_OVERFLOW) { \
4180 ret = GST_FLOW_OK; \
4186 static GstFlowReturn
4187 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4188 guint64 length, guint needed)
4190 GstEbmlRead ebml = { 0, };
4191 GstFlowReturn ret = GST_FLOW_OK;
4194 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4195 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4197 /* if we plan to read and parse this element, we need prefix (id + length)
4198 * and the contents */
4199 /* mind about overflow wrap-around when dealing with undefined size */
4201 if (G_LIKELY (length != G_MAXUINT64))
4204 switch (demux->common.state) {
4205 case GST_MATROSKA_READ_STATE_START:
4207 case GST_EBML_ID_HEADER:
4208 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4209 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4210 if (ret != GST_FLOW_OK)
4212 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4213 gst_matroska_demux_check_seekability (demux);
4216 goto invalid_header;
4220 case GST_MATROSKA_READ_STATE_SEGMENT:
4222 case GST_MATROSKA_ID_SEGMENT:
4223 /* eat segment prefix */
4224 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4225 GST_DEBUG_OBJECT (demux,
4226 "Found Segment start at offset %" G_GUINT64_FORMAT,
4227 demux->common.offset);
4228 /* seeks are from the beginning of the segment,
4229 * after the segment ID/length */
4230 demux->common.ebml_segment_start = demux->common.offset;
4231 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4234 GST_WARNING_OBJECT (demux,
4235 "Expected a Segment ID (0x%x), but received 0x%x!",
4236 GST_MATROSKA_ID_SEGMENT, id);
4237 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4241 case GST_MATROSKA_READ_STATE_SCANNING:
4242 if (id != GST_MATROSKA_ID_CLUSTER &&
4243 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4246 case GST_MATROSKA_READ_STATE_HEADER:
4247 case GST_MATROSKA_READ_STATE_DATA:
4248 case GST_MATROSKA_READ_STATE_SEEK:
4250 case GST_MATROSKA_ID_SEGMENTINFO:
4251 if (!demux->common.segmentinfo_parsed) {
4252 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4253 ret = gst_matroska_read_common_parse_info (&demux->common,
4254 GST_ELEMENT_CAST (demux), &ebml);
4256 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4259 case GST_MATROSKA_ID_TRACKS:
4260 if (!demux->tracks_parsed) {
4261 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4262 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4264 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4267 case GST_MATROSKA_ID_CLUSTER:
4268 if (G_UNLIKELY (!demux->tracks_parsed)) {
4269 if (demux->streaming) {
4270 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4271 goto not_streamable;
4273 ret = gst_matroska_demux_find_tracks (demux);
4274 if (!demux->tracks_parsed)
4278 if (G_UNLIKELY (demux->common.state
4279 == GST_MATROSKA_READ_STATE_HEADER)) {
4280 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4281 demux->first_cluster_offset = demux->common.offset;
4282 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4283 gst_element_no_more_pads (GST_ELEMENT (demux));
4284 /* send initial segment - we wait till we know the first
4285 incoming timestamp, so we can properly set the start of
4287 demux->need_segment = TRUE;
4289 demux->cluster_time = GST_CLOCK_TIME_NONE;
4290 demux->cluster_offset = demux->common.offset;
4291 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4292 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4293 " not found in Cluster, trying next Cluster's first block instead",
4295 demux->seek_block = 0;
4297 demux->seek_first = FALSE;
4298 /* record next cluster for recovery */
4299 if (read != G_MAXUINT64)
4300 demux->next_cluster_offset = demux->cluster_offset + read;
4301 /* eat cluster prefix */
4302 gst_matroska_demux_flush (demux, needed);
4304 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4308 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4309 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4311 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4312 demux->cluster_time = num;
4314 if (demux->common.element_index) {
4315 if (demux->common.element_index_writer_id == -1)
4316 gst_index_get_writer_id (demux->common.element_index,
4317 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4318 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4319 G_GUINT64_FORMAT " for writer id %d",
4320 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4321 demux->common.element_index_writer_id);
4322 gst_index_add_association (demux->common.element_index,
4323 demux->common.element_index_writer_id,
4324 GST_ASSOCIATION_FLAG_KEY_UNIT,
4325 GST_FORMAT_TIME, demux->cluster_time,
4326 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4331 case GST_MATROSKA_ID_BLOCKGROUP:
4332 if (!gst_matroska_demux_seek_block (demux))
4334 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4335 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4336 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4337 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4338 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4340 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4342 case GST_MATROSKA_ID_SIMPLEBLOCK:
4343 if (!gst_matroska_demux_seek_block (demux))
4345 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4346 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4347 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4348 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4349 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4351 case GST_MATROSKA_ID_ATTACHMENTS:
4352 if (!demux->common.attachments_parsed) {
4353 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4354 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4355 GST_ELEMENT_CAST (demux), &ebml);
4357 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4360 case GST_MATROSKA_ID_TAGS:
4361 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4362 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4363 GST_ELEMENT_CAST (demux), &ebml);
4365 case GST_MATROSKA_ID_CHAPTERS:
4366 if (!demux->common.chapters_parsed) {
4367 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4369 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4371 if (demux->common.toc) {
4372 gst_matroska_demux_send_event (demux,
4373 gst_event_new_toc (demux->common.toc, FALSE));
4374 gst_element_post_message (GST_ELEMENT_CAST (demux),
4375 gst_message_new_toc (GST_OBJECT_CAST (demux),
4376 demux->common.toc, FALSE));
4379 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4381 case GST_MATROSKA_ID_SEEKHEAD:
4382 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4383 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4385 case GST_MATROSKA_ID_CUES:
4386 if (demux->common.index_parsed) {
4387 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4390 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4391 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4392 /* only push based; delayed index building */
4393 if (ret == GST_FLOW_OK
4394 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4397 GST_OBJECT_LOCK (demux);
4398 event = demux->seek_event;
4399 demux->seek_event = NULL;
4400 GST_OBJECT_UNLOCK (demux);
4403 /* unlikely to fail, since we managed to seek to this point */
4404 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4406 /* resume data handling, main thread clear to seek again */
4407 GST_OBJECT_LOCK (demux);
4408 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4409 GST_OBJECT_UNLOCK (demux);
4412 case GST_MATROSKA_ID_POSITION:
4413 case GST_MATROSKA_ID_PREVSIZE:
4414 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4415 case GST_MATROSKA_ID_SILENTTRACKS:
4416 GST_DEBUG_OBJECT (demux,
4417 "Skipping Cluster subelement 0x%x - ignoring", id);
4421 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4422 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4428 if (ret == GST_FLOW_PARSE)
4432 gst_ebml_read_clear (&ebml);
4438 /* simply exit, maybe not enough data yet */
4439 /* no ebml to clear if read error */
4444 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4445 ("Failed to parse Element 0x%x", id));
4446 ret = GST_FLOW_ERROR;
4451 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4452 ("File layout does not permit streaming"));
4453 ret = GST_FLOW_ERROR;
4458 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4459 ("No Tracks element found"));
4460 ret = GST_FLOW_ERROR;
4465 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4466 ret = GST_FLOW_ERROR;
4471 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4472 ret = GST_FLOW_ERROR;
4478 gst_matroska_demux_loop (GstPad * pad)
4480 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4486 /* If we have to close a segment, send a new segment to do this now */
4487 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4488 if (G_UNLIKELY (demux->new_segment)) {
4489 gst_matroska_demux_send_event (demux, demux->new_segment);
4490 demux->new_segment = NULL;
4494 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4495 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4496 if (ret == GST_FLOW_EOS)
4498 if (ret != GST_FLOW_OK) {
4499 if (gst_matroska_demux_check_parse_error (demux))
4505 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4506 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4509 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4510 if (ret == GST_FLOW_EOS)
4512 if (ret != GST_FLOW_OK)
4515 /* check if we're at the end of a configured segment */
4516 if (G_LIKELY (demux->common.src->len)) {
4519 g_assert (demux->common.num_streams == demux->common.src->len);
4520 for (i = 0; i < demux->common.src->len; i++) {
4521 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4523 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4524 GST_TIME_ARGS (context->pos));
4525 if (context->eos == FALSE)
4529 GST_INFO_OBJECT (demux, "All streams are EOS");
4535 if (G_UNLIKELY (demux->common.offset ==
4536 gst_matroska_read_common_get_length (&demux->common))) {
4537 GST_LOG_OBJECT (demux, "Reached end of stream");
4547 if (demux->common.segment.rate < 0.0) {
4548 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4549 if (ret == GST_FLOW_OK)
4556 const gchar *reason = gst_flow_get_name (ret);
4557 gboolean push_eos = FALSE;
4559 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4560 gst_pad_pause_task (demux->common.sinkpad);
4562 if (ret == GST_FLOW_EOS) {
4563 /* perform EOS logic */
4565 /* If we were in the headers, make sure we send no-more-pads.
4566 This will ensure decodebin2 does not get stuck thinking
4567 the chain is not complete yet, and waiting indefinitely. */
4568 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4569 if (demux->common.src->len == 0) {
4570 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4571 ("No pads created"));
4573 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4574 ("Failed to finish reading headers"));
4576 gst_element_no_more_pads (GST_ELEMENT (demux));
4579 /* Close the segment, i.e. update segment stop with the duration
4580 * if no stop was set */
4581 if (GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
4582 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
4583 GST_CLOCK_TIME_IS_VALID (demux->common.segment.start) &&
4584 demux->last_stop_end > demux->common.segment.start) {
4585 GstSegment segment = demux->common.segment;
4588 segment.stop = demux->last_stop_end;
4589 event = gst_event_new_segment (&segment);
4590 gst_matroska_demux_send_event (demux, event);
4593 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4596 /* for segment playback we need to post when (in stream time)
4597 * we stopped, this is either stop (when set) or the duration. */
4598 if ((stop = demux->common.segment.stop) == -1)
4599 stop = demux->last_stop_end;
4601 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4602 gst_element_post_message (GST_ELEMENT (demux),
4603 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4608 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4609 /* for fatal errors we post an error message */
4610 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4611 ("stream stopped, reason %s", reason));
4615 /* send EOS, and prevent hanging if no streams yet */
4616 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4617 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4618 (ret == GST_FLOW_EOS)) {
4619 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4620 (NULL), ("got eos but no streams (yet)"));
4628 * Create and push a flushing seek event upstream
4631 perform_seek_to_offset (GstMatroskaDemux * demux, guint64 offset)
4636 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4639 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
4640 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4641 GST_SEEK_TYPE_NONE, -1);
4643 res = gst_pad_push_event (demux->common.sinkpad, event);
4645 /* segment event will update offset */
4649 static GstFlowReturn
4650 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4652 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4654 GstFlowReturn ret = GST_FLOW_OK;
4659 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4660 GST_DEBUG_OBJECT (demux, "got DISCONT");
4661 gst_adapter_clear (demux->common.adapter);
4662 GST_OBJECT_LOCK (demux);
4663 gst_matroska_read_common_reset_streams (&demux->common,
4664 GST_CLOCK_TIME_NONE, FALSE);
4665 GST_OBJECT_UNLOCK (demux);
4668 gst_adapter_push (demux->common.adapter, buffer);
4672 available = gst_adapter_available (demux->common.adapter);
4674 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4675 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4676 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS))
4679 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4680 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4681 demux->common.offset, id, length, needed, available);
4683 if (needed > available)
4686 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4687 if (ret == GST_FLOW_EOS) {
4688 /* need more data */
4690 } else if (ret != GST_FLOW_OK) {
4697 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4700 gboolean res = TRUE;
4701 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4703 GST_DEBUG_OBJECT (demux,
4704 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4706 switch (GST_EVENT_TYPE (event)) {
4707 case GST_EVENT_SEGMENT:
4709 const GstSegment *segment;
4711 /* some debug output */
4712 gst_event_parse_segment (event, &segment);
4713 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4714 GST_DEBUG_OBJECT (demux,
4715 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4718 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4719 GST_DEBUG_OBJECT (demux, "still starting");
4723 /* we only expect a BYTE segment, e.g. following a seek */
4724 if (segment->format != GST_FORMAT_BYTES) {
4725 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4729 GST_DEBUG_OBJECT (demux, "clearing segment state");
4730 GST_OBJECT_LOCK (demux);
4731 /* clear current segment leftover */
4732 gst_adapter_clear (demux->common.adapter);
4733 /* and some streaming setup */
4734 demux->common.offset = segment->start;
4735 /* do not know where we are;
4736 * need to come across a cluster and generate segment */
4737 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4738 demux->cluster_time = GST_CLOCK_TIME_NONE;
4739 demux->cluster_offset = 0;
4740 demux->need_segment = TRUE;
4741 /* but keep some of the upstream segment */
4742 demux->common.segment.rate = segment->rate;
4743 GST_OBJECT_UNLOCK (demux);
4745 /* chain will send initial segment after pads have been added,
4746 * or otherwise come up with one */
4747 GST_DEBUG_OBJECT (demux, "eating event");
4748 gst_event_unref (event);
4754 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4755 gst_event_unref (event);
4756 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4757 (NULL), ("got eos and didn't receive a complete header object"));
4758 } else if (demux->common.num_streams == 0) {
4759 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4760 (NULL), ("got eos but no streams (yet)"));
4762 gst_matroska_demux_send_event (demux, event);
4766 case GST_EVENT_FLUSH_STOP:
4770 gst_adapter_clear (demux->common.adapter);
4771 GST_OBJECT_LOCK (demux);
4772 gst_matroska_read_common_reset_streams (&demux->common,
4773 GST_CLOCK_TIME_NONE, TRUE);
4774 dur = demux->common.segment.duration;
4775 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4776 demux->common.segment.duration = dur;
4777 demux->cluster_time = GST_CLOCK_TIME_NONE;
4778 demux->cluster_offset = 0;
4779 GST_OBJECT_UNLOCK (demux);
4783 res = gst_pad_event_default (pad, parent, event);
4791 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4793 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4795 gboolean pull_mode = FALSE;
4797 query = gst_query_new_scheduling ();
4799 if (gst_pad_peer_query (sinkpad, query))
4800 pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL);
4802 gst_query_unref (query);
4805 GST_DEBUG ("going to pull mode");
4806 demux->streaming = FALSE;
4807 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4809 GST_DEBUG ("going to push (streaming) mode");
4810 demux->streaming = TRUE;
4811 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4816 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4817 GstPadMode mode, gboolean active)
4820 case GST_PAD_MODE_PULL:
4822 /* if we have a scheduler we can start the task */
4823 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4826 gst_pad_stop_task (sinkpad);
4829 case GST_PAD_MODE_PUSH:
4837 gst_duration_to_fraction (guint64 duration, gint * dest_n, gint * dest_d)
4839 static const int common_den[] = { 1, 2, 3, 4, 1001 };
4844 for (i = 0; i < G_N_ELEMENTS (common_den); i++) {
4846 n = floor (0.5 + (d * 1e9) / duration);
4847 a = gst_util_uint64_scale_int (1000000000, d, n);
4848 if (duration >= a - 1 && duration <= a + 1) {
4853 gst_util_double_to_fraction (1e9 / duration, &n, &d);
4862 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4863 videocontext, const gchar * codec_id, guint8 * data, guint size,
4864 gchar ** codec_name, guint32 * riff_fourcc)
4866 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4867 GstCaps *caps = NULL;
4869 g_assert (videocontext != NULL);
4870 g_assert (codec_name != NULL);
4872 context->send_xiph_headers = FALSE;
4873 context->send_flac_headers = FALSE;
4874 context->send_speex_headers = FALSE;
4879 /* TODO: check if we have all codec types from matroska-ids.h
4880 * check if we have to do more special things with codec_private
4883 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4884 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4887 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4888 gst_riff_strf_vids *vids = NULL;
4891 GstBuffer *buf = NULL;
4893 vids = (gst_riff_strf_vids *) data;
4895 /* assure size is big enough */
4897 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4900 if (size < sizeof (gst_riff_strf_vids)) {
4901 vids = g_new (gst_riff_strf_vids, 1);
4902 memcpy (vids, data, size);
4905 /* little-endian -> byte-order */
4906 vids->size = GUINT32_FROM_LE (vids->size);
4907 vids->width = GUINT32_FROM_LE (vids->width);
4908 vids->height = GUINT32_FROM_LE (vids->height);
4909 vids->planes = GUINT16_FROM_LE (vids->planes);
4910 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4911 vids->compression = GUINT32_FROM_LE (vids->compression);
4912 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4913 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4914 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4915 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4916 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4918 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4919 gsize offset = sizeof (gst_riff_strf_vids);
4922 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
4923 size - offset), size - offset);
4927 *riff_fourcc = vids->compression;
4929 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4930 buf, NULL, codec_name);
4933 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4934 GST_FOURCC_ARGS (vids->compression));
4938 gst_buffer_unref (buf);
4940 if (vids != (gst_riff_strf_vids *) data)
4943 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4944 const gchar *format = NULL;
4946 switch (videocontext->fourcc) {
4947 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4948 *codec_name = g_strdup ("Raw planar YUV 4:2:0");
4951 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4952 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
4955 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4956 *codec_name = g_strdup ("Raw packed YUV 4:2:0");
4959 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4960 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
4963 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4964 *codec_name = g_strdup ("Raw packed YUV 4:4:4 with alpha channel");
4969 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
4970 GST_FOURCC_ARGS (videocontext->fourcc));
4974 caps = gst_caps_new_simple ("video/x-raw",
4975 "format", G_TYPE_STRING, format, NULL);
4976 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
4977 caps = gst_caps_new_simple ("video/x-divx",
4978 "divxversion", G_TYPE_INT, 4, NULL);
4979 *codec_name = g_strdup ("MPEG-4 simple profile");
4980 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
4981 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
4983 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4984 "divxversion", G_TYPE_INT, 5, NULL),
4985 gst_structure_new ("video/x-xvid", NULL),
4986 gst_structure_new ("video/mpeg",
4987 "mpegversion", G_TYPE_INT, 4,
4988 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
4990 caps = gst_caps_new_simple ("video/mpeg",
4991 "mpegversion", G_TYPE_INT, 4,
4992 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
4996 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4997 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4998 gst_buffer_unref (priv);
5000 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5001 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5003 *codec_name = g_strdup ("MPEG-4 advanced profile");
5004 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5006 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5007 "divxversion", G_TYPE_INT, 3, NULL),
5008 gst_structure_new ("video/x-msmpeg",
5009 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5011 caps = gst_caps_new_simple ("video/x-msmpeg",
5012 "msmpegversion", G_TYPE_INT, 43, NULL);
5013 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5014 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5015 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5018 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5023 caps = gst_caps_new_simple ("video/mpeg",
5024 "systemstream", G_TYPE_BOOLEAN, FALSE,
5025 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5026 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5027 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5028 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5029 caps = gst_caps_new_empty_simple ("image/jpeg");
5030 *codec_name = g_strdup ("Motion-JPEG");
5031 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5032 caps = gst_caps_new_empty_simple ("video/x-h264");
5036 /* First byte is the version, second is the profile indication, and third
5037 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5038 * level indication. */
5039 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5042 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5043 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5044 gst_buffer_unref (priv);
5046 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5047 "alignment", G_TYPE_STRING, "au", NULL);
5049 GST_WARNING ("No codec data found, assuming output is byte-stream");
5050 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5053 *codec_name = g_strdup ("H264");
5054 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5055 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5056 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5057 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5058 gint rmversion = -1;
5060 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5062 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5064 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5066 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5069 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5070 "rmversion", G_TYPE_INT, rmversion, NULL);
5071 GST_DEBUG ("data:%p, size:0x%x", data, size);
5072 /* We need to extract the extradata ! */
5073 if (data && (size >= 0x22)) {
5078 subformat = GST_READ_UINT32_BE (data + 0x1a);
5079 rformat = GST_READ_UINT32_BE (data + 0x1e);
5082 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5084 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5085 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5086 gst_buffer_unref (priv);
5089 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5090 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5091 caps = gst_caps_new_empty_simple ("video/x-theora");
5092 context->send_xiph_headers = TRUE;
5093 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5094 caps = gst_caps_new_empty_simple ("video/x-dirac");
5095 *codec_name = g_strdup_printf ("Dirac");
5096 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5097 caps = gst_caps_new_empty_simple ("video/x-vp8");
5098 *codec_name = g_strdup_printf ("On2 VP8");
5100 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5106 GstStructure *structure;
5108 for (i = 0; i < gst_caps_get_size (caps); i++) {
5109 structure = gst_caps_get_structure (caps, i);
5111 /* FIXME: use the real unit here! */
5112 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5113 videocontext->pixel_width,
5114 videocontext->pixel_height,
5115 videocontext->display_width, videocontext->display_height);
5117 /* pixel width and height are the w and h of the video in pixels */
5118 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5119 gint w = videocontext->pixel_width;
5120 gint h = videocontext->pixel_height;
5122 gst_structure_set (structure,
5123 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5126 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5129 if (videocontext->display_width <= 0)
5130 videocontext->display_width = videocontext->pixel_width;
5131 if (videocontext->display_height <= 0)
5132 videocontext->display_height = videocontext->pixel_height;
5134 /* calculate the pixel aspect ratio using the display and pixel w/h */
5135 n = videocontext->display_width * videocontext->pixel_height;
5136 d = videocontext->display_height * videocontext->pixel_width;
5137 GST_DEBUG ("setting PAR to %d/%d", n, d);
5138 gst_structure_set (structure, "pixel-aspect-ratio",
5140 videocontext->display_width * videocontext->pixel_height,
5141 videocontext->display_height * videocontext->pixel_width, NULL);
5144 if (videocontext->default_fps > 0.0) {
5145 GValue fps_double = { 0, };
5146 GValue fps_fraction = { 0, };
5148 g_value_init (&fps_double, G_TYPE_DOUBLE);
5149 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
5150 g_value_set_double (&fps_double, videocontext->default_fps);
5151 g_value_transform (&fps_double, &fps_fraction);
5153 GST_DEBUG ("using default fps %f", videocontext->default_fps);
5155 gst_structure_set_value (structure, "framerate", &fps_fraction);
5156 g_value_unset (&fps_double);
5157 g_value_unset (&fps_fraction);
5158 } else if (context->default_duration > 0) {
5161 gst_duration_to_fraction (context->default_duration, &fps_n, &fps_d);
5163 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5164 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5166 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5167 fps_n, fps_d, NULL);
5169 /* sort of a hack to get most codecs to support,
5170 * even if the default_duration is missing */
5171 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5175 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5176 gst_structure_set (structure, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
5179 caps = gst_caps_simplify (caps);
5186 * Some AAC specific code... *sigh*
5187 * FIXME: maybe we should use '15' and code the sample rate explicitly
5188 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5192 aac_rate_idx (gint rate)
5196 else if (75132 <= rate)
5198 else if (55426 <= rate)
5200 else if (46009 <= rate)
5202 else if (37566 <= rate)
5204 else if (27713 <= rate)
5206 else if (23004 <= rate)
5208 else if (18783 <= rate)
5210 else if (13856 <= rate)
5212 else if (11502 <= rate)
5214 else if (9391 <= rate)
5221 aac_profile_idx (const gchar * codec_id)
5225 if (strlen (codec_id) <= 12)
5227 else if (!strncmp (&codec_id[12], "MAIN", 4))
5229 else if (!strncmp (&codec_id[12], "LC", 2))
5231 else if (!strncmp (&codec_id[12], "SSR", 3))
5239 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5242 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5243 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5244 gchar ** codec_name, guint16 * riff_audio_fmt)
5246 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5247 GstCaps *caps = NULL;
5249 g_assert (audiocontext != NULL);
5250 g_assert (codec_name != NULL);
5253 *riff_audio_fmt = 0;
5255 context->send_xiph_headers = FALSE;
5256 context->send_flac_headers = FALSE;
5257 context->send_speex_headers = FALSE;
5259 /* TODO: check if we have all codec types from matroska-ids.h
5260 * check if we have to do more special things with codec_private
5261 * check if we need bitdepth in different places too
5262 * implement channel position magic
5264 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5265 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5266 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5267 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5270 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5271 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5272 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5275 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5277 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5282 caps = gst_caps_new_simple ("audio/mpeg",
5283 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5284 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5285 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5286 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5289 GstAudioFormat format;
5291 sign = (audiocontext->bitdepth != 8);
5292 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5293 endianness = G_BIG_ENDIAN;
5295 endianness = G_LITTLE_ENDIAN;
5297 format = gst_audio_format_build_integer (sign, endianness,
5298 audiocontext->bitdepth, audiocontext->bitdepth);
5300 /* FIXME: Channel mask and reordering */
5301 caps = gst_caps_new_simple ("audio/x-raw",
5302 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5303 "layout", G_TYPE_STRING, "interleaved", NULL);
5305 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5306 audiocontext->bitdepth);
5307 context->alignment = audiocontext->bitdepth / 8;
5308 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5309 const gchar *format;
5310 if (audiocontext->bitdepth == 32)
5314 /* FIXME: Channel mask and reordering */
5315 caps = gst_caps_new_simple ("audio/x-raw",
5316 "format", G_TYPE_STRING, format,
5317 "layout", G_TYPE_STRING, "interleaved", NULL);
5318 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5319 audiocontext->bitdepth);
5320 context->alignment = audiocontext->bitdepth / 8;
5321 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5322 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5323 caps = gst_caps_new_simple ("audio/x-ac3",
5324 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5325 *codec_name = g_strdup ("AC-3 audio");
5326 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5327 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5328 caps = gst_caps_new_simple ("audio/x-eac3",
5329 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5330 *codec_name = g_strdup ("E-AC-3 audio");
5331 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5332 caps = gst_caps_new_empty_simple ("audio/x-dts");
5333 *codec_name = g_strdup ("DTS audio");
5334 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5335 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5336 context->send_xiph_headers = TRUE;
5337 /* vorbis decoder does tags */
5338 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5339 caps = gst_caps_new_empty_simple ("audio/x-flac");
5340 context->send_flac_headers = TRUE;
5341 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5342 caps = gst_caps_new_empty_simple ("audio/x-speex");
5343 context->send_speex_headers = TRUE;
5344 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5345 gst_riff_strf_auds auds;
5348 GstBuffer *codec_data;
5350 /* little-endian -> byte-order */
5351 auds.format = GST_READ_UINT16_LE (data);
5352 auds.channels = GST_READ_UINT16_LE (data + 2);
5353 auds.rate = GST_READ_UINT32_LE (data + 4);
5354 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5355 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5356 auds.size = GST_READ_UINT16_LE (data + 16);
5358 /* 18 is the waveformatex size */
5359 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5360 data + 18, auds.size, 0, auds.size, NULL, NULL);
5363 *riff_audio_fmt = auds.format;
5365 /* FIXME: Handle reorder map */
5366 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5367 codec_data, codec_name, NULL);
5368 gst_buffer_unref (codec_data);
5371 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5374 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5375 GstBuffer *priv = NULL;
5377 gint rate_idx, profile;
5378 guint8 *data = NULL;
5380 /* unspecified AAC profile with opaque private codec data */
5381 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5382 if (context->codec_priv_size >= 2) {
5383 guint obj_type, freq_index, explicit_freq_bytes = 0;
5385 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5387 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5388 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5389 if (freq_index == 15)
5390 explicit_freq_bytes = 3;
5391 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5392 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5393 context->codec_priv_size), context->codec_priv_size);
5394 /* assume SBR if samplerate <= 24kHz */
5395 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5396 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5397 audiocontext->samplerate *= 2;
5400 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5401 /* this is pretty broken;
5402 * maybe we need to make up some default private,
5403 * or maybe ADTS data got dumped in.
5404 * Let's set up some private data now, and check actual data later */
5405 /* just try this and see what happens ... */
5406 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5407 context->postprocess_frame = gst_matroska_demux_check_aac;
5411 /* make up decoder-specific data if it is not supplied */
5415 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5416 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5418 rate_idx = aac_rate_idx (audiocontext->samplerate);
5419 profile = aac_profile_idx (codec_id);
5421 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5422 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5424 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5425 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5427 gst_buffer_unmap (priv, &map);
5428 gst_buffer_set_size (priv, 2);
5429 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5430 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5433 if (g_strrstr (codec_id, "SBR")) {
5434 /* HE-AAC (aka SBR AAC) */
5435 audiocontext->samplerate *= 2;
5436 rate_idx = aac_rate_idx (audiocontext->samplerate);
5437 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5438 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5439 data[4] = (1 << 7) | (rate_idx << 3);
5440 gst_buffer_unmap (priv, &map);
5442 gst_buffer_unmap (priv, &map);
5443 gst_buffer_set_size (priv, 2);
5446 gst_buffer_unmap (priv, &map);
5447 gst_buffer_unref (priv);
5449 GST_ERROR ("Unknown AAC profile and no codec private data");
5454 caps = gst_caps_new_simple ("audio/mpeg",
5455 "mpegversion", G_TYPE_INT, mpegversion,
5456 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5457 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5458 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5459 gst_buffer_unref (priv);
5461 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5462 caps = gst_caps_new_simple ("audio/x-tta",
5463 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5464 *codec_name = g_strdup ("TTA audio");
5465 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5466 caps = gst_caps_new_simple ("audio/x-wavpack",
5467 "width", G_TYPE_INT, audiocontext->bitdepth,
5468 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5469 *codec_name = g_strdup ("Wavpack audio");
5470 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5471 audiocontext->wvpk_block_index = 0;
5472 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5473 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5474 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5475 gint raversion = -1;
5477 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5479 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5484 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5485 "raversion", G_TYPE_INT, raversion, NULL);
5486 /* Extract extra information from caps, mapping varies based on codec */
5487 if (data && (size >= 0x50)) {
5494 guint extra_data_size;
5496 GST_ERROR ("real audio raversion:%d", raversion);
5497 if (raversion == 8) {
5499 flavor = GST_READ_UINT16_BE (data + 22);
5500 packet_size = GST_READ_UINT32_BE (data + 24);
5501 height = GST_READ_UINT16_BE (data + 40);
5502 leaf_size = GST_READ_UINT16_BE (data + 44);
5503 sample_width = GST_READ_UINT16_BE (data + 58);
5504 extra_data_size = GST_READ_UINT32_BE (data + 74);
5507 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5508 flavor, packet_size, height, leaf_size, sample_width,
5510 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5511 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5512 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5514 if ((size - 78) >= extra_data_size) {
5515 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5517 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5518 gst_buffer_unref (priv);
5523 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5524 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5525 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5526 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5527 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5528 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5529 *codec_name = g_strdup ("Real Audio Lossless");
5530 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5531 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5532 *codec_name = g_strdup ("Sony ATRAC3");
5534 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5539 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5542 for (i = 0; i < gst_caps_get_size (caps); i++) {
5543 gst_structure_set (gst_caps_get_structure (caps, i),
5544 "channels", G_TYPE_INT, audiocontext->channels,
5545 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5549 caps = gst_caps_simplify (caps);
5556 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5557 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5559 GstCaps *caps = NULL;
5560 GstMatroskaTrackContext *context =
5561 (GstMatroskaTrackContext *) subtitlecontext;
5563 /* for backwards compatibility */
5564 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5565 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5566 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5567 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5568 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5569 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5570 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5571 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5573 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5574 * Check if we have to do something with codec_private */
5575 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5576 /* well, plain text simply does not have a lot of markup ... */
5577 caps = gst_caps_new_empty_simple ("text/x-pango-markup");
5578 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5579 subtitlecontext->check_markup = TRUE;
5580 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5581 caps = gst_caps_new_empty_simple ("application/x-ssa");
5582 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5583 subtitlecontext->check_markup = FALSE;
5584 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5585 caps = gst_caps_new_empty_simple ("application/x-ass");
5586 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5587 subtitlecontext->check_markup = FALSE;
5588 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5589 caps = gst_caps_new_empty_simple ("application/x-usf");
5590 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5591 subtitlecontext->check_markup = FALSE;
5592 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5593 caps = gst_caps_new_empty_simple ("video/x-dvd-subpicture");
5594 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5595 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5596 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5597 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5598 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5599 context->send_xiph_headers = TRUE;
5601 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5602 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5605 if (data != NULL && size > 0) {
5608 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5609 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5610 gst_buffer_unref (buf);
5618 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5620 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5622 GST_OBJECT_LOCK (demux);
5623 if (demux->common.element_index)
5624 gst_object_unref (demux->common.element_index);
5625 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5626 GST_OBJECT_UNLOCK (demux);
5627 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5628 demux->common.element_index);
5632 gst_matroska_demux_get_index (GstElement * element)
5634 GstIndex *result = NULL;
5635 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5637 GST_OBJECT_LOCK (demux);
5638 if (demux->common.element_index)
5639 result = gst_object_ref (demux->common.element_index);
5640 GST_OBJECT_UNLOCK (demux);
5642 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5648 static GstStateChangeReturn
5649 gst_matroska_demux_change_state (GstElement * element,
5650 GstStateChange transition)
5652 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5653 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5655 /* handle upwards state changes here */
5656 switch (transition) {
5661 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5663 /* handle downwards state changes */
5664 switch (transition) {
5665 case GST_STATE_CHANGE_PAUSED_TO_READY:
5666 gst_matroska_demux_reset (GST_ELEMENT (demux));
5676 gst_matroska_demux_set_property (GObject * object,
5677 guint prop_id, const GValue * value, GParamSpec * pspec)
5679 GstMatroskaDemux *demux;
5681 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5682 demux = GST_MATROSKA_DEMUX (object);
5685 case ARG_MAX_GAP_TIME:
5686 GST_OBJECT_LOCK (demux);
5687 demux->max_gap_time = g_value_get_uint64 (value);
5688 GST_OBJECT_UNLOCK (demux);
5691 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5697 gst_matroska_demux_get_property (GObject * object,
5698 guint prop_id, GValue * value, GParamSpec * pspec)
5700 GstMatroskaDemux *demux;
5702 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5703 demux = GST_MATROSKA_DEMUX (object);
5706 case ARG_MAX_GAP_TIME:
5707 GST_OBJECT_LOCK (demux);
5708 g_value_set_uint64 (value, demux->max_gap_time);
5709 GST_OBJECT_UNLOCK (demux);
5712 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5718 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5722 /* parser helper separate debug */
5723 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5724 0, "EBML stream helper class");
5726 /* create an elementfactory for the matroska_demux element */
5727 if (!gst_element_register (plugin, "matroskademux",
5728 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))