1 /* GStreamer Matroska muxer/demuxer
2 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3 * (c) 2006 Tim-Philipp Müller <tim centricular net>
4 * (c) 2008 Sebastian Dröge <slomo@circular-chaos.org>
5 * (c) 2011 Debarshi Ray <rishi@gnu.org>
7 * matroska-demux.c: matroska file/stream demuxer
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
25 /* TODO: check CRC32 if present
26 * TODO: there can be a segment after the first segment. Handle like
27 * chained oggs. Fixes #334082
28 * TODO: Test samples: http://www.matroska.org/samples/matrix/index.html
29 * http://samples.mplayerhq.hu/Matroska/
30 * TODO: check if demuxing is done correct for all codecs according to spec
31 * TODO: seeking with incomplete or without CUE
35 * SECTION:element-matroskademux
37 * matroskademux demuxes a Matroska file into the different contained streams.
40 * <title>Example launch line</title>
42 * gst-launch-1.0 -v filesrc location=/path/to/mkv ! matroskademux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
43 * ]| This pipeline demuxes a Matroska file and outputs the contained Vorbis audio.
54 #include <glib/gprintf.h>
56 /* For AVI compatibility mode
57 and for fourcc stuff */
58 #include <gst/riff/riff-read.h>
59 #include <gst/riff/riff-ids.h>
60 #include <gst/riff/riff-media.h>
62 #include <gst/audio/audio.h>
63 #include <gst/tag/tag.h>
64 #include <gst/pbutils/pbutils.h>
66 #include "matroska-demux.h"
67 #include "matroska-ids.h"
69 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
70 #define GST_CAT_DEFAULT matroskademux_debug
72 #define DEBUG_ELEMENT_START(demux, ebml, element) \
73 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
74 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
76 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
77 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
78 " finished with '%s'", gst_flow_get_name (ret))
88 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
90 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
93 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
94 "video/x-matroska-3d; audio/webm; video/webm")
97 /* TODO: fill in caps! */
99 static GstStaticPadTemplate audio_src_templ =
100 GST_STATIC_PAD_TEMPLATE ("audio_%u",
103 GST_STATIC_CAPS ("ANY")
106 static GstStaticPadTemplate video_src_templ =
107 GST_STATIC_PAD_TEMPLATE ("video_%u",
110 GST_STATIC_CAPS ("ANY")
113 static GstStaticPadTemplate subtitle_src_templ =
114 GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
117 GST_STATIC_CAPS ("text/x-raw, format=pango-markup; application/x-ssa; "
118 "application/x-ass;application/x-usf; subpicture/x-dvd; "
119 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
122 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
123 guint32 id, guint64 length, guint needed);
125 /* element functions */
126 static void gst_matroska_demux_loop (GstPad * pad);
128 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
130 static gboolean gst_matroska_demux_element_query (GstElement * element,
134 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad,
136 static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
137 GstObject * parent, GstPadMode mode, gboolean active);
139 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
140 GstPad * pad, GstEvent * event);
141 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
142 GstObject * parent, GstEvent * event);
143 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
144 GstObject * parent, GstQuery * query);
146 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
147 GstObject * parent, GstEvent * event);
148 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
149 GstObject * object, GstBuffer * buffer);
151 static GstStateChangeReturn
152 gst_matroska_demux_change_state (GstElement * element,
153 GstStateChange transition);
156 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
157 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
161 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
162 * videocontext, const gchar * codec_id, guint8 * data, guint size,
163 gchar ** codec_name, guint32 * riff_fourcc);
164 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
165 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
166 gchar ** codec_name, guint16 * riff_audio_fmt);
168 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
169 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
172 static void gst_matroska_demux_reset (GstElement * element);
173 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
174 gdouble rate, guint64 offset);
176 /* gobject functions */
177 static void gst_matroska_demux_set_property (GObject * object,
178 guint prop_id, const GValue * value, GParamSpec * pspec);
179 static void gst_matroska_demux_get_property (GObject * object,
180 guint prop_id, GValue * value, GParamSpec * pspec);
182 GType gst_matroska_demux_get_type (void);
183 #define parent_class gst_matroska_demux_parent_class
184 G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
187 gst_matroska_demux_finalize (GObject * object)
189 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
191 if (demux->common.src) {
192 g_ptr_array_free (demux->common.src, TRUE);
193 demux->common.src = NULL;
196 if (demux->common.global_tags) {
197 gst_tag_list_unref (demux->common.global_tags);
198 demux->common.global_tags = NULL;
201 g_object_unref (demux->common.adapter);
203 G_OBJECT_CLASS (parent_class)->finalize (object);
207 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
209 GObjectClass *gobject_class = (GObjectClass *) klass;
210 GstElementClass *gstelement_class = (GstElementClass *) klass;
212 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
215 gobject_class->finalize = gst_matroska_demux_finalize;
217 gobject_class->get_property = gst_matroska_demux_get_property;
218 gobject_class->set_property = gst_matroska_demux_set_property;
220 g_object_class_install_property (gobject_class, ARG_MAX_GAP_TIME,
221 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
222 "The demuxer sends out segment events for skipping "
223 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
224 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
226 gstelement_class->change_state =
227 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
228 gstelement_class->send_event =
229 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
230 gstelement_class->query =
231 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
233 gstelement_class->set_index =
234 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
235 gstelement_class->get_index =
236 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
239 gst_element_class_add_pad_template (gstelement_class,
240 gst_static_pad_template_get (&video_src_templ));
241 gst_element_class_add_pad_template (gstelement_class,
242 gst_static_pad_template_get (&audio_src_templ));
243 gst_element_class_add_pad_template (gstelement_class,
244 gst_static_pad_template_get (&subtitle_src_templ));
245 gst_element_class_add_pad_template (gstelement_class,
246 gst_static_pad_template_get (&sink_templ));
248 gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
250 "Demuxes Matroska/WebM streams into video/audio/subtitles",
251 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
255 gst_matroska_demux_init (GstMatroskaDemux * demux)
257 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
259 gst_pad_set_activate_function (demux->common.sinkpad,
260 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
261 gst_pad_set_activatemode_function (demux->common.sinkpad,
262 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
263 gst_pad_set_chain_function (demux->common.sinkpad,
264 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
265 gst_pad_set_event_function (demux->common.sinkpad,
266 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
267 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
269 /* initial stream no. */
270 demux->common.src = NULL;
272 demux->common.writing_app = NULL;
273 demux->common.muxing_app = NULL;
274 demux->common.index = NULL;
275 demux->common.global_tags = NULL;
277 demux->common.adapter = gst_adapter_new ();
279 /* property defaults */
280 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
282 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
285 gst_matroska_demux_reset (GST_ELEMENT (demux));
289 gst_matroska_track_free (GstMatroskaTrackContext * track)
291 g_free (track->codec_id);
292 g_free (track->codec_name);
293 g_free (track->name);
294 g_free (track->language);
295 g_free (track->codec_priv);
296 g_free (track->codec_state);
298 if (track->encodings != NULL) {
301 for (i = 0; i < track->encodings->len; ++i) {
302 GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
303 GstMatroskaTrackEncoding,
306 g_free (enc->comp_settings);
308 g_array_free (track->encodings, TRUE);
311 if (track->pending_tags)
312 gst_tag_list_unref (track->pending_tags);
314 if (track->index_table)
315 g_array_free (track->index_table, TRUE);
317 if (track->stream_headers)
318 gst_buffer_list_unref (track->stream_headers);
324 * Returns the aggregated GstFlowReturn.
327 gst_matroska_demux_combine_flows (GstMatroskaDemux * demux,
328 GstMatroskaTrackContext * track, GstFlowReturn ret)
332 /* store the value */
333 track->last_flow = ret;
335 /* any other error that is not-linked can be returned right away */
336 if (ret != GST_FLOW_NOT_LINKED)
339 /* only return NOT_LINKED if all other pads returned NOT_LINKED */
340 g_assert (demux->common.src->len == demux->common.num_streams);
341 for (i = 0; i < demux->common.src->len; i++) {
342 GstMatroskaTrackContext *ostream = g_ptr_array_index (demux->common.src,
348 ret = ostream->last_flow;
349 /* some other return value (must be SUCCESS but we can return
350 * other values as well) */
351 if (ret != GST_FLOW_NOT_LINKED)
354 /* if we get here, all other pads were unlinked and we return
357 GST_LOG_OBJECT (demux, "combined return %s", gst_flow_get_name (ret));
362 gst_matroska_demux_free_parsed_el (gpointer mem, gpointer user_data)
364 g_slice_free (guint64, mem);
368 gst_matroska_demux_reset (GstElement * element)
370 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
373 GST_DEBUG_OBJECT (demux, "Resetting state");
376 demux->common.state = GST_MATROSKA_READ_STATE_START;
378 /* clean up existing streams */
379 if (demux->common.src) {
380 g_assert (demux->common.src->len == demux->common.num_streams);
381 for (i = 0; i < demux->common.src->len; i++) {
382 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
385 if (context->pad != NULL)
386 gst_element_remove_pad (GST_ELEMENT (demux), context->pad);
388 gst_caps_replace (&context->caps, NULL);
389 gst_matroska_track_free (context);
391 g_ptr_array_free (demux->common.src, TRUE);
393 demux->common.src = g_ptr_array_new ();
395 demux->common.num_streams = 0;
396 demux->num_a_streams = 0;
397 demux->num_t_streams = 0;
398 demux->num_v_streams = 0;
400 /* reset media info */
401 g_free (demux->common.writing_app);
402 demux->common.writing_app = NULL;
403 g_free (demux->common.muxing_app);
404 demux->common.muxing_app = NULL;
407 if (demux->common.index) {
408 g_array_free (demux->common.index, TRUE);
409 demux->common.index = NULL;
412 if (demux->clusters) {
413 g_array_free (demux->clusters, TRUE);
414 demux->clusters = NULL;
419 demux->common.time_scale = 1000000;
420 demux->common.created = G_MININT64;
422 demux->common.index_parsed = FALSE;
423 demux->tracks_parsed = FALSE;
424 demux->common.segmentinfo_parsed = FALSE;
425 demux->common.attachments_parsed = FALSE;
426 demux->common.chapters_parsed = FALSE;
428 g_list_foreach (demux->common.tags_parsed,
429 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
430 g_list_free (demux->common.tags_parsed);
431 demux->common.tags_parsed = NULL;
433 g_list_foreach (demux->seek_parsed,
434 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
435 g_list_free (demux->seek_parsed);
436 demux->seek_parsed = NULL;
438 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
439 demux->last_stop_end = GST_CLOCK_TIME_NONE;
440 demux->seek_block = 0;
441 demux->stream_start_time = GST_CLOCK_TIME_NONE;
442 demux->to_time = GST_CLOCK_TIME_NONE;
444 demux->common.offset = 0;
445 demux->cluster_time = GST_CLOCK_TIME_NONE;
446 demux->cluster_offset = 0;
447 demux->next_cluster_offset = 0;
448 demux->index_offset = 0;
449 demux->seekable = FALSE;
450 demux->need_segment = FALSE;
451 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
452 demux->seek_offset = -1;
453 demux->building_index = FALSE;
454 if (demux->seek_event) {
455 gst_event_unref (demux->seek_event);
456 demux->seek_event = NULL;
459 demux->seek_index = NULL;
460 demux->seek_entry = 0;
462 if (demux->new_segment) {
463 gst_event_unref (demux->new_segment);
464 demux->new_segment = NULL;
467 if (demux->common.element_index) {
468 gst_object_unref (demux->common.element_index);
469 demux->common.element_index = NULL;
471 demux->common.element_index_writer_id = -1;
474 if (demux->common.global_tags) {
475 gst_tag_list_unref (demux->common.global_tags);
477 demux->common.global_tags = gst_tag_list_new_empty ();
478 gst_tag_list_set_scope (demux->common.global_tags, GST_TAG_SCOPE_GLOBAL);
480 if (demux->common.cached_buffer) {
481 if (demux->common.cached_data) {
482 gst_buffer_unmap (demux->common.cached_buffer, &demux->common.cached_map);
483 demux->common.cached_data = NULL;
485 gst_buffer_unref (demux->common.cached_buffer);
486 demux->common.cached_buffer = NULL;
489 /* free chapters TOC if any */
490 if (demux->common.toc) {
491 gst_toc_unref (demux->common.toc);
492 demux->common.toc = NULL;
495 demux->invalid_duration = FALSE;
499 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
505 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
507 GST_DEBUG ("decoding buffer %p", buf);
509 gst_buffer_map (buf, &map, GST_MAP_READ);
513 g_return_val_if_fail (size > 0, buf);
515 if (gst_matroska_decode_data (context->encodings, &data, &size,
516 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
517 gst_buffer_unmap (buf, &map);
518 gst_buffer_unref (buf);
519 return gst_buffer_new_wrapped (data, size);
521 GST_DEBUG ("decode data failed");
522 gst_buffer_unmap (buf, &map);
523 gst_buffer_unref (buf);
529 gst_matroska_demux_add_stream_headers_to_caps (GstMatroskaDemux * demux,
530 GstBufferList * list, GstCaps * caps)
533 GValue arr_val = G_VALUE_INIT;
534 GValue buf_val = G_VALUE_INIT;
537 g_assert (gst_caps_is_writable (caps));
539 g_value_init (&arr_val, GST_TYPE_ARRAY);
540 g_value_init (&buf_val, GST_TYPE_BUFFER);
542 num = gst_buffer_list_length (list);
543 for (i = 0; i < num; ++i) {
544 g_value_set_boxed (&buf_val, gst_buffer_list_get (list, i));
545 gst_value_array_append_value (&arr_val, &buf_val);
548 s = gst_caps_get_structure (caps, 0);
549 gst_structure_take_value (s, "streamheader", &arr_val);
550 g_value_unset (&buf_val);
554 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
556 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
557 GstMatroskaTrackContext *context;
558 GstPadTemplate *templ = NULL;
559 GstStreamFlags stream_flags;
560 GstCaps *caps = NULL;
561 gchar *padname = NULL;
563 guint32 id, riff_fourcc = 0;
564 guint16 riff_audio_fmt = 0;
565 GstTagList *list = NULL;
566 GstEvent *stream_start;
570 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
572 /* start with the master */
573 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
574 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
578 /* allocate generic... if we know the type, we'll g_renew()
579 * with the precise type */
580 context = g_new0 (GstMatroskaTrackContext, 1);
581 g_ptr_array_add (demux->common.src, context);
582 context->index = demux->common.num_streams;
583 context->index_writer_id = -1;
584 context->type = 0; /* no type yet */
585 context->default_duration = 0;
587 context->set_discont = TRUE;
588 context->timecodescale = 1.0;
590 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
591 GST_MATROSKA_TRACK_LACING;
592 context->last_flow = GST_FLOW_OK;
593 context->from_time = GST_CLOCK_TIME_NONE;
594 context->from_offset = -1;
595 context->to_offset = G_MAXINT64;
596 context->alignment = 1;
597 demux->common.num_streams++;
598 g_assert (demux->common.src->len == demux->common.num_streams);
600 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
602 /* try reading the trackentry headers */
603 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
604 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
608 /* track number (unique stream ID) */
609 case GST_MATROSKA_ID_TRACKNUMBER:{
612 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
616 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
617 ret = GST_FLOW_ERROR;
619 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
621 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
622 " is not unique", num);
623 ret = GST_FLOW_ERROR;
627 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
631 /* track UID (unique identifier) */
632 case GST_MATROSKA_ID_TRACKUID:{
635 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
639 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
640 ret = GST_FLOW_ERROR;
644 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
649 /* track type (video, audio, combined, subtitle, etc.) */
650 case GST_MATROSKA_ID_TRACKTYPE:{
653 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
657 if (context->type != 0 && context->type != track_type) {
658 GST_WARNING_OBJECT (demux,
659 "More than one tracktype defined in a TrackEntry - skipping");
661 } else if (track_type < 1 || track_type > 254) {
662 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
667 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
669 /* ok, so we're actually going to reallocate this thing */
670 switch (track_type) {
671 case GST_MATROSKA_TRACK_TYPE_VIDEO:
672 gst_matroska_track_init_video_context (&context);
674 case GST_MATROSKA_TRACK_TYPE_AUDIO:
675 gst_matroska_track_init_audio_context (&context);
677 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
678 gst_matroska_track_init_subtitle_context (&context);
680 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
681 case GST_MATROSKA_TRACK_TYPE_LOGO:
682 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
683 case GST_MATROSKA_TRACK_TYPE_CONTROL:
685 GST_WARNING_OBJECT (demux,
686 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
691 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
696 /* tracktype specific stuff for video */
697 case GST_MATROSKA_ID_TRACKVIDEO:{
698 GstMatroskaTrackVideoContext *videocontext;
700 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
702 if (!gst_matroska_track_init_video_context (&context)) {
703 GST_WARNING_OBJECT (demux,
704 "TrackVideo element in non-video track - ignoring track");
705 ret = GST_FLOW_ERROR;
707 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
710 videocontext = (GstMatroskaTrackVideoContext *) context;
711 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
714 while (ret == GST_FLOW_OK &&
715 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
716 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
720 /* Should be one level up but some broken muxers write it here. */
721 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
724 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
728 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
732 GST_DEBUG_OBJECT (demux,
733 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
734 context->default_duration = num;
738 /* video framerate */
739 /* NOTE: This one is here only for backward compatibility.
740 * Use _TRACKDEFAULDURATION one level up. */
741 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
744 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
748 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
752 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
753 if (context->default_duration == 0)
754 context->default_duration =
755 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
756 videocontext->default_fps = num;
760 /* width of the size to display the video at */
761 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
764 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
768 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
772 GST_DEBUG_OBJECT (demux,
773 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
774 videocontext->display_width = num;
778 /* height of the size to display the video at */
779 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
782 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
786 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
790 GST_DEBUG_OBJECT (demux,
791 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
792 videocontext->display_height = num;
796 /* width of the video in the file */
797 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
800 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
804 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
808 GST_DEBUG_OBJECT (demux,
809 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
810 videocontext->pixel_width = num;
814 /* height of the video in the file */
815 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
818 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
822 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
826 GST_DEBUG_OBJECT (demux,
827 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
828 videocontext->pixel_height = num;
832 /* whether the video is interlaced */
833 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
836 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
840 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
842 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
843 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
844 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
849 /* aspect ratio behaviour */
850 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
853 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
856 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
857 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
858 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
859 GST_WARNING_OBJECT (demux,
860 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
863 GST_DEBUG_OBJECT (demux,
864 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
865 videocontext->asr_mode = num;
869 /* colourspace (only matters for raw video) fourcc */
870 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
875 gst_ebml_read_binary (ebml, &id, &data,
876 &datalen)) != GST_FLOW_OK)
881 GST_WARNING_OBJECT (demux,
882 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
887 memcpy (&videocontext->fourcc, data, 4);
888 GST_DEBUG_OBJECT (demux,
889 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
890 GST_FOURCC_ARGS (videocontext->fourcc));
896 GST_WARNING_OBJECT (demux,
897 "Unknown TrackVideo subelement 0x%x - ignoring", id);
899 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
900 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
901 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
902 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
903 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
904 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
905 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
906 ret = gst_ebml_read_skip (ebml);
911 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
915 /* tracktype specific stuff for audio */
916 case GST_MATROSKA_ID_TRACKAUDIO:{
917 GstMatroskaTrackAudioContext *audiocontext;
919 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
921 if (!gst_matroska_track_init_audio_context (&context)) {
922 GST_WARNING_OBJECT (demux,
923 "TrackAudio element in non-audio track - ignoring track");
924 ret = GST_FLOW_ERROR;
928 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
931 audiocontext = (GstMatroskaTrackAudioContext *) context;
932 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
935 while (ret == GST_FLOW_OK &&
936 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
937 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
942 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
945 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
950 GST_WARNING_OBJECT (demux,
951 "Invalid TrackAudioSamplingFrequency %lf", num);
955 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
956 audiocontext->samplerate = num;
961 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
964 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
968 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
972 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
974 audiocontext->bitdepth = num;
979 case GST_MATROSKA_ID_AUDIOCHANNELS:{
982 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
986 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
990 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
992 audiocontext->channels = num;
997 GST_WARNING_OBJECT (demux,
998 "Unknown TrackAudio subelement 0x%x - ignoring", id);
1000 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
1001 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
1002 ret = gst_ebml_read_skip (ebml);
1007 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
1012 /* codec identifier */
1013 case GST_MATROSKA_ID_CODECID:{
1016 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
1019 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
1020 context->codec_id = text;
1024 /* codec private data */
1025 case GST_MATROSKA_ID_CODECPRIVATE:{
1030 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
1033 context->codec_priv = data;
1034 context->codec_priv_size = size;
1036 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1041 /* name of the codec */
1042 case GST_MATROSKA_ID_CODECNAME:{
1045 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1048 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1049 context->codec_name = text;
1053 /* name of this track */
1054 case GST_MATROSKA_ID_TRACKNAME:{
1057 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1060 context->name = text;
1061 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1065 /* language (matters for audio/subtitles, mostly) */
1066 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1069 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1073 context->language = text;
1076 if (strlen (context->language) >= 4 && context->language[3] == '-')
1077 context->language[3] = '\0';
1079 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1080 GST_STR_NULL (context->language));
1084 /* whether this is actually used */
1085 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1088 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1092 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1094 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1096 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1097 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1101 /* whether it's the default for this track type */
1102 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1105 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1109 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1111 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1113 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1114 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
1118 /* whether the track must be used during playback */
1119 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1122 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1126 context->flags |= GST_MATROSKA_TRACK_FORCED;
1128 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1130 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1131 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
1135 /* lacing (like MPEG, where blocks don't end/start on frame
1137 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1140 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1144 context->flags |= GST_MATROSKA_TRACK_LACING;
1146 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1148 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1149 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
1153 /* default length (in time) of one data block in this track */
1154 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1157 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1162 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1166 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1168 context->default_duration = num;
1172 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1173 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1178 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1181 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1185 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1189 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1190 context->timecodescale = num;
1195 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1198 /* we ignore these because they're nothing useful (i.e. crap)
1199 * or simply not implemented yet. */
1200 case GST_MATROSKA_ID_TRACKMINCACHE:
1201 case GST_MATROSKA_ID_TRACKMAXCACHE:
1202 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1203 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1204 case GST_MATROSKA_ID_TRACKOVERLAY:
1205 case GST_MATROSKA_ID_TRACKTRANSLATE:
1206 case GST_MATROSKA_ID_TRACKOFFSET:
1207 case GST_MATROSKA_ID_CODECSETTINGS:
1208 case GST_MATROSKA_ID_CODECINFOURL:
1209 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1210 case GST_MATROSKA_ID_CODECDECODEALL:
1211 ret = gst_ebml_read_skip (ebml);
1216 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1218 /* Decode codec private data if necessary */
1219 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1220 && context->codec_priv_size > 0) {
1221 if (!gst_matroska_decode_data (context->encodings,
1222 &context->codec_priv, &context->codec_priv_size,
1223 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1224 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1225 ret = GST_FLOW_ERROR;
1229 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1230 && ret != GST_FLOW_EOS)) {
1231 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1232 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1234 demux->common.num_streams--;
1235 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1236 g_assert (demux->common.src->len == demux->common.num_streams);
1238 gst_matroska_track_free (context);
1244 /* now create the GStreamer connectivity */
1245 switch (context->type) {
1246 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1247 GstMatroskaTrackVideoContext *videocontext =
1248 (GstMatroskaTrackVideoContext *) context;
1250 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1251 templ = gst_element_class_get_pad_template (klass, "video_%u");
1252 caps = gst_matroska_demux_video_caps (videocontext,
1253 context->codec_id, context->codec_priv,
1254 context->codec_priv_size, &codec, &riff_fourcc);
1257 list = gst_tag_list_new (GST_TAG_VIDEO_CODEC, codec, NULL);
1263 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1264 GstMatroskaTrackAudioContext *audiocontext =
1265 (GstMatroskaTrackAudioContext *) context;
1267 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1268 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1269 caps = gst_matroska_demux_audio_caps (audiocontext,
1270 context->codec_id, context->codec_priv, context->codec_priv_size,
1271 &codec, &riff_audio_fmt);
1274 list = gst_tag_list_new (GST_TAG_AUDIO_CODEC, codec, NULL);
1280 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1281 GstMatroskaTrackSubtitleContext *subtitlecontext =
1282 (GstMatroskaTrackSubtitleContext *) context;
1284 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1285 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1286 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1287 context->codec_id, context->codec_priv, context->codec_priv_size);
1291 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1292 case GST_MATROSKA_TRACK_TYPE_LOGO:
1293 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1294 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1296 /* we should already have quit by now */
1297 g_assert_not_reached ();
1300 if ((context->language == NULL || *context->language == '\0') &&
1301 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1302 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1303 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1304 context->language = g_strdup ("eng");
1307 if (context->language) {
1311 list = gst_tag_list_new_empty ();
1313 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1314 lang = gst_tag_get_language_code (context->language);
1315 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1316 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1320 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1321 "codec_id='%s'", context->codec_id);
1322 switch (context->type) {
1323 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1324 caps = gst_caps_new_empty_simple ("video/x-unknown");
1326 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1327 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1329 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1330 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1332 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1334 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1337 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1340 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1341 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1342 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1343 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1344 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1345 GST_FOURCC_ARGS (riff_fourcc));
1346 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1349 } else if (context->stream_headers != NULL) {
1350 gst_matroska_demux_add_stream_headers_to_caps (demux,
1351 context->stream_headers, caps);
1354 /* the pad in here */
1355 context->pad = gst_pad_new_from_template (templ, padname);
1356 context->caps = caps;
1358 gst_pad_set_event_function (context->pad,
1359 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1360 gst_pad_set_query_function (context->pad,
1361 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1363 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1366 context->pending_tags = list;
1368 gst_pad_set_element_private (context->pad, context);
1370 gst_pad_use_fixed_caps (context->pad);
1371 gst_pad_set_active (context->pad, TRUE);
1374 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1375 "%03u", context->uid);
1376 stream_start = gst_event_new_stream_start (stream_id);
1378 stream_flags = GST_STREAM_FLAG_NONE;
1379 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1380 stream_flags |= GST_STREAM_FLAG_SPARSE;
1381 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1382 stream_flags |= GST_STREAM_FLAG_SELECT;
1383 gst_event_set_stream_flags (stream_start, stream_flags);
1384 gst_pad_push_event (context->pad, stream_start);
1385 gst_pad_set_caps (context->pad, context->caps);
1387 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1396 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1399 gboolean res = FALSE;
1400 GstMatroskaTrackContext *context = NULL;
1403 context = gst_pad_get_element_private (pad);
1406 switch (GST_QUERY_TYPE (query)) {
1407 case GST_QUERY_POSITION:
1411 gst_query_parse_position (query, &format, NULL);
1414 if (format == GST_FORMAT_TIME) {
1415 GST_OBJECT_LOCK (demux);
1417 gst_query_set_position (query, GST_FORMAT_TIME,
1418 MAX (context->pos, demux->stream_start_time) -
1419 demux->stream_start_time);
1421 gst_query_set_position (query, GST_FORMAT_TIME,
1422 MAX (demux->common.segment.position, demux->stream_start_time) -
1423 demux->stream_start_time);
1424 GST_OBJECT_UNLOCK (demux);
1425 } else if (format == GST_FORMAT_DEFAULT && context
1426 && context->default_duration) {
1427 GST_OBJECT_LOCK (demux);
1428 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1429 context->pos / context->default_duration);
1430 GST_OBJECT_UNLOCK (demux);
1432 GST_DEBUG_OBJECT (demux,
1433 "only position query in TIME and DEFAULT format is supported");
1439 case GST_QUERY_DURATION:
1443 gst_query_parse_duration (query, &format, NULL);
1446 if (format == GST_FORMAT_TIME) {
1447 GST_OBJECT_LOCK (demux);
1448 gst_query_set_duration (query, GST_FORMAT_TIME,
1449 demux->common.segment.duration);
1450 GST_OBJECT_UNLOCK (demux);
1451 } else if (format == GST_FORMAT_DEFAULT && context
1452 && context->default_duration) {
1453 GST_OBJECT_LOCK (demux);
1454 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1455 demux->common.segment.duration / context->default_duration);
1456 GST_OBJECT_UNLOCK (demux);
1458 GST_DEBUG_OBJECT (demux,
1459 "only duration query in TIME and DEFAULT format is supported");
1465 case GST_QUERY_SEEKING:
1469 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1470 GST_OBJECT_LOCK (demux);
1471 if (fmt == GST_FORMAT_TIME) {
1474 if (demux->streaming) {
1475 /* assuming we'll be able to get an index ... */
1476 seekable = demux->seekable;
1481 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1482 0, demux->common.segment.duration);
1485 GST_OBJECT_UNLOCK (demux);
1490 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1493 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1502 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1504 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1508 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1511 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1513 return gst_matroska_demux_query (demux, pad, query);
1516 /* returns FALSE if there are no pads to deliver event to,
1517 * otherwise TRUE (whatever the outcome of event sending),
1518 * takes ownership of the passed event! */
1520 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1522 gboolean is_segment;
1523 gboolean ret = FALSE;
1526 g_return_val_if_fail (event != NULL, FALSE);
1528 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1529 GST_EVENT_TYPE_NAME (event));
1531 is_segment = (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
1533 g_assert (demux->common.src->len == demux->common.num_streams);
1534 for (i = 0; i < demux->common.src->len; i++) {
1535 GstMatroskaTrackContext *stream;
1537 stream = g_ptr_array_index (demux->common.src, i);
1538 gst_event_ref (event);
1539 gst_pad_push_event (stream->pad, event);
1542 /* FIXME: send global tags before stream tags */
1543 if (G_UNLIKELY (is_segment && stream->pending_tags != NULL)) {
1544 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
1545 GST_PTR_FORMAT, stream->pending_tags,
1546 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
1547 gst_pad_push_event (stream->pad,
1548 gst_event_new_tag (stream->pending_tags));
1549 stream->pending_tags = NULL;
1553 if (G_UNLIKELY (is_segment && demux->common.global_tags != NULL)) {
1554 GstEvent *tag_event;
1555 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1556 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1557 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1558 demux->common.global_tags, demux->common.global_tags);
1560 tag_event = gst_event_new_tag (demux->common.global_tags);
1562 for (i = 0; i < demux->common.src->len; i++) {
1563 GstMatroskaTrackContext *stream;
1565 stream = g_ptr_array_index (demux->common.src, i);
1566 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1569 gst_event_unref (tag_event);
1570 demux->common.global_tags = NULL;
1573 gst_event_unref (event);
1578 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1580 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1583 g_return_val_if_fail (event != NULL, FALSE);
1585 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1586 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1588 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1589 GST_EVENT_TYPE_NAME (event));
1592 gst_event_unref (event);
1597 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1598 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1602 GST_OBJECT_LOCK (demux);
1605 /* seek (relative to matroska segment) */
1606 /* position might be invalid; will error when streaming resumes ... */
1607 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1608 demux->next_cluster_offset = 0;
1610 GST_DEBUG_OBJECT (demux,
1611 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1612 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1613 entry->block, GST_TIME_ARGS (entry->time));
1615 /* update the time */
1616 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1617 demux->common.segment.position = entry->time;
1618 demux->seek_block = entry->block;
1619 demux->seek_first = TRUE;
1620 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1623 for (i = 0; i < demux->common.src->len; i++) {
1624 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1627 stream->to_offset = G_MAXINT64;
1629 if (stream->from_offset != -1)
1630 stream->to_offset = stream->from_offset;
1632 stream->from_offset = -1;
1633 stream->from_time = GST_CLOCK_TIME_NONE;
1636 GST_OBJECT_UNLOCK (demux);
1642 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1652 /* searches for a cluster start from @pos,
1653 * return GST_FLOW_OK and cluster position in @pos if found */
1654 static GstFlowReturn
1655 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1657 gint64 newpos = *pos;
1659 GstFlowReturn ret = GST_FLOW_OK;
1660 const guint chunk = 64 * 1024;
1661 GstBuffer *buf = NULL;
1663 gpointer data = NULL;
1669 orig_offset = demux->common.offset;
1671 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1674 if (demux->clusters) {
1677 cpos = gst_util_array_binary_search (demux->clusters->data,
1678 demux->clusters->len, sizeof (gint64),
1679 (GCompareDataFunc) gst_matroska_cluster_compare,
1680 GST_SEARCH_MODE_AFTER, pos, NULL);
1683 GST_DEBUG_OBJECT (demux,
1684 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1685 demux->common.offset = *cpos;
1686 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1687 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1688 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1695 /* read in at newpos and scan for ebml cluster id */
1697 GstByteReader reader;
1701 gst_buffer_unmap (buf, &map);
1702 gst_buffer_unref (buf);
1705 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1706 if (ret != GST_FLOW_OK)
1708 GST_DEBUG_OBJECT (demux,
1709 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1710 gst_buffer_get_size (buf), newpos);
1711 gst_buffer_map (buf, &map, GST_MAP_READ);
1714 gst_byte_reader_init (&reader, data, size);
1716 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1717 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1718 if (cluster_pos >= 0) {
1719 newpos += cluster_pos;
1720 /* prepare resuming at next byte */
1721 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1722 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1725 GST_DEBUG_OBJECT (demux,
1726 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1727 /* extra checks whether we really sync'ed to a cluster:
1728 * - either it is the first and only cluster
1729 * - either there is a cluster after this one
1730 * - either cluster length is undefined
1732 /* ok if first cluster (there may not a subsequent one) */
1733 if (newpos == demux->first_cluster_offset) {
1734 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1737 demux->common.offset = newpos;
1738 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1739 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1740 if (ret != GST_FLOW_OK) {
1741 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1744 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1745 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1747 /* ok if undefined length or first cluster */
1748 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1749 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1753 demux->common.offset += length + needed;
1754 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1755 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1756 if (ret != GST_FLOW_OK)
1758 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1759 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1760 if (id == GST_MATROSKA_ID_CLUSTER)
1762 /* not ok, resume */
1765 /* partial cluster id may have been in tail of buffer */
1766 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1771 gst_buffer_unmap (buf, &map);
1772 gst_buffer_unref (buf);
1777 demux->common.offset = orig_offset;
1782 /* bisect and scan through file for cluster starting before @time,
1783 * returns fake index entry with corresponding info on cluster */
1784 static GstMatroskaIndex *
1785 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1787 GstMatroskaIndex *entry = NULL;
1788 GstMatroskaReadState current_state;
1789 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1790 gint64 opos, newpos, startpos = 0, current_offset;
1791 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1792 const guint chunk = 64 * 1024;
1798 /* (under)estimate new position, resync using cluster ebml id,
1799 * and scan forward to appropriate cluster
1800 * (and re-estimate if need to go backward) */
1802 prev_cluster_time = GST_CLOCK_TIME_NONE;
1804 /* store some current state */
1805 current_state = demux->common.state;
1806 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1808 current_cluster_offset = demux->cluster_offset;
1809 current_cluster_time = demux->cluster_time;
1810 current_offset = demux->common.offset;
1812 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1814 /* estimate using start and current position */
1815 GST_OBJECT_LOCK (demux);
1816 opos = demux->common.offset - demux->common.ebml_segment_start;
1817 otime = demux->common.segment.position;
1818 GST_OBJECT_UNLOCK (demux);
1821 time = MAX (time, demux->stream_start_time);
1823 /* avoid division by zero in first estimation below */
1824 if (otime <= demux->stream_start_time)
1828 GST_LOG_OBJECT (demux,
1829 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1830 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1831 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1832 GST_TIME_ARGS (otime - demux->stream_start_time),
1833 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1835 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1836 time - demux->stream_start_time,
1837 otime - demux->stream_start_time) - chunk;
1840 /* favour undershoot */
1841 newpos = newpos * 90 / 100;
1842 newpos += demux->common.ebml_segment_start;
1844 GST_DEBUG_OBJECT (demux,
1845 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1846 GST_TIME_ARGS (time), newpos);
1848 /* and at least start scanning before previous scan start to avoid looping */
1849 startpos = startpos * 90 / 100;
1850 if (startpos && startpos < newpos)
1853 /* read in at newpos and scan for ebml cluster id */
1857 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1858 if (ret == GST_FLOW_EOS) {
1859 /* heuristic HACK */
1860 newpos = startpos * 80 / 100;
1861 GST_DEBUG_OBJECT (demux, "EOS; "
1862 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1863 GST_TIME_ARGS (time), newpos);
1866 } else if (ret != GST_FLOW_OK) {
1873 /* then start scanning and parsing for cluster time,
1874 * re-estimate if overshoot, otherwise next cluster and so on */
1875 demux->common.offset = newpos;
1876 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1878 guint64 cluster_size = 0;
1880 /* peek and parse some elements */
1881 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1882 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1883 if (ret != GST_FLOW_OK)
1885 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1886 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1888 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1889 if (ret != GST_FLOW_OK)
1892 if (id == GST_MATROSKA_ID_CLUSTER) {
1893 cluster_time = GST_CLOCK_TIME_NONE;
1894 if (length == G_MAXUINT64)
1897 cluster_size = length + needed;
1899 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1900 cluster_time == GST_CLOCK_TIME_NONE) {
1901 cluster_time = demux->cluster_time * demux->common.time_scale;
1902 cluster_offset = demux->cluster_offset;
1903 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1904 " with time %" GST_TIME_FORMAT, cluster_offset,
1905 GST_TIME_ARGS (cluster_time));
1906 if (cluster_time > time) {
1907 GST_DEBUG_OBJECT (demux, "overshot target");
1908 /* cluster overshoots */
1909 if (cluster_offset == demux->first_cluster_offset) {
1910 /* but no prev one */
1911 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1912 prev_cluster_time = cluster_time;
1913 prev_cluster_offset = cluster_offset;
1916 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1917 /* prev cluster did not overshoot, so prev cluster is target */
1920 /* re-estimate using this new position info */
1921 opos = cluster_offset;
1922 otime = cluster_time;
1926 /* cluster undershoots, goto next one */
1927 prev_cluster_time = cluster_time;
1928 prev_cluster_offset = cluster_offset;
1929 /* skip cluster if length is defined,
1930 * otherwise will be skippingly parsed into */
1932 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1933 demux->common.offset = cluster_offset + cluster_size;
1934 demux->cluster_time = GST_CLOCK_TIME_NONE;
1936 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1943 if (ret == GST_FLOW_EOS) {
1944 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1950 entry = g_new0 (GstMatroskaIndex, 1);
1951 entry->time = prev_cluster_time;
1952 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1953 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1954 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1958 /* restore some state */
1959 demux->cluster_offset = current_cluster_offset;
1960 demux->cluster_time = current_cluster_time;
1961 demux->common.offset = current_offset;
1962 demux->common.state = current_state;
1968 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1969 GstPad * pad, GstEvent * event)
1971 GstMatroskaIndex *entry = NULL;
1972 GstMatroskaIndex scan_entry;
1974 GstSeekType cur_type, stop_type;
1976 gboolean flush, keyunit, before, after, snap_next;
1979 GstMatroskaTrackContext *track = NULL;
1980 GstSegment seeksegment = { 0, };
1981 gboolean update = TRUE;
1982 gboolean pad_locked = FALSE;
1985 track = gst_pad_get_element_private (pad);
1987 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1990 /* we can only seek on time */
1991 if (format != GST_FORMAT_TIME) {
1992 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1996 /* copy segment, we need this because we still need the old
1997 * segment when we close the current segment. */
1998 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
2000 /* pull mode without index means that the actual duration is not known,
2001 * we might be playing a file that's still being recorded
2002 * so, invalidate our current duration, which is only a moving target,
2003 * and should not be used to clamp anything */
2004 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
2005 seeksegment.duration = GST_CLOCK_TIME_NONE;
2009 GST_DEBUG_OBJECT (demux, "configuring seek");
2010 gst_segment_do_seek (&seeksegment, rate, format, flags,
2011 cur_type, cur, stop_type, stop, &update);
2012 /* compensate for clip start time, but only for SET seeks,
2013 * otherwise it is already part of the segments */
2014 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2015 if (cur_type == GST_SEEK_TYPE_SET) {
2017 seeksegment.position += demux->stream_start_time;
2018 seeksegment.start += demux->stream_start_time;
2020 if (stop_type == GST_SEEK_TYPE_SET
2021 && GST_CLOCK_TIME_IS_VALID (seeksegment.stop)) {
2023 seeksegment.position += demux->stream_start_time;
2024 seeksegment.stop += demux->stream_start_time;
2029 /* restore segment duration (if any effect),
2030 * would be determined again when parsing, but anyway ... */
2031 seeksegment.duration = demux->common.segment.duration;
2033 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2034 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2035 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
2036 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
2038 /* always do full update if flushing,
2039 * otherwise problems might arise downstream with missing keyframes etc */
2040 update = update || flush;
2042 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2044 /* check sanity before we start flushing and all that */
2045 snap_next = after && !before;
2046 if (seeksegment.rate < 0)
2047 snap_next = !snap_next;
2048 GST_OBJECT_LOCK (demux);
2049 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2050 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2051 seeksegment.position, &demux->seek_index, &demux->seek_entry,
2052 snap_next)) == NULL) {
2053 /* pull mode without index can scan later on */
2054 if (demux->streaming) {
2055 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2056 GST_OBJECT_UNLOCK (demux);
2058 } else if (rate < 0.0) {
2059 /* FIXME: We should build an index during playback or when scanning
2060 * that can be used here. The reverse playback code requires seek_index
2061 * and seek_entry to be set!
2063 GST_DEBUG_OBJECT (demux,
2064 "No matching seek entry in index, needed for reverse playback");
2065 GST_OBJECT_UNLOCK (demux);
2069 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2070 GST_OBJECT_UNLOCK (demux);
2073 /* only have to update some segment,
2074 * but also still have to honour flush and so on */
2075 GST_DEBUG_OBJECT (demux, "... no update");
2076 /* bad goto, bad ... */
2080 if (demux->streaming)
2085 GST_DEBUG_OBJECT (demux, "Starting flush");
2086 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_start ());
2087 gst_matroska_demux_send_event (demux, gst_event_new_flush_start ());
2089 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2090 gst_pad_pause_task (demux->common.sinkpad);
2094 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2098 /* now grab the stream lock so that streaming cannot continue, for
2099 * non flushing seeks when the element is in PAUSED this could block
2101 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2102 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2105 /* pull mode without index can do some scanning */
2106 if (!demux->streaming && !entry) {
2107 /* need to stop flushing upstream as we need it next */
2109 gst_pad_push_event (demux->common.sinkpad,
2110 gst_event_new_flush_stop (TRUE));
2111 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2112 /* keep local copy */
2114 scan_entry = *entry;
2116 entry = &scan_entry;
2118 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2120 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop (TRUE));
2127 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2128 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2129 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2130 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2131 seeksegment.position = seeksegment.start;
2132 seeksegment.time = seeksegment.start - demux->stream_start_time;
2135 if (demux->streaming) {
2136 GST_OBJECT_LOCK (demux);
2137 /* track real position we should start at */
2138 GST_DEBUG_OBJECT (demux, "storing segment start");
2139 demux->requested_seek_time = seeksegment.position;
2140 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2141 GST_OBJECT_UNLOCK (demux);
2142 /* need to seek to cluster start to pick up cluster time */
2143 /* upstream takes care of flushing and all that
2144 * ... and newsegment event handling takes care of the rest */
2145 return perform_seek_to_offset (demux, rate,
2146 entry->pos + demux->common.ebml_segment_start);
2151 GST_DEBUG_OBJECT (demux, "Stopping flush");
2152 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_stop (TRUE));
2153 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop (TRUE));
2156 GST_OBJECT_LOCK (demux);
2157 /* now update the real segment info */
2158 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2159 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2160 GST_OBJECT_UNLOCK (demux);
2162 /* update some (segment) state */
2163 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2166 /* notify start of new segment */
2167 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2170 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2171 GST_FORMAT_TIME, demux->common.segment.start);
2172 gst_element_post_message (GST_ELEMENT (demux), msg);
2175 GST_OBJECT_LOCK (demux);
2176 if (demux->new_segment)
2177 gst_event_unref (demux->new_segment);
2179 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2180 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2181 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2182 demux->to_time = demux->common.segment.position;
2184 demux->to_time = GST_CLOCK_TIME_NONE;
2185 GST_OBJECT_UNLOCK (demux);
2187 /* restart our task since it might have been stopped when we did the
2189 gst_pad_start_task (demux->common.sinkpad,
2190 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2192 /* streaming can continue now */
2194 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2202 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2204 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2210 * Handle whether we can perform the seek event or if we have to let the chain
2211 * function handle seeks to build the seek indexes first.
2214 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2218 GstSeekType cur_type, stop_type;
2223 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2228 /* we can only seek on time */
2229 if (format != GST_FORMAT_TIME) {
2230 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2234 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2235 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2239 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2240 GST_DEBUG_OBJECT (demux,
2241 "Non-flushing seek not supported in streaming mode");
2245 if (flags & GST_SEEK_FLAG_SEGMENT) {
2246 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2250 /* check for having parsed index already */
2251 if (!demux->common.index_parsed) {
2252 gboolean building_index;
2255 if (!demux->index_offset) {
2256 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2260 GST_OBJECT_LOCK (demux);
2261 /* handle the seek event in the chain function */
2262 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2263 /* no more seek can be issued until state reset to _DATA */
2265 /* copy the event */
2266 if (demux->seek_event)
2267 gst_event_unref (demux->seek_event);
2268 demux->seek_event = gst_event_ref (event);
2270 /* set the building_index flag so that only one thread can setup the
2271 * structures for index seeking. */
2272 building_index = demux->building_index;
2273 if (!building_index) {
2274 demux->building_index = TRUE;
2275 offset = demux->index_offset;
2277 GST_OBJECT_UNLOCK (demux);
2279 if (!building_index) {
2280 /* seek to the first subindex or legacy index */
2281 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2282 return perform_seek_to_offset (demux, rate, offset);
2285 /* well, we are handling it already */
2289 /* delegate to tweaked regular seek */
2290 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2294 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2297 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2298 gboolean res = TRUE;
2300 switch (GST_EVENT_TYPE (event)) {
2301 case GST_EVENT_SEEK:
2302 /* no seeking until we are (safely) ready */
2303 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2304 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2307 if (!demux->streaming)
2308 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2310 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2311 gst_event_unref (event);
2316 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2317 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2318 GstMatroskaTrackVideoContext *videocontext =
2319 (GstMatroskaTrackVideoContext *) context;
2321 GstClockTimeDiff diff;
2322 GstClockTime timestamp;
2324 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2326 GST_OBJECT_LOCK (demux);
2327 videocontext->earliest_time = timestamp + diff;
2328 GST_OBJECT_UNLOCK (demux);
2331 gst_event_unref (event);
2335 case GST_EVENT_TOC_SELECT:
2338 GstTocEntry *entry = NULL;
2339 GstEvent *seek_event;
2342 if (!demux->common.toc) {
2343 GST_DEBUG_OBJECT (demux, "no TOC to select");
2346 gst_event_parse_toc_select (event, &uid);
2348 GST_OBJECT_LOCK (demux);
2349 entry = gst_toc_find_entry (demux->common.toc, uid);
2350 if (entry == NULL) {
2351 GST_OBJECT_UNLOCK (demux);
2352 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2355 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2356 GST_OBJECT_UNLOCK (demux);
2357 seek_event = gst_event_new_seek (1.0,
2359 GST_SEEK_FLAG_FLUSH,
2360 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2361 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2362 gst_event_unref (seek_event);
2366 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2370 gst_event_unref (event);
2374 /* events we don't need to handle */
2375 case GST_EVENT_NAVIGATION:
2376 gst_event_unref (event);
2380 case GST_EVENT_LATENCY:
2382 res = gst_pad_push_event (demux->common.sinkpad, event);
2389 static GstFlowReturn
2390 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2392 GstFlowReturn ret = GST_FLOW_EOS;
2393 gboolean done = TRUE;
2396 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2397 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2400 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2402 if (!demux->seek_entry) {
2403 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2407 for (i = 0; i < demux->common.src->len; i++) {
2408 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2410 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2411 ", stream %d at %" GST_TIME_FORMAT,
2412 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2413 GST_TIME_ARGS (stream->from_time));
2414 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2415 if (stream->from_time > demux->common.segment.start) {
2416 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2420 /* nothing pushed for this stream;
2421 * likely seek entry did not start at keyframe, so all was skipped.
2422 * So we need an earlier entry */
2428 GstMatroskaIndex *entry;
2430 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2431 --demux->seek_entry);
2432 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2442 static GstFlowReturn
2443 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2445 GstFlowReturn ret = GST_FLOW_OK;
2448 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2450 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2451 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2455 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2456 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2460 /* one track within the "all-tracks" header */
2461 case GST_MATROSKA_ID_TRACKENTRY:
2462 ret = gst_matroska_demux_add_stream (demux, ebml);
2466 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2471 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2473 demux->tracks_parsed = TRUE;
2479 * Read signed/unsigned "EBML" numbers.
2480 * Return: number of bytes processed.
2484 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2486 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2494 while (read <= 8 && !(total & len_mask)) {
2501 if ((total &= (len_mask - 1)) == len_mask - 1)
2506 if (data[n] == 0xff)
2508 total = (total << 8) | data[n];
2512 if (read == num_ffs && total != 0)
2521 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2526 /* read as unsigned number first */
2527 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2531 if (unum == G_MAXUINT64)
2534 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2540 * Mostly used for subtitles. We add void filler data for each
2541 * lagging stream to make sure we don't deadlock.
2545 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2549 GST_OBJECT_LOCK (demux);
2551 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2552 GST_TIME_ARGS (demux->common.segment.position));
2554 g_assert (demux->common.num_streams == demux->common.src->len);
2555 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2556 GstMatroskaTrackContext *context;
2558 context = g_ptr_array_index (demux->common.src, stream_nr);
2560 GST_LOG_OBJECT (demux,
2561 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2562 GST_TIME_ARGS (context->pos));
2564 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2565 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2569 /* does it lag? 0.5 seconds is a random threshold...
2570 * lag need only be considered if we have advanced into requested segment */
2571 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2572 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2573 demux->common.segment.position > demux->common.segment.start &&
2574 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2577 guint64 start = context->pos;
2578 guint64 stop = demux->common.segment.position - (GST_SECOND / 2);
2580 GST_DEBUG_OBJECT (demux,
2581 "Synchronizing stream %d with other by advancing time from %"
2582 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2583 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2585 context->pos = stop;
2587 event = gst_event_new_gap (start, stop - start);
2588 GST_OBJECT_UNLOCK (demux);
2589 gst_pad_push_event (context->pad, event);
2590 GST_OBJECT_LOCK (demux);
2594 GST_OBJECT_UNLOCK (demux);
2597 static GstFlowReturn
2598 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2599 GstMatroskaTrackContext * stream)
2601 GstFlowReturn ret = GST_FLOW_OK;
2604 num = gst_buffer_list_length (stream->stream_headers);
2605 for (i = 0; i < num; ++i) {
2608 buf = gst_buffer_list_get (stream->stream_headers, i);
2609 buf = gst_buffer_copy (buf);
2611 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2613 if (stream->set_discont) {
2614 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2615 stream->set_discont = FALSE;
2618 /* push out all headers in one go and use last flow return */
2619 ret = gst_pad_push (stream->pad, buf);
2622 /* don't need these any longer */
2623 gst_buffer_list_unref (stream->stream_headers);
2624 stream->stream_headers = NULL;
2627 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
2633 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2634 GstMatroskaTrackContext * stream)
2638 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2640 if (!stream->codec_priv)
2643 /* ideally, VobSub private data should be parsed and stored more convenient
2644 * elsewhere, but for now, only interested in a small part */
2646 /* make sure we have terminating 0 */
2647 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2649 /* just locate and parse palette part */
2650 start = strstr (buf, "palette:");
2655 guint8 r, g, b, y, u, v;
2658 while (g_ascii_isspace (*start))
2660 for (i = 0; i < 16; i++) {
2661 if (sscanf (start, "%06x", &col) != 1)
2664 while ((*start == ',') || g_ascii_isspace (*start))
2666 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2667 r = (col >> 16) & 0xff;
2668 g = (col >> 8) & 0xff;
2670 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2672 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2673 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2674 clut[i] = (y << 16) | (u << 8) | v;
2677 /* got them all without problems; build and send event */
2681 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2682 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2683 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2684 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2685 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2686 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2687 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2688 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2689 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2690 G_TYPE_INT, clut[15], NULL);
2692 gst_pad_push_event (stream->pad,
2693 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
2699 static GstFlowReturn
2700 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2701 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2704 guint seq_header_len;
2705 guint32 header, tmp;
2707 if (stream->codec_state) {
2708 seq_header = stream->codec_state;
2709 seq_header_len = stream->codec_state_size;
2710 } else if (stream->codec_priv) {
2711 seq_header = stream->codec_priv;
2712 seq_header_len = stream->codec_priv_size;
2717 /* Sequence header only needed for keyframes */
2718 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2721 if (gst_buffer_get_size (*buf) < 4)
2724 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2725 header = GUINT32_FROM_BE (tmp);
2727 /* Sequence start code, if not found prepend */
2728 if (header != 0x000001b3) {
2731 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2733 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2736 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2737 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2738 gst_buffer_get_size (*buf));
2740 gst_buffer_unref (*buf);
2747 static GstFlowReturn
2748 gst_matroska_demux_add_wvpk_header (GstElement * element,
2749 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2751 GstMatroskaTrackAudioContext *audiocontext =
2752 (GstMatroskaTrackAudioContext *) stream;
2753 GstBuffer *newbuf = NULL;
2754 GstMapInfo map, outmap;
2755 guint8 *buf_data, *data;
2763 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2766 wvh.total_samples = -1;
2767 wvh.block_index = audiocontext->wvpk_block_index;
2769 if (audiocontext->channels <= 2) {
2770 guint32 block_samples, tmp;
2771 gsize size = gst_buffer_get_size (*buf);
2773 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2774 block_samples = GUINT32_FROM_LE (tmp);
2775 /* we need to reconstruct the header of the wavpack block */
2777 /* -20 because ck_size is the size of the wavpack block -8
2778 * and lace_size is the size of the wavpack block + 12
2779 * (the three guint32 of the header that already are in the buffer) */
2780 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2782 /* block_samples, flags and crc are already in the buffer */
2783 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2785 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2791 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2792 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2793 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2794 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2795 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2796 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2798 /* Append data from buf: */
2799 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2800 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2802 gst_buffer_unref (*buf);
2804 audiocontext->wvpk_block_index += block_samples;
2806 guint8 *outdata = NULL;
2808 gsize buf_size, size, out_size = 0;
2809 guint32 block_samples, flags, crc, blocksize;
2811 gst_buffer_map (*buf, &map, GST_MAP_READ);
2812 buf_data = map.data;
2813 buf_size = map.size;
2816 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2817 gst_buffer_unmap (*buf, &map);
2818 return GST_FLOW_ERROR;
2824 block_samples = GST_READ_UINT32_LE (data);
2829 flags = GST_READ_UINT32_LE (data);
2832 crc = GST_READ_UINT32_LE (data);
2835 blocksize = GST_READ_UINT32_LE (data);
2839 if (blocksize == 0 || size < blocksize)
2842 g_assert ((newbuf == NULL) == (outdata == NULL));
2844 if (newbuf == NULL) {
2845 out_size = sizeof (Wavpack4Header) + blocksize;
2846 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2848 gst_buffer_copy_into (newbuf, *buf,
2849 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2852 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2853 outdata = outmap.data;
2855 gst_buffer_unmap (newbuf, &outmap);
2856 out_size += sizeof (Wavpack4Header) + blocksize;
2857 gst_buffer_set_size (newbuf, out_size);
2858 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2859 outdata = outmap.data;
2862 outdata[outpos] = 'w';
2863 outdata[outpos + 1] = 'v';
2864 outdata[outpos + 2] = 'p';
2865 outdata[outpos + 3] = 'k';
2868 GST_WRITE_UINT32_LE (outdata + outpos,
2869 blocksize + sizeof (Wavpack4Header) - 8);
2870 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2871 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2872 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2873 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2874 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2875 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2876 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2877 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2880 g_memmove (outdata + outpos, data, blocksize);
2881 outpos += blocksize;
2885 gst_buffer_unmap (*buf, &map);
2886 gst_buffer_unref (*buf);
2889 gst_buffer_unmap (newbuf, &outmap);
2892 audiocontext->wvpk_block_index += block_samples;
2898 /* @text must be null-terminated */
2900 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2905 g_return_val_if_fail (text != NULL, FALSE);
2907 /* yes, this might all lead to false positives ... */
2908 tag = (gchar *) text;
2909 while ((tag = strchr (tag, '<'))) {
2911 if (*tag != '\0' && *(tag + 1) == '>') {
2912 /* some common convenience ones */
2913 /* maybe any character will do here ? */
2926 if (strstr (text, "<span"))
2932 static GstFlowReturn
2933 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2934 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2936 GstMatroskaTrackSubtitleContext *sub_stream;
2937 const gchar *encoding;
2943 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
2945 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
2948 if (!sub_stream->invalid_utf8) {
2949 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
2952 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
2953 " is not valid UTF-8, this is broken according to the matroska"
2954 " specification", stream->num);
2955 sub_stream->invalid_utf8 = TRUE;
2958 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
2959 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
2960 if (encoding == NULL || *encoding == '\0') {
2961 /* if local encoding is UTF-8 and no encoding specified
2962 * via the environment variable, assume ISO-8859-15 */
2963 if (g_get_charset (&encoding)) {
2964 encoding = "ISO-8859-15";
2969 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
2970 (char *) "*", NULL, NULL, &err);
2973 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
2974 encoding, err->message);
2978 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
2979 encoding = "ISO-8859-15";
2981 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
2982 encoding, (char *) "*", NULL, NULL, NULL);
2985 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
2986 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
2989 utf8 = g_strdup ("invalid subtitle");
2991 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
2992 gst_buffer_copy_into (newbuf, *buf,
2993 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
2995 gst_buffer_unmap (*buf, &map);
2996 gst_buffer_unref (*buf);
2999 gst_buffer_map (*buf, &map, GST_MAP_READ);
3002 if (sub_stream->check_markup) {
3003 /* caps claim markup text, so we need to escape text,
3004 * except if text is already markup and then needs no further escaping */
3005 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3006 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3008 if (!sub_stream->seen_markup_tag) {
3009 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3011 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3012 gst_buffer_copy_into (newbuf, *buf,
3013 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3014 GST_BUFFER_COPY_META, 0, -1);
3015 gst_buffer_unmap (*buf, &map);
3016 gst_buffer_unref (*buf);
3025 static GstFlowReturn
3026 gst_matroska_demux_check_aac (GstElement * element,
3027 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3032 gst_buffer_extract (*buf, 0, data, 2);
3033 size = gst_buffer_get_size (*buf);
3035 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3038 /* tss, ADTS data, remove codec_data
3039 * still assume it is at least parsed */
3040 stream->caps = gst_caps_make_writable (stream->caps);
3041 s = gst_caps_get_structure (stream->caps, 0);
3043 gst_structure_remove_field (s, "codec_data");
3044 gst_pad_set_caps (stream->pad, stream->caps);
3045 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3046 "new caps: %" GST_PTR_FORMAT, stream->caps);
3049 /* disable subsequent checking */
3050 stream->postprocess_frame = NULL;
3056 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3057 GstBuffer * buffer, gsize alignment)
3061 gst_buffer_map (buffer, &map, GST_MAP_READ);
3063 if (map.size < sizeof (guintptr)) {
3064 gst_buffer_unmap (buffer, &map);
3068 if (((guintptr) map.data) & (alignment - 1)) {
3069 GstBuffer *new_buffer;
3070 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3072 new_buffer = gst_buffer_new_allocate (NULL,
3073 gst_buffer_get_size (buffer), ¶ms);
3075 /* Copy data "by hand", so ensure alignment is kept: */
3076 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3078 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3079 GST_DEBUG_OBJECT (demux,
3080 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3083 gst_buffer_unmap (buffer, &map);
3084 gst_buffer_unref (buffer);
3089 gst_buffer_unmap (buffer, &map);
3093 static GstFlowReturn
3094 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3095 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3096 gboolean is_simpleblock)
3098 GstMatroskaTrackContext *stream = NULL;
3099 GstFlowReturn ret = GST_FLOW_OK;
3100 gboolean readblock = FALSE;
3102 guint64 block_duration = -1;
3103 GstBuffer *buf = NULL;
3105 gint stream_num = -1, n, laces = 0;
3107 gint *lace_size = NULL;
3110 gint64 referenceblock = 0;
3113 offset = gst_ebml_read_get_offset (ebml);
3115 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3116 if (!is_simpleblock) {
3117 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3121 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3125 /* one block inside the group. Note, block parsing is one
3126 * of the harder things, so this code is a bit complicated.
3127 * See http://www.matroska.org/ for documentation. */
3128 case GST_MATROSKA_ID_SIMPLEBLOCK:
3129 case GST_MATROSKA_ID_BLOCK:
3135 gst_buffer_unmap (buf, &map);
3136 gst_buffer_unref (buf);
3139 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3142 gst_buffer_map (buf, &map, GST_MAP_READ);
3146 /* first byte(s): blocknum */
3147 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3152 /* fetch stream from num */
3153 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3155 if (G_UNLIKELY (size < 3)) {
3156 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3157 /* non-fatal, try next block(group) */
3160 } else if (G_UNLIKELY (stream_num < 0 ||
3161 stream_num >= demux->common.num_streams)) {
3162 /* let's not give up on a stray invalid track number */
3163 GST_WARNING_OBJECT (demux,
3164 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3165 "; ignoring block", stream_num, num);
3169 stream = g_ptr_array_index (demux->common.src, stream_num);
3171 /* time (relative to cluster time) */
3172 time = ((gint16) GST_READ_UINT16_BE (data));
3175 flags = GST_READ_UINT8 (data);
3179 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3182 switch ((flags & 0x06) >> 1) {
3183 case 0x0: /* no lacing */
3185 lace_size = g_new (gint, 1);
3186 lace_size[0] = size;
3189 case 0x1: /* xiph lacing */
3190 case 0x2: /* fixed-size lacing */
3191 case 0x3: /* EBML lacing */
3193 goto invalid_lacing;
3194 laces = GST_READ_UINT8 (data) + 1;
3197 lace_size = g_new0 (gint, laces);
3199 switch ((flags & 0x06) >> 1) {
3200 case 0x1: /* xiph lacing */ {
3201 guint temp, total = 0;
3203 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3206 goto invalid_lacing;
3207 temp = GST_READ_UINT8 (data);
3208 lace_size[n] += temp;
3214 total += lace_size[n];
3216 lace_size[n] = size - total;
3220 case 0x2: /* fixed-size lacing */
3221 for (n = 0; n < laces; n++)
3222 lace_size[n] = size / laces;
3225 case 0x3: /* EBML lacing */ {
3228 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3232 total = lace_size[0] = num;
3233 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3237 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3241 lace_size[n] = lace_size[n - 1] + snum;
3242 total += lace_size[n];
3245 lace_size[n] = size - total;
3252 if (ret != GST_FLOW_OK)
3259 case GST_MATROSKA_ID_BLOCKDURATION:{
3260 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3261 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3266 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3267 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3268 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3273 case GST_MATROSKA_ID_CODECSTATE:{
3275 guint64 data_len = 0;
3278 gst_ebml_read_binary (ebml, &id, &data,
3279 &data_len)) != GST_FLOW_OK)
3282 if (G_UNLIKELY (stream == NULL)) {
3283 GST_WARNING_OBJECT (demux,
3284 "Unexpected CodecState subelement - ignoring");
3288 g_free (stream->codec_state);
3289 stream->codec_state = data;
3290 stream->codec_state_size = data_len;
3292 /* Decode if necessary */
3293 if (stream->encodings && stream->encodings->len > 0
3294 && stream->codec_state && stream->codec_state_size > 0) {
3295 if (!gst_matroska_decode_data (stream->encodings,
3296 &stream->codec_state, &stream->codec_state_size,
3297 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3298 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3302 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3303 stream->codec_state_size);
3308 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3312 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3313 case GST_MATROSKA_ID_BLOCKADDITIONS:
3314 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3315 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3316 case GST_MATROSKA_ID_SLICES:
3317 GST_DEBUG_OBJECT (demux,
3318 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3319 ret = gst_ebml_read_skip (ebml);
3327 /* reading a number or so could have failed */
3328 if (ret != GST_FLOW_OK)
3331 if (ret == GST_FLOW_OK && readblock) {
3332 gboolean invisible_frame = FALSE;
3333 gboolean delta_unit = FALSE;
3334 guint64 duration = 0;
3335 gint64 lace_time = 0;
3337 stream = g_ptr_array_index (demux->common.src, stream_num);
3339 if (cluster_time != GST_CLOCK_TIME_NONE) {
3340 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3341 * Drop unless the lace contains timestamp 0? */
3342 if (time < 0 && (-time) > cluster_time) {
3345 if (stream->timecodescale == 1.0)
3346 lace_time = (cluster_time + time) * demux->common.time_scale;
3349 gst_util_guint64_to_gdouble ((cluster_time + time) *
3350 demux->common.time_scale) * stream->timecodescale;
3353 lace_time = GST_CLOCK_TIME_NONE;
3356 /* need to refresh segment info ASAP */
3357 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3358 GstSegment *segment = &demux->common.segment;
3361 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3362 demux->stream_start_time = lace_time;
3363 GST_DEBUG_OBJECT (demux,
3364 "Setting stream start time to %" GST_TIME_FORMAT,
3365 GST_TIME_ARGS (lace_time));
3367 clace_time = MAX (lace_time, demux->stream_start_time);
3368 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3369 demux->common.segment.position != 0) {
3370 GST_DEBUG_OBJECT (demux,
3371 "using stored seek position %" GST_TIME_FORMAT,
3372 GST_TIME_ARGS (demux->common.segment.position));
3373 clace_time = demux->common.segment.position + demux->stream_start_time;
3374 segment->position = GST_CLOCK_TIME_NONE;
3376 segment->start = clace_time;
3377 segment->stop = GST_CLOCK_TIME_NONE;
3378 segment->time = segment->start - demux->stream_start_time;
3379 segment->position = segment->start - demux->stream_start_time;
3380 GST_DEBUG_OBJECT (demux,
3381 "generated segment starting at %" GST_TIME_FORMAT ": %"
3382 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3383 /* now convey our segment notion downstream */
3384 gst_matroska_demux_send_event (demux, gst_event_new_segment (segment));
3385 demux->need_segment = FALSE;
3388 if (stream->send_stream_headers) {
3389 if (stream->stream_headers != NULL) {
3390 ret = gst_matroska_demux_push_stream_headers (demux, stream);
3392 /* FIXME: perhaps we can just disable and skip this stream then */
3393 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
3394 ("Failed to extract stream headers from codec private data"));
3396 stream->send_stream_headers = FALSE;
3399 if (stream->send_dvd_event) {
3400 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
3401 /* FIXME: should we send this event again after (flushing) seek ? */
3402 stream->send_dvd_event = FALSE;
3405 if (block_duration != -1) {
3406 if (stream->timecodescale == 1.0)
3407 duration = gst_util_uint64_scale (block_duration,
3408 demux->common.time_scale, 1);
3411 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3412 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3413 1)) * stream->timecodescale);
3414 } else if (stream->default_duration) {
3415 duration = stream->default_duration * laces;
3417 /* else duration is diff between timecode of this and next block */
3419 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3420 a ReferenceBlock implies that this is not a keyframe. In either
3421 case, it only makes sense for video streams. */
3422 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3423 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3425 invisible_frame = ((flags & 0x08)) &&
3426 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3427 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3431 if (delta_unit && stream->set_discont) {
3432 /* When doing seeks or such, we need to restart on key frames or
3433 * decoders might choke. */
3434 GST_DEBUG_OBJECT (demux, "skipping delta unit");
3438 for (n = 0; n < laces; n++) {
3441 if (G_UNLIKELY (lace_size[n] > size)) {
3442 GST_WARNING_OBJECT (demux, "Invalid lace size");
3446 /* QoS for video track with an index. the assumption is that
3447 index entries point to keyframes, but if that is not true we
3448 will instad skip until the next keyframe. */
3449 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3450 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3451 stream->index_table && demux->common.segment.rate > 0.0) {
3452 GstMatroskaTrackVideoContext *videocontext =
3453 (GstMatroskaTrackVideoContext *) stream;
3454 GstClockTime earliest_time;
3455 GstClockTime earliest_stream_time;
3457 GST_OBJECT_LOCK (demux);
3458 earliest_time = videocontext->earliest_time;
3459 GST_OBJECT_UNLOCK (demux);
3460 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3461 GST_FORMAT_TIME, earliest_time);
3463 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3464 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3465 lace_time <= earliest_stream_time) {
3466 /* find index entry (keyframe) <= earliest_stream_time */
3467 GstMatroskaIndex *entry =
3468 gst_util_array_binary_search (stream->index_table->data,
3469 stream->index_table->len, sizeof (GstMatroskaIndex),
3470 (GCompareDataFunc) gst_matroska_index_seek_find,
3471 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3473 /* if that entry (keyframe) is after the current the current
3474 buffer, we can skip pushing (and thus decoding) all
3475 buffers until that keyframe. */
3476 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3477 entry->time > lace_time) {
3478 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3479 stream->set_discont = TRUE;
3485 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3486 gst_buffer_get_size (buf) - size, lace_size[n]);
3487 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3490 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3492 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3494 if (invisible_frame)
3495 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3497 if (stream->encodings != NULL && stream->encodings->len > 0)
3498 sub = gst_matroska_decode_buffer (stream, sub);
3501 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3505 GST_BUFFER_TIMESTAMP (sub) = lace_time;
3507 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3508 GstClockTime last_stop_end;
3510 /* Check if this stream is after segment stop */
3511 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3512 lace_time >= demux->common.segment.stop) {
3513 GST_DEBUG_OBJECT (demux,
3514 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3515 GST_TIME_ARGS (demux->common.segment.stop));
3516 gst_buffer_unref (sub);
3519 if (offset >= stream->to_offset
3520 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3521 && lace_time > demux->to_time)) {
3522 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3524 gst_buffer_unref (sub);
3528 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3529 * that landed us with timestamps not quite intended */
3530 GST_OBJECT_LOCK (demux);
3531 if (demux->max_gap_time &&
3532 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3533 demux->common.segment.rate > 0.0) {
3534 GstClockTimeDiff diff;
3536 /* only send segments with increasing start times,
3537 * otherwise if these go back and forth downstream (sinks) increase
3538 * accumulated time and running_time */
3539 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3540 if (diff > 0 && diff > demux->max_gap_time
3541 && lace_time > demux->common.segment.start
3542 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3543 || lace_time < demux->common.segment.stop)) {
3545 GstEvent *event1, *event2;
3546 GST_DEBUG_OBJECT (demux,
3547 "Gap of %" G_GINT64_FORMAT " ns detected in"
3548 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3549 "Sending updated SEGMENT events", diff,
3550 stream->index, GST_TIME_ARGS (stream->pos),
3551 GST_TIME_ARGS (lace_time));
3552 /* send segment events such that the gap is not accounted in
3553 * segment base time, hence running_time */
3554 /* close ahead of gap */
3555 segment = demux->common.segment;
3556 segment.start = demux->last_stop_end;
3557 segment.stop = demux->last_stop_end;
3558 segment.position = demux->last_stop_end;
3559 event1 = gst_event_new_segment (&segment);
3561 segment.start = lace_time;
3562 segment.stop = demux->common.segment.stop;
3563 segment.position = lace_time;
3564 event2 = gst_event_new_segment (&segment);
3565 GST_OBJECT_UNLOCK (demux);
3566 gst_matroska_demux_send_event (demux, event1);
3567 gst_matroska_demux_send_event (demux, event2);
3568 GST_OBJECT_LOCK (demux);
3569 /* align segment view with downstream,
3570 * prevents double-counting base time when closing segment */
3571 /* FIXME: in 0.10, the segment base/accum got updated here, but
3572 * maybe we don't need that because of the double accounting
3573 * mentioned above? */
3574 demux->common.segment = segment;
3578 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3579 || demux->common.segment.position < lace_time) {
3580 demux->common.segment.position = lace_time;
3582 GST_OBJECT_UNLOCK (demux);
3584 last_stop_end = lace_time;
3586 GST_BUFFER_DURATION (sub) = duration / laces;
3587 last_stop_end += GST_BUFFER_DURATION (sub);
3590 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3591 demux->last_stop_end < last_stop_end)
3592 demux->last_stop_end = last_stop_end;
3594 GST_OBJECT_LOCK (demux);
3595 if (demux->common.segment.duration == -1 ||
3596 demux->stream_start_time + demux->common.segment.duration <
3598 demux->common.segment.duration =
3599 last_stop_end - demux->stream_start_time;
3600 GST_OBJECT_UNLOCK (demux);
3601 if (!demux->invalid_duration) {
3602 gst_element_post_message (GST_ELEMENT_CAST (demux),
3603 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3604 demux->invalid_duration = TRUE;
3607 GST_OBJECT_UNLOCK (demux);
3611 stream->pos = lace_time;
3613 gst_matroska_demux_sync_streams (demux);
3615 if (stream->set_discont) {
3616 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3617 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3618 stream->set_discont = FALSE;
3621 /* reverse playback book-keeping */
3622 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3623 stream->from_time = lace_time;
3624 if (stream->from_offset == -1)
3625 stream->from_offset = offset;
3627 GST_DEBUG_OBJECT (demux,
3628 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3629 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3630 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3631 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
3632 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3635 if (demux->common.element_index) {
3636 if (stream->index_writer_id == -1)
3637 gst_index_get_writer_id (demux->common.element_index,
3638 GST_OBJECT (stream->pad), &stream->index_writer_id);
3640 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3641 G_GUINT64_FORMAT " for writer id %d",
3642 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
3643 stream->index_writer_id);
3644 gst_index_add_association (demux->common.element_index,
3645 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3646 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3647 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
3648 cluster_offset, NULL);
3652 /* Postprocess the buffers depending on the codec used */
3653 if (stream->postprocess_frame) {
3654 GST_LOG_OBJECT (demux, "running post process");
3655 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3658 /* At this point, we have a sub-buffer pointing at data within a larger
3659 buffer. This data might not be aligned with anything. If the data is
3660 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3661 for 32 bit samples, etc), or bad things will happen downstream as
3662 elements typically assume minimal alignment.
3663 Therefore, create an aligned copy if necessary. */
3664 g_assert (stream->alignment <= G_MEM_ALIGN);
3665 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3667 ret = gst_pad_push (stream->pad, sub);
3669 if (demux->common.segment.rate < 0) {
3670 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3671 /* In reverse playback we can get a GST_FLOW_EOS when
3672 * we are at the end of the segment, so we just need to jump
3673 * back to the previous section. */
3674 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3679 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3682 size -= lace_size[n];
3683 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3684 lace_time += duration / laces;
3686 lace_time = GST_CLOCK_TIME_NONE;
3692 gst_buffer_unmap (buf, &map);
3693 gst_buffer_unref (buf);
3705 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3710 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3711 /* non-fatal, try next block(group) */
3717 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3718 /* non-fatal, try next block(group) */
3724 /* return FALSE if block(group) should be skipped (due to a seek) */
3725 static inline gboolean
3726 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3728 if (G_UNLIKELY (demux->seek_block)) {
3729 if (!(--demux->seek_block)) {
3732 GST_LOG_OBJECT (demux, "should skip block due to seek");
3740 static GstFlowReturn
3741 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3745 guint64 seek_pos = (guint64) - 1;
3746 guint32 seek_id = 0;
3749 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3751 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3752 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3756 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3757 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3761 case GST_MATROSKA_ID_SEEKID:
3765 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3768 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3773 case GST_MATROSKA_ID_SEEKPOSITION:
3777 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3780 if (t > G_MAXINT64) {
3781 GST_WARNING_OBJECT (demux,
3782 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3786 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3792 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3798 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3801 if (!seek_id || seek_pos == (guint64) - 1) {
3802 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3803 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3808 case GST_MATROSKA_ID_SEEKHEAD:
3811 case GST_MATROSKA_ID_CUES:
3812 case GST_MATROSKA_ID_TAGS:
3813 case GST_MATROSKA_ID_TRACKS:
3814 case GST_MATROSKA_ID_SEGMENTINFO:
3815 case GST_MATROSKA_ID_ATTACHMENTS:
3816 case GST_MATROSKA_ID_CHAPTERS:
3818 guint64 before_pos, length;
3822 length = gst_matroska_read_common_get_length (&demux->common);
3823 before_pos = demux->common.offset;
3825 if (length == (guint64) - 1) {
3826 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3830 /* check for validity */
3831 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3832 GST_WARNING_OBJECT (demux,
3833 "SeekHead reference lies outside file!" " (%"
3834 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3835 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3840 /* only pick up index location when streaming */
3841 if (demux->streaming) {
3842 if (seek_id == GST_MATROSKA_ID_CUES) {
3843 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3844 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3845 demux->index_offset);
3851 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3854 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3855 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3859 if (id != seek_id) {
3860 GST_WARNING_OBJECT (demux,
3861 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3862 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3865 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3870 demux->common.offset = before_pos;
3874 case GST_MATROSKA_ID_CLUSTER:
3876 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3878 GST_LOG_OBJECT (demux, "Cluster position");
3879 if (G_UNLIKELY (!demux->clusters))
3880 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3881 g_array_append_val (demux->clusters, pos);
3886 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3889 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3894 static GstFlowReturn
3895 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3897 GstFlowReturn ret = GST_FLOW_OK;
3900 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3902 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3903 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3907 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3908 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3912 case GST_MATROSKA_ID_SEEKENTRY:
3914 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3915 /* Ignore EOS and errors here */
3916 if (ret != GST_FLOW_OK) {
3917 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3924 ret = gst_matroska_read_common_parse_skip (&demux->common,
3925 ebml, "SeekHead", id);
3930 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3932 /* Sort clusters by position for easier searching */
3933 if (demux->clusters)
3934 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3939 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3941 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3943 static inline GstFlowReturn
3944 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
3946 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
3947 /* only a few blocks are expected/allowed to be large,
3948 * and will be recursed into, whereas others will be read and must fit */
3949 if (demux->streaming) {
3950 /* fatal in streaming case, as we can't step over easily */
3951 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3952 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
3953 "file might be corrupt.", bytes));
3954 return GST_FLOW_ERROR;
3956 /* indicate higher level to quietly give up */
3957 GST_DEBUG_OBJECT (demux,
3958 "too large block of size %" G_GUINT64_FORMAT, bytes);
3959 return GST_FLOW_ERROR;
3966 /* returns TRUE if we truely are in error state, and should give up */
3967 static inline gboolean
3968 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
3970 if (!demux->streaming && demux->next_cluster_offset > 0) {
3971 /* just repositioning to where next cluster should be and try from there */
3972 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
3973 G_GUINT64_FORMAT, demux->next_cluster_offset);
3974 demux->common.offset = demux->next_cluster_offset;
3975 demux->next_cluster_offset = 0;
3980 /* sigh, one last attempt above and beyond call of duty ...;
3981 * search for cluster mark following current pos */
3982 pos = demux->common.offset;
3983 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
3984 if (gst_matroska_demux_search_cluster (demux, &pos) != GST_FLOW_OK) {
3985 /* did not work, give up */
3988 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
3989 /* try that position */
3990 demux->common.offset = pos;
3996 static inline GstFlowReturn
3997 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
3999 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4000 demux->common.offset += flush;
4001 if (demux->streaming) {
4004 /* hard to skip large blocks when streaming */
4005 ret = gst_matroska_demux_check_read_size (demux, flush);
4006 if (ret != GST_FLOW_OK)
4008 if (flush <= gst_adapter_available (demux->common.adapter))
4009 gst_adapter_flush (demux->common.adapter, flush);
4011 return GST_FLOW_EOS;
4016 /* initializes @ebml with @bytes from input stream at current offset.
4017 * Returns EOS if insufficient available,
4018 * ERROR if too much was attempted to read. */
4019 static inline GstFlowReturn
4020 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4023 GstBuffer *buffer = NULL;
4024 GstFlowReturn ret = GST_FLOW_OK;
4026 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4028 ret = gst_matroska_demux_check_read_size (demux, bytes);
4029 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4030 if (!demux->streaming) {
4031 /* in pull mode, we can skip */
4032 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4033 ret = GST_FLOW_OVERFLOW;
4035 /* otherwise fatal */
4036 ret = GST_FLOW_ERROR;
4040 if (demux->streaming) {
4041 if (gst_adapter_available (demux->common.adapter) >= bytes)
4042 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4046 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4047 demux->common.offset, bytes, &buffer, NULL);
4048 if (G_LIKELY (buffer)) {
4049 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4050 demux->common.offset);
4051 demux->common.offset += bytes;
4058 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4061 gboolean seekable = FALSE;
4062 gint64 start = -1, stop = -1;
4064 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4065 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4066 GST_DEBUG_OBJECT (demux, "seeking query failed");
4070 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4072 /* try harder to query upstream size if we didn't get it the first time */
4073 if (seekable && stop == -1) {
4074 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4075 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4079 /* if upstream doesn't know the size, it's likely that it's not seekable in
4080 * practice even if it technically may be seekable */
4081 if (seekable && (start != 0 || stop <= start)) {
4082 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4087 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4088 G_GUINT64_FORMAT ")", seekable, start, stop);
4089 demux->seekable = seekable;
4091 gst_query_unref (query);
4094 static GstFlowReturn
4095 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4101 GstFlowReturn ret = GST_FLOW_OK;
4103 GST_WARNING_OBJECT (demux,
4104 "Found Cluster element before Tracks, searching Tracks");
4107 before_pos = demux->common.offset;
4109 /* Search Tracks element */
4111 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4112 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4113 if (ret != GST_FLOW_OK)
4116 if (id != GST_MATROSKA_ID_TRACKS) {
4117 /* we may be skipping large cluster here, so forego size check etc */
4118 /* ... but we can't skip undefined size; force error */
4119 if (length == G_MAXUINT64) {
4120 ret = gst_matroska_demux_check_read_size (demux, length);
4123 demux->common.offset += needed;
4124 demux->common.offset += length;
4129 /* will lead to track parsing ... */
4130 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4135 demux->common.offset = before_pos;
4140 #define GST_READ_CHECK(stmt) \
4142 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4143 if (ret == GST_FLOW_OVERFLOW) { \
4144 ret = GST_FLOW_OK; \
4150 static GstFlowReturn
4151 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4152 guint64 length, guint needed)
4154 GstEbmlRead ebml = { 0, };
4155 GstFlowReturn ret = GST_FLOW_OK;
4158 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4159 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4161 /* if we plan to read and parse this element, we need prefix (id + length)
4162 * and the contents */
4163 /* mind about overflow wrap-around when dealing with undefined size */
4165 if (G_LIKELY (length != G_MAXUINT64))
4168 switch (demux->common.state) {
4169 case GST_MATROSKA_READ_STATE_START:
4171 case GST_EBML_ID_HEADER:
4172 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4173 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4174 if (ret != GST_FLOW_OK)
4176 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4177 gst_matroska_demux_check_seekability (demux);
4180 goto invalid_header;
4184 case GST_MATROSKA_READ_STATE_SEGMENT:
4186 case GST_MATROSKA_ID_SEGMENT:
4187 /* eat segment prefix */
4188 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4189 GST_DEBUG_OBJECT (demux,
4190 "Found Segment start at offset %" G_GUINT64_FORMAT,
4191 demux->common.offset);
4192 /* seeks are from the beginning of the segment,
4193 * after the segment ID/length */
4194 demux->common.ebml_segment_start = demux->common.offset;
4195 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4198 GST_WARNING_OBJECT (demux,
4199 "Expected a Segment ID (0x%x), but received 0x%x!",
4200 GST_MATROSKA_ID_SEGMENT, id);
4201 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4205 case GST_MATROSKA_READ_STATE_SCANNING:
4206 if (id != GST_MATROSKA_ID_CLUSTER &&
4207 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4210 case GST_MATROSKA_READ_STATE_HEADER:
4211 case GST_MATROSKA_READ_STATE_DATA:
4212 case GST_MATROSKA_READ_STATE_SEEK:
4214 case GST_MATROSKA_ID_SEGMENTINFO:
4215 if (!demux->common.segmentinfo_parsed) {
4216 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4217 ret = gst_matroska_read_common_parse_info (&demux->common,
4218 GST_ELEMENT_CAST (demux), &ebml);
4220 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4223 case GST_MATROSKA_ID_TRACKS:
4224 if (!demux->tracks_parsed) {
4225 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4226 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4228 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4231 case GST_MATROSKA_ID_CLUSTER:
4232 if (G_UNLIKELY (!demux->tracks_parsed)) {
4233 if (demux->streaming) {
4234 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4235 goto not_streamable;
4237 ret = gst_matroska_demux_find_tracks (demux);
4238 if (!demux->tracks_parsed)
4242 if (G_UNLIKELY (demux->common.state
4243 == GST_MATROSKA_READ_STATE_HEADER)) {
4244 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4245 demux->first_cluster_offset = demux->common.offset;
4246 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4247 gst_element_no_more_pads (GST_ELEMENT (demux));
4248 /* send initial segment - we wait till we know the first
4249 incoming timestamp, so we can properly set the start of
4251 demux->need_segment = TRUE;
4253 demux->cluster_time = GST_CLOCK_TIME_NONE;
4254 demux->cluster_offset = demux->common.offset;
4255 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4256 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4257 " not found in Cluster, trying next Cluster's first block instead",
4259 demux->seek_block = 0;
4261 demux->seek_first = FALSE;
4262 /* record next cluster for recovery */
4263 if (read != G_MAXUINT64)
4264 demux->next_cluster_offset = demux->cluster_offset + read;
4265 /* eat cluster prefix */
4266 gst_matroska_demux_flush (demux, needed);
4268 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4272 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4273 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4275 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4276 demux->cluster_time = num;
4278 if (demux->common.element_index) {
4279 if (demux->common.element_index_writer_id == -1)
4280 gst_index_get_writer_id (demux->common.element_index,
4281 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4282 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4283 G_GUINT64_FORMAT " for writer id %d",
4284 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4285 demux->common.element_index_writer_id);
4286 gst_index_add_association (demux->common.element_index,
4287 demux->common.element_index_writer_id,
4288 GST_ASSOCIATION_FLAG_KEY_UNIT,
4289 GST_FORMAT_TIME, demux->cluster_time,
4290 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4295 case GST_MATROSKA_ID_BLOCKGROUP:
4296 if (!gst_matroska_demux_seek_block (demux))
4298 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4299 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4300 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4301 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4302 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4304 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4306 case GST_MATROSKA_ID_SIMPLEBLOCK:
4307 if (!gst_matroska_demux_seek_block (demux))
4309 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4310 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4311 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4312 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4313 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4315 case GST_MATROSKA_ID_ATTACHMENTS:
4316 if (!demux->common.attachments_parsed) {
4317 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4318 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4319 GST_ELEMENT_CAST (demux), &ebml);
4321 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4324 case GST_MATROSKA_ID_TAGS:
4325 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4326 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4327 GST_ELEMENT_CAST (demux), &ebml);
4329 case GST_MATROSKA_ID_CHAPTERS:
4330 if (!demux->common.chapters_parsed) {
4331 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4333 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4335 if (demux->common.toc) {
4336 gst_matroska_demux_send_event (demux,
4337 gst_event_new_toc (demux->common.toc, FALSE));
4340 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4342 case GST_MATROSKA_ID_SEEKHEAD:
4343 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4344 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4346 case GST_MATROSKA_ID_CUES:
4347 if (demux->common.index_parsed) {
4348 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4351 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4352 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4353 /* only push based; delayed index building */
4354 if (ret == GST_FLOW_OK
4355 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4358 GST_OBJECT_LOCK (demux);
4359 event = demux->seek_event;
4360 demux->seek_event = NULL;
4361 GST_OBJECT_UNLOCK (demux);
4364 /* unlikely to fail, since we managed to seek to this point */
4365 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4367 /* resume data handling, main thread clear to seek again */
4368 GST_OBJECT_LOCK (demux);
4369 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4370 GST_OBJECT_UNLOCK (demux);
4373 case GST_MATROSKA_ID_POSITION:
4374 case GST_MATROSKA_ID_PREVSIZE:
4375 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4376 case GST_MATROSKA_ID_SILENTTRACKS:
4377 GST_DEBUG_OBJECT (demux,
4378 "Skipping Cluster subelement 0x%x - ignoring", id);
4382 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4383 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4389 if (ret == GST_FLOW_PARSE)
4393 gst_ebml_read_clear (&ebml);
4399 /* simply exit, maybe not enough data yet */
4400 /* no ebml to clear if read error */
4405 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4406 ("Failed to parse Element 0x%x", id));
4407 ret = GST_FLOW_ERROR;
4412 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4413 ("File layout does not permit streaming"));
4414 ret = GST_FLOW_ERROR;
4419 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4420 ("No Tracks element found"));
4421 ret = GST_FLOW_ERROR;
4426 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4427 ret = GST_FLOW_ERROR;
4432 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4433 ret = GST_FLOW_ERROR;
4439 gst_matroska_demux_loop (GstPad * pad)
4441 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4447 /* If we have to close a segment, send a new segment to do this now */
4448 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4449 if (G_UNLIKELY (demux->new_segment)) {
4450 gst_matroska_demux_send_event (demux, demux->new_segment);
4451 demux->new_segment = NULL;
4455 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4456 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4457 if (ret == GST_FLOW_EOS)
4459 if (ret != GST_FLOW_OK) {
4460 if (gst_matroska_demux_check_parse_error (demux))
4466 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4467 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4470 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4471 if (ret == GST_FLOW_EOS)
4473 if (ret != GST_FLOW_OK)
4476 /* check if we're at the end of a configured segment */
4477 if (G_LIKELY (demux->common.src->len)) {
4480 g_assert (demux->common.num_streams == demux->common.src->len);
4481 for (i = 0; i < demux->common.src->len; i++) {
4482 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4484 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4485 GST_TIME_ARGS (context->pos));
4486 if (context->eos == FALSE)
4490 GST_INFO_OBJECT (demux, "All streams are EOS");
4496 if (G_UNLIKELY (demux->common.offset ==
4497 gst_matroska_read_common_get_length (&demux->common))) {
4498 GST_LOG_OBJECT (demux, "Reached end of stream");
4508 if (demux->common.segment.rate < 0.0) {
4509 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4510 if (ret == GST_FLOW_OK)
4517 const gchar *reason = gst_flow_get_name (ret);
4518 gboolean push_eos = FALSE;
4520 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4521 gst_pad_pause_task (demux->common.sinkpad);
4523 if (ret == GST_FLOW_EOS) {
4524 /* perform EOS logic */
4526 /* If we were in the headers, make sure we send no-more-pads.
4527 This will ensure decodebin2 does not get stuck thinking
4528 the chain is not complete yet, and waiting indefinitely. */
4529 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4530 if (demux->common.src->len == 0) {
4531 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4532 ("No pads created"));
4534 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4535 ("Failed to finish reading headers"));
4537 gst_element_no_more_pads (GST_ELEMENT (demux));
4540 /* Close the segment, i.e. update segment stop with the duration
4541 * if no stop was set */
4542 if (GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
4543 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
4544 GST_CLOCK_TIME_IS_VALID (demux->common.segment.start) &&
4545 demux->last_stop_end > demux->common.segment.start) {
4546 GstSegment segment = demux->common.segment;
4549 segment.stop = demux->last_stop_end;
4550 event = gst_event_new_segment (&segment);
4551 gst_matroska_demux_send_event (demux, event);
4554 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4557 /* for segment playback we need to post when (in stream time)
4558 * we stopped, this is either stop (when set) or the duration. */
4559 if ((stop = demux->common.segment.stop) == -1)
4560 stop = demux->last_stop_end;
4562 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4563 gst_element_post_message (GST_ELEMENT (demux),
4564 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4566 gst_matroska_demux_send_event (demux,
4567 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4571 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4572 /* for fatal errors we post an error message */
4573 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4574 ("stream stopped, reason %s", reason));
4578 /* send EOS, and prevent hanging if no streams yet */
4579 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4580 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4581 (ret == GST_FLOW_EOS)) {
4582 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4583 (NULL), ("got eos but no streams (yet)"));
4591 * Create and push a flushing seek event upstream
4594 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset)
4599 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4602 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4603 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4604 GST_SEEK_TYPE_NONE, -1);
4606 res = gst_pad_push_event (demux->common.sinkpad, event);
4608 /* segment event will update offset */
4612 static GstFlowReturn
4613 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4615 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4617 GstFlowReturn ret = GST_FLOW_OK;
4622 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4623 GST_DEBUG_OBJECT (demux, "got DISCONT");
4624 gst_adapter_clear (demux->common.adapter);
4625 GST_OBJECT_LOCK (demux);
4626 gst_matroska_read_common_reset_streams (&demux->common,
4627 GST_CLOCK_TIME_NONE, FALSE);
4628 GST_OBJECT_UNLOCK (demux);
4631 gst_adapter_push (demux->common.adapter, buffer);
4635 available = gst_adapter_available (demux->common.adapter);
4637 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4638 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4639 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS))
4642 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4643 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4644 demux->common.offset, id, length, needed, available);
4646 if (needed > available)
4649 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4650 if (ret == GST_FLOW_EOS) {
4651 /* need more data */
4653 } else if (ret != GST_FLOW_OK) {
4660 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4663 gboolean res = TRUE;
4664 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4666 GST_DEBUG_OBJECT (demux,
4667 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4669 switch (GST_EVENT_TYPE (event)) {
4670 case GST_EVENT_SEGMENT:
4672 const GstSegment *segment;
4674 /* some debug output */
4675 gst_event_parse_segment (event, &segment);
4676 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4677 GST_DEBUG_OBJECT (demux,
4678 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4681 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4682 GST_DEBUG_OBJECT (demux, "still starting");
4686 /* we only expect a BYTE segment, e.g. following a seek */
4687 if (segment->format != GST_FORMAT_BYTES) {
4688 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4692 GST_DEBUG_OBJECT (demux, "clearing segment state");
4693 GST_OBJECT_LOCK (demux);
4694 /* clear current segment leftover */
4695 gst_adapter_clear (demux->common.adapter);
4696 /* and some streaming setup */
4697 demux->common.offset = segment->start;
4698 /* accumulate base based on current position */
4699 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4700 demux->common.segment.base +=
4701 (MAX (demux->common.segment.position, demux->stream_start_time)
4702 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4703 /* do not know where we are;
4704 * need to come across a cluster and generate segment */
4705 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4706 demux->cluster_time = GST_CLOCK_TIME_NONE;
4707 demux->cluster_offset = 0;
4708 demux->need_segment = TRUE;
4709 /* but keep some of the upstream segment */
4710 demux->common.segment.rate = segment->rate;
4711 /* also check if need to keep some of the requested seek position */
4712 if (demux->seek_offset == segment->start) {
4713 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4714 demux->common.segment.position = demux->requested_seek_time;
4716 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4718 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4719 demux->seek_offset = -1;
4720 GST_OBJECT_UNLOCK (demux);
4722 /* chain will send initial segment after pads have been added,
4723 * or otherwise come up with one */
4724 GST_DEBUG_OBJECT (demux, "eating event");
4725 gst_event_unref (event);
4731 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4732 gst_event_unref (event);
4733 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4734 (NULL), ("got eos and didn't receive a complete header object"));
4735 } else if (demux->common.num_streams == 0) {
4736 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4737 (NULL), ("got eos but no streams (yet)"));
4739 gst_matroska_demux_send_event (demux, event);
4743 case GST_EVENT_FLUSH_STOP:
4747 gst_adapter_clear (demux->common.adapter);
4748 GST_OBJECT_LOCK (demux);
4749 gst_matroska_read_common_reset_streams (&demux->common,
4750 GST_CLOCK_TIME_NONE, TRUE);
4751 dur = demux->common.segment.duration;
4752 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4753 demux->common.segment.duration = dur;
4754 demux->cluster_time = GST_CLOCK_TIME_NONE;
4755 demux->cluster_offset = 0;
4756 GST_OBJECT_UNLOCK (demux);
4760 res = gst_pad_event_default (pad, parent, event);
4768 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4770 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4772 gboolean pull_mode = FALSE;
4774 query = gst_query_new_scheduling ();
4776 if (gst_pad_peer_query (sinkpad, query))
4777 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4778 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4780 gst_query_unref (query);
4783 GST_DEBUG ("going to pull mode");
4784 demux->streaming = FALSE;
4785 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4787 GST_DEBUG ("going to push (streaming) mode");
4788 demux->streaming = TRUE;
4789 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4794 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4795 GstPadMode mode, gboolean active)
4798 case GST_PAD_MODE_PULL:
4800 /* if we have a scheduler we can start the task */
4801 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4804 gst_pad_stop_task (sinkpad);
4807 case GST_PAD_MODE_PUSH:
4815 gst_duration_to_fraction (guint64 duration, gint * dest_n, gint * dest_d)
4817 static const int common_den[] = { 1, 2, 3, 4, 1001 };
4822 for (i = 0; i < G_N_ELEMENTS (common_den); i++) {
4824 n = floor (0.5 + (d * 1e9) / duration);
4825 a = gst_util_uint64_scale_int (1000000000, d, n);
4826 if (duration >= a - 1 && duration <= a + 1) {
4831 gst_util_double_to_fraction (1e9 / duration, &n, &d);
4840 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4841 videocontext, const gchar * codec_id, guint8 * data, guint size,
4842 gchar ** codec_name, guint32 * riff_fourcc)
4844 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4845 GstCaps *caps = NULL;
4847 g_assert (videocontext != NULL);
4848 g_assert (codec_name != NULL);
4853 /* TODO: check if we have all codec types from matroska-ids.h
4854 * check if we have to do more special things with codec_private
4857 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4858 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4861 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4862 gst_riff_strf_vids *vids = NULL;
4865 GstBuffer *buf = NULL;
4867 vids = (gst_riff_strf_vids *) data;
4869 /* assure size is big enough */
4871 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4874 if (size < sizeof (gst_riff_strf_vids)) {
4875 vids = g_new (gst_riff_strf_vids, 1);
4876 memcpy (vids, data, size);
4879 /* little-endian -> byte-order */
4880 vids->size = GUINT32_FROM_LE (vids->size);
4881 vids->width = GUINT32_FROM_LE (vids->width);
4882 vids->height = GUINT32_FROM_LE (vids->height);
4883 vids->planes = GUINT16_FROM_LE (vids->planes);
4884 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4885 vids->compression = GUINT32_FROM_LE (vids->compression);
4886 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4887 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4888 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4889 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4890 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4892 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4893 gsize offset = sizeof (gst_riff_strf_vids);
4896 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
4897 size - offset), size - offset);
4901 *riff_fourcc = vids->compression;
4903 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4904 buf, NULL, codec_name);
4907 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4908 GST_FOURCC_ARGS (vids->compression));
4912 gst_buffer_unref (buf);
4914 if (vids != (gst_riff_strf_vids *) data)
4917 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4918 const gchar *format = NULL;
4920 switch (videocontext->fourcc) {
4921 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4922 *codec_name = g_strdup ("Raw planar YUV 4:2:0");
4925 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4926 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
4929 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4930 *codec_name = g_strdup ("Raw packed YUV 4:2:0");
4933 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4934 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
4937 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4938 *codec_name = g_strdup ("Raw packed YUV 4:4:4 with alpha channel");
4943 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
4944 GST_FOURCC_ARGS (videocontext->fourcc));
4948 caps = gst_caps_new_simple ("video/x-raw",
4949 "format", G_TYPE_STRING, format, NULL);
4950 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
4951 caps = gst_caps_new_simple ("video/x-divx",
4952 "divxversion", G_TYPE_INT, 4, NULL);
4953 *codec_name = g_strdup ("MPEG-4 simple profile");
4954 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
4955 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
4956 caps = gst_caps_new_simple ("video/mpeg",
4957 "mpegversion", G_TYPE_INT, 4,
4958 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
4962 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
4963 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
4964 gst_buffer_unref (priv);
4966 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
4967 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
4969 *codec_name = g_strdup ("MPEG-4 advanced profile");
4970 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
4972 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
4973 "divxversion", G_TYPE_INT, 3, NULL),
4974 gst_structure_new ("video/x-msmpeg",
4975 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
4977 caps = gst_caps_new_simple ("video/x-msmpeg",
4978 "msmpegversion", G_TYPE_INT, 43, NULL);
4979 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
4980 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
4981 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
4984 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
4989 caps = gst_caps_new_simple ("video/mpeg",
4990 "systemstream", G_TYPE_BOOLEAN, FALSE,
4991 "mpegversion", G_TYPE_INT, mpegversion, NULL);
4992 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
4993 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
4994 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
4995 caps = gst_caps_new_empty_simple ("image/jpeg");
4996 *codec_name = g_strdup ("Motion-JPEG");
4997 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
4998 caps = gst_caps_new_empty_simple ("video/x-h264");
5002 /* First byte is the version, second is the profile indication, and third
5003 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5004 * level indication. */
5005 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5008 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5009 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5010 gst_buffer_unref (priv);
5012 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5013 "alignment", G_TYPE_STRING, "au", NULL);
5015 GST_WARNING ("No codec data found, assuming output is byte-stream");
5016 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5019 *codec_name = g_strdup ("H264");
5020 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5021 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5022 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5023 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5024 gint rmversion = -1;
5026 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5028 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5030 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5032 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5035 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5036 "rmversion", G_TYPE_INT, rmversion, NULL);
5037 GST_DEBUG ("data:%p, size:0x%x", data, size);
5038 /* We need to extract the extradata ! */
5039 if (data && (size >= 0x22)) {
5044 subformat = GST_READ_UINT32_BE (data + 0x1a);
5045 rformat = GST_READ_UINT32_BE (data + 0x1e);
5048 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5050 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5051 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5052 gst_buffer_unref (priv);
5055 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5056 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5057 caps = gst_caps_new_empty_simple ("video/x-theora");
5058 context->stream_headers =
5059 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5060 context->codec_priv_size);
5061 /* FIXME: mark stream as broken and skip if there are no stream headers */
5062 context->send_stream_headers = TRUE;
5063 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5064 caps = gst_caps_new_empty_simple ("video/x-dirac");
5065 *codec_name = g_strdup_printf ("Dirac");
5066 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5067 caps = gst_caps_new_empty_simple ("video/x-vp8");
5068 *codec_name = g_strdup_printf ("On2 VP8");
5069 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5070 caps = gst_caps_new_empty_simple ("video/x-vp9");
5071 *codec_name = g_strdup_printf ("On2 VP9");
5073 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5079 GstStructure *structure;
5081 for (i = 0; i < gst_caps_get_size (caps); i++) {
5082 structure = gst_caps_get_structure (caps, i);
5084 /* FIXME: use the real unit here! */
5085 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5086 videocontext->pixel_width,
5087 videocontext->pixel_height,
5088 videocontext->display_width, videocontext->display_height);
5090 /* pixel width and height are the w and h of the video in pixels */
5091 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5092 gint w = videocontext->pixel_width;
5093 gint h = videocontext->pixel_height;
5095 gst_structure_set (structure,
5096 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5099 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5102 if (videocontext->display_width <= 0)
5103 videocontext->display_width = videocontext->pixel_width;
5104 if (videocontext->display_height <= 0)
5105 videocontext->display_height = videocontext->pixel_height;
5107 /* calculate the pixel aspect ratio using the display and pixel w/h */
5108 n = videocontext->display_width * videocontext->pixel_height;
5109 d = videocontext->display_height * videocontext->pixel_width;
5110 GST_DEBUG ("setting PAR to %d/%d", n, d);
5111 gst_structure_set (structure, "pixel-aspect-ratio",
5113 videocontext->display_width * videocontext->pixel_height,
5114 videocontext->display_height * videocontext->pixel_width, NULL);
5117 if (videocontext->default_fps > 0.0) {
5118 GValue fps_double = { 0, };
5119 GValue fps_fraction = { 0, };
5121 g_value_init (&fps_double, G_TYPE_DOUBLE);
5122 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
5123 g_value_set_double (&fps_double, videocontext->default_fps);
5124 g_value_transform (&fps_double, &fps_fraction);
5126 GST_DEBUG ("using default fps %f", videocontext->default_fps);
5128 gst_structure_set_value (structure, "framerate", &fps_fraction);
5129 g_value_unset (&fps_double);
5130 g_value_unset (&fps_fraction);
5131 } else if (context->default_duration > 0) {
5134 gst_duration_to_fraction (context->default_duration, &fps_n, &fps_d);
5136 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5137 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5139 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5140 fps_n, fps_d, NULL);
5142 /* sort of a hack to get most codecs to support,
5143 * even if the default_duration is missing */
5144 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5148 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5149 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5153 caps = gst_caps_simplify (caps);
5160 * Some AAC specific code... *sigh*
5161 * FIXME: maybe we should use '15' and code the sample rate explicitly
5162 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5166 aac_rate_idx (gint rate)
5170 else if (75132 <= rate)
5172 else if (55426 <= rate)
5174 else if (46009 <= rate)
5176 else if (37566 <= rate)
5178 else if (27713 <= rate)
5180 else if (23004 <= rate)
5182 else if (18783 <= rate)
5184 else if (13856 <= rate)
5186 else if (11502 <= rate)
5188 else if (9391 <= rate)
5195 aac_profile_idx (const gchar * codec_id)
5199 if (strlen (codec_id) <= 12)
5201 else if (!strncmp (&codec_id[12], "MAIN", 4))
5203 else if (!strncmp (&codec_id[12], "LC", 2))
5205 else if (!strncmp (&codec_id[12], "SSR", 3))
5213 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5216 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5217 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5218 gchar ** codec_name, guint16 * riff_audio_fmt)
5220 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5221 GstCaps *caps = NULL;
5223 g_assert (audiocontext != NULL);
5224 g_assert (codec_name != NULL);
5227 *riff_audio_fmt = 0;
5229 /* TODO: check if we have all codec types from matroska-ids.h
5230 * check if we have to do more special things with codec_private
5231 * check if we need bitdepth in different places too
5232 * implement channel position magic
5234 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5235 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5236 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5237 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5240 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5241 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5242 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5245 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5247 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5252 caps = gst_caps_new_simple ("audio/mpeg",
5253 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5254 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5255 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5256 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5259 GstAudioFormat format;
5261 sign = (audiocontext->bitdepth != 8);
5262 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5263 endianness = G_BIG_ENDIAN;
5265 endianness = G_LITTLE_ENDIAN;
5267 format = gst_audio_format_build_integer (sign, endianness,
5268 audiocontext->bitdepth, audiocontext->bitdepth);
5270 /* FIXME: Channel mask and reordering */
5271 caps = gst_caps_new_simple ("audio/x-raw",
5272 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5273 "layout", G_TYPE_STRING, "interleaved", NULL);
5275 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5276 audiocontext->bitdepth);
5277 context->alignment = audiocontext->bitdepth / 8;
5278 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5279 const gchar *format;
5280 if (audiocontext->bitdepth == 32)
5284 /* FIXME: Channel mask and reordering */
5285 caps = gst_caps_new_simple ("audio/x-raw",
5286 "format", G_TYPE_STRING, format,
5287 "layout", G_TYPE_STRING, "interleaved", NULL);
5288 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5289 audiocontext->bitdepth);
5290 context->alignment = audiocontext->bitdepth / 8;
5291 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5292 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5293 caps = gst_caps_new_simple ("audio/x-ac3",
5294 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5295 *codec_name = g_strdup ("AC-3 audio");
5296 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5297 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5298 caps = gst_caps_new_simple ("audio/x-eac3",
5299 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5300 *codec_name = g_strdup ("E-AC-3 audio");
5301 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5302 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5303 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5304 *codec_name = g_strdup ("Dolby TrueHD");
5305 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5306 caps = gst_caps_new_empty_simple ("audio/x-dts");
5307 *codec_name = g_strdup ("DTS audio");
5308 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5309 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5310 context->stream_headers =
5311 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5312 context->codec_priv_size);
5313 /* FIXME: mark stream as broken and skip if there are no stream headers */
5314 context->send_stream_headers = TRUE;
5315 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5316 caps = gst_caps_new_empty_simple ("audio/x-flac");
5317 context->stream_headers =
5318 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5319 context->codec_priv_size);
5320 /* FIXME: mark stream as broken and skip if there are no stream headers */
5321 context->send_stream_headers = TRUE;
5322 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5323 caps = gst_caps_new_empty_simple ("audio/x-speex");
5324 context->stream_headers =
5325 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5326 context->codec_priv_size);
5327 /* FIXME: mark stream as broken and skip if there are no stream headers */
5328 context->send_stream_headers = TRUE;
5329 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5330 gst_riff_strf_auds auds;
5333 GstBuffer *codec_data;
5335 /* little-endian -> byte-order */
5336 auds.format = GST_READ_UINT16_LE (data);
5337 auds.channels = GST_READ_UINT16_LE (data + 2);
5338 auds.rate = GST_READ_UINT32_LE (data + 4);
5339 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5340 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5341 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5343 /* 18 is the waveformatex size */
5344 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5345 data + 18, auds.bits_per_sample, 0, auds.bits_per_sample, NULL, NULL);
5348 *riff_audio_fmt = auds.format;
5350 /* FIXME: Handle reorder map */
5351 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5352 codec_data, codec_name, NULL);
5353 gst_buffer_unref (codec_data);
5356 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5359 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5360 GstBuffer *priv = NULL;
5362 gint rate_idx, profile;
5363 guint8 *data = NULL;
5365 /* unspecified AAC profile with opaque private codec data */
5366 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5367 if (context->codec_priv_size >= 2) {
5368 guint obj_type, freq_index, explicit_freq_bytes = 0;
5370 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5372 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5373 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5374 if (freq_index == 15)
5375 explicit_freq_bytes = 3;
5376 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5377 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5378 context->codec_priv_size), context->codec_priv_size);
5379 /* assume SBR if samplerate <= 24kHz */
5380 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5381 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5382 audiocontext->samplerate *= 2;
5385 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5386 /* this is pretty broken;
5387 * maybe we need to make up some default private,
5388 * or maybe ADTS data got dumped in.
5389 * Let's set up some private data now, and check actual data later */
5390 /* just try this and see what happens ... */
5391 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5392 context->postprocess_frame = gst_matroska_demux_check_aac;
5396 /* make up decoder-specific data if it is not supplied */
5400 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5401 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5403 rate_idx = aac_rate_idx (audiocontext->samplerate);
5404 profile = aac_profile_idx (codec_id);
5406 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5407 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5409 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5410 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5412 gst_buffer_unmap (priv, &map);
5413 gst_buffer_set_size (priv, 2);
5414 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5415 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5418 if (g_strrstr (codec_id, "SBR")) {
5419 /* HE-AAC (aka SBR AAC) */
5420 audiocontext->samplerate *= 2;
5421 rate_idx = aac_rate_idx (audiocontext->samplerate);
5422 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5423 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5424 data[4] = (1 << 7) | (rate_idx << 3);
5425 gst_buffer_unmap (priv, &map);
5427 gst_buffer_unmap (priv, &map);
5428 gst_buffer_set_size (priv, 2);
5431 gst_buffer_unmap (priv, &map);
5432 gst_buffer_unref (priv);
5434 GST_ERROR ("Unknown AAC profile and no codec private data");
5439 caps = gst_caps_new_simple ("audio/mpeg",
5440 "mpegversion", G_TYPE_INT, mpegversion,
5441 "framed", G_TYPE_BOOLEAN, TRUE,
5442 "stream-format", G_TYPE_STRING, "raw", NULL);
5443 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5444 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5445 gst_buffer_unref (priv);
5447 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5448 caps = gst_caps_new_simple ("audio/x-tta",
5449 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5450 *codec_name = g_strdup ("TTA audio");
5451 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5452 caps = gst_caps_new_simple ("audio/x-wavpack",
5453 "width", G_TYPE_INT, audiocontext->bitdepth,
5454 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5455 *codec_name = g_strdup ("Wavpack audio");
5456 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5457 audiocontext->wvpk_block_index = 0;
5458 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5459 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5460 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5461 gint raversion = -1;
5463 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5465 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5470 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5471 "raversion", G_TYPE_INT, raversion, NULL);
5472 /* Extract extra information from caps, mapping varies based on codec */
5473 if (data && (size >= 0x50)) {
5480 guint extra_data_size;
5482 GST_ERROR ("real audio raversion:%d", raversion);
5483 if (raversion == 8) {
5485 flavor = GST_READ_UINT16_BE (data + 22);
5486 packet_size = GST_READ_UINT32_BE (data + 24);
5487 height = GST_READ_UINT16_BE (data + 40);
5488 leaf_size = GST_READ_UINT16_BE (data + 44);
5489 sample_width = GST_READ_UINT16_BE (data + 58);
5490 extra_data_size = GST_READ_UINT32_BE (data + 74);
5493 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5494 flavor, packet_size, height, leaf_size, sample_width,
5496 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5497 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5498 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5500 if ((size - 78) >= extra_data_size) {
5501 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5503 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5504 gst_buffer_unref (priv);
5509 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5510 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5511 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5512 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5513 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5514 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5515 *codec_name = g_strdup ("Real Audio Lossless");
5516 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5517 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5518 *codec_name = g_strdup ("Sony ATRAC3");
5520 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5525 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5528 for (i = 0; i < gst_caps_get_size (caps); i++) {
5529 gst_structure_set (gst_caps_get_structure (caps, i),
5530 "channels", G_TYPE_INT, audiocontext->channels,
5531 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5535 caps = gst_caps_simplify (caps);
5542 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5543 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5545 GstCaps *caps = NULL;
5546 GstMatroskaTrackContext *context =
5547 (GstMatroskaTrackContext *) subtitlecontext;
5549 /* for backwards compatibility */
5550 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5551 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5552 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5553 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5554 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5555 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5556 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5557 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5559 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5560 * Check if we have to do something with codec_private */
5561 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5562 /* well, plain text simply does not have a lot of markup ... */
5563 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5564 "pango-markup", NULL);
5565 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5566 subtitlecontext->check_markup = TRUE;
5567 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5568 caps = gst_caps_new_empty_simple ("application/x-ssa");
5569 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5570 subtitlecontext->check_markup = FALSE;
5571 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5572 caps = gst_caps_new_empty_simple ("application/x-ass");
5573 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5574 subtitlecontext->check_markup = FALSE;
5575 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5576 caps = gst_caps_new_empty_simple ("application/x-usf");
5577 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5578 subtitlecontext->check_markup = FALSE;
5579 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5580 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5581 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5582 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5583 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5584 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5585 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5586 context->stream_headers =
5587 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5588 context->codec_priv_size);
5589 /* FIXME: mark stream as broken and skip if there are no stream headers */
5590 context->send_stream_headers = TRUE;
5592 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5593 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5596 if (data != NULL && size > 0) {
5599 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5600 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5601 gst_buffer_unref (buf);
5609 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5611 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5613 GST_OBJECT_LOCK (demux);
5614 if (demux->common.element_index)
5615 gst_object_unref (demux->common.element_index);
5616 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5617 GST_OBJECT_UNLOCK (demux);
5618 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5619 demux->common.element_index);
5623 gst_matroska_demux_get_index (GstElement * element)
5625 GstIndex *result = NULL;
5626 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5628 GST_OBJECT_LOCK (demux);
5629 if (demux->common.element_index)
5630 result = gst_object_ref (demux->common.element_index);
5631 GST_OBJECT_UNLOCK (demux);
5633 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5639 static GstStateChangeReturn
5640 gst_matroska_demux_change_state (GstElement * element,
5641 GstStateChange transition)
5643 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5644 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5646 /* handle upwards state changes here */
5647 switch (transition) {
5652 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5654 /* handle downwards state changes */
5655 switch (transition) {
5656 case GST_STATE_CHANGE_PAUSED_TO_READY:
5657 gst_matroska_demux_reset (GST_ELEMENT (demux));
5667 gst_matroska_demux_set_property (GObject * object,
5668 guint prop_id, const GValue * value, GParamSpec * pspec)
5670 GstMatroskaDemux *demux;
5672 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5673 demux = GST_MATROSKA_DEMUX (object);
5676 case ARG_MAX_GAP_TIME:
5677 GST_OBJECT_LOCK (demux);
5678 demux->max_gap_time = g_value_get_uint64 (value);
5679 GST_OBJECT_UNLOCK (demux);
5682 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5688 gst_matroska_demux_get_property (GObject * object,
5689 guint prop_id, GValue * value, GParamSpec * pspec)
5691 GstMatroskaDemux *demux;
5693 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5694 demux = GST_MATROSKA_DEMUX (object);
5697 case ARG_MAX_GAP_TIME:
5698 GST_OBJECT_LOCK (demux);
5699 g_value_set_uint64 (value, demux->max_gap_time);
5700 GST_OBJECT_UNLOCK (demux);
5703 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5709 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5713 /* parser helper separate debug */
5714 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5715 0, "EBML stream helper class");
5717 /* create an elementfactory for the matroska_demux element */
5718 if (!gst_element_register (plugin, "matroskademux",
5719 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))