1 /* GStreamer Matroska muxer/demuxer
2 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3 * (c) 2006 Tim-Philipp Müller <tim centricular net>
4 * (c) 2008 Sebastian Dröge <slomo@circular-chaos.org>
5 * (c) 2011 Debarshi Ray <rishi@gnu.org>
7 * matroska-demux.c: matroska file/stream demuxer
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
25 /* TODO: check CRC32 if present
26 * TODO: there can be a segment after the first segment. Handle like
27 * chained oggs. Fixes #334082
28 * TODO: Test samples: http://www.matroska.org/samples/matrix/index.html
29 * http://samples.mplayerhq.hu/Matroska/
30 * TODO: check if demuxing is done correct for all codecs according to spec
31 * TODO: seeking with incomplete or without CUE
35 * SECTION:element-matroskademux
37 * matroskademux demuxes a Matroska file into the different contained streams.
40 * <title>Example launch line</title>
42 * gst-launch -v filesrc location=/path/to/mkv ! matroskademux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
43 * ]| This pipeline demuxes a Matroska file and outputs the contained Vorbis audio.
54 #include <glib/gprintf.h>
56 /* For AVI compatibility mode
57 and for fourcc stuff */
58 #include <gst/riff/riff-read.h>
59 #include <gst/riff/riff-ids.h>
60 #include <gst/riff/riff-media.h>
62 #include <gst/audio/audio.h>
63 #include <gst/tag/tag.h>
64 #include <gst/pbutils/pbutils.h>
66 #include "matroska-demux.h"
67 #include "matroska-ids.h"
69 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
70 #define GST_CAT_DEFAULT matroskademux_debug
72 #define DEBUG_ELEMENT_START(demux, ebml, element) \
73 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
74 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
76 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
77 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
78 " finished with '%s'", gst_flow_get_name (ret))
88 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
90 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
93 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
94 "video/x-matroska-3d; audio/webm; video/webm")
97 /* TODO: fill in caps! */
99 static GstStaticPadTemplate audio_src_templ =
100 GST_STATIC_PAD_TEMPLATE ("audio_%u",
103 GST_STATIC_CAPS ("ANY")
106 static GstStaticPadTemplate video_src_templ =
107 GST_STATIC_PAD_TEMPLATE ("video_%u",
110 GST_STATIC_CAPS ("ANY")
113 static GstStaticPadTemplate subtitle_src_templ =
114 GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
117 GST_STATIC_CAPS ("text/x-pango-markup; application/x-ssa; "
118 "application/x-ass;application/x-usf; 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);
321 * Returns the aggregated GstFlowReturn.
324 gst_matroska_demux_combine_flows (GstMatroskaDemux * demux,
325 GstMatroskaTrackContext * track, GstFlowReturn ret)
329 /* store the value */
330 track->last_flow = ret;
332 /* any other error that is not-linked can be returned right away */
333 if (ret != GST_FLOW_NOT_LINKED)
336 /* only return NOT_LINKED if all other pads returned NOT_LINKED */
337 g_assert (demux->common.src->len == demux->common.num_streams);
338 for (i = 0; i < demux->common.src->len; i++) {
339 GstMatroskaTrackContext *ostream = g_ptr_array_index (demux->common.src,
345 ret = ostream->last_flow;
346 /* some other return value (must be SUCCESS but we can return
347 * other values as well) */
348 if (ret != GST_FLOW_NOT_LINKED)
351 /* if we get here, all other pads were unlinked and we return
354 GST_LOG_OBJECT (demux, "combined return %s", gst_flow_get_name (ret));
359 gst_matroska_demux_free_parsed_el (gpointer mem, gpointer user_data)
361 g_slice_free (guint64, mem);
365 gst_matroska_demux_reset (GstElement * element)
367 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
370 GST_DEBUG_OBJECT (demux, "Resetting state");
373 demux->common.state = GST_MATROSKA_READ_STATE_START;
375 /* clean up existing streams */
376 if (demux->common.src) {
377 g_assert (demux->common.src->len == demux->common.num_streams);
378 for (i = 0; i < demux->common.src->len; i++) {
379 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
382 if (context->pad != NULL)
383 gst_element_remove_pad (GST_ELEMENT (demux), context->pad);
385 gst_caps_replace (&context->caps, NULL);
386 gst_matroska_track_free (context);
388 g_ptr_array_free (demux->common.src, TRUE);
390 demux->common.src = g_ptr_array_new ();
392 demux->common.num_streams = 0;
393 demux->num_a_streams = 0;
394 demux->num_t_streams = 0;
395 demux->num_v_streams = 0;
397 /* reset media info */
398 g_free (demux->common.writing_app);
399 demux->common.writing_app = NULL;
400 g_free (demux->common.muxing_app);
401 demux->common.muxing_app = NULL;
404 if (demux->common.index) {
405 g_array_free (demux->common.index, TRUE);
406 demux->common.index = NULL;
409 if (demux->clusters) {
410 g_array_free (demux->clusters, TRUE);
411 demux->clusters = NULL;
416 demux->common.time_scale = 1000000;
417 demux->common.created = G_MININT64;
419 demux->common.index_parsed = FALSE;
420 demux->tracks_parsed = FALSE;
421 demux->common.segmentinfo_parsed = FALSE;
422 demux->common.attachments_parsed = FALSE;
423 demux->common.chapters_parsed = FALSE;
425 g_list_foreach (demux->common.tags_parsed,
426 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
427 g_list_free (demux->common.tags_parsed);
428 demux->common.tags_parsed = NULL;
430 g_list_foreach (demux->seek_parsed,
431 (GFunc) gst_matroska_demux_free_parsed_el, NULL);
432 g_list_free (demux->seek_parsed);
433 demux->seek_parsed = NULL;
435 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
436 demux->last_stop_end = GST_CLOCK_TIME_NONE;
437 demux->seek_block = 0;
438 demux->stream_start_time = GST_CLOCK_TIME_NONE;
439 demux->to_time = GST_CLOCK_TIME_NONE;
441 demux->common.offset = 0;
442 demux->cluster_time = GST_CLOCK_TIME_NONE;
443 demux->cluster_offset = 0;
444 demux->next_cluster_offset = 0;
445 demux->index_offset = 0;
446 demux->seekable = FALSE;
447 demux->need_segment = FALSE;
448 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
449 demux->seek_offset = -1;
450 demux->building_index = FALSE;
451 if (demux->seek_event) {
452 gst_event_unref (demux->seek_event);
453 demux->seek_event = NULL;
456 demux->seek_index = NULL;
457 demux->seek_entry = 0;
459 if (demux->new_segment) {
460 gst_event_unref (demux->new_segment);
461 demux->new_segment = NULL;
464 if (demux->common.element_index) {
465 gst_object_unref (demux->common.element_index);
466 demux->common.element_index = NULL;
468 demux->common.element_index_writer_id = -1;
471 if (demux->common.global_tags) {
472 gst_tag_list_unref (demux->common.global_tags);
474 demux->common.global_tags = gst_tag_list_new_empty ();
475 gst_tag_list_set_scope (demux->common.global_tags, GST_TAG_SCOPE_GLOBAL);
477 if (demux->common.cached_buffer) {
478 if (demux->common.cached_data) {
479 gst_buffer_unmap (demux->common.cached_buffer, &demux->common.cached_map);
480 demux->common.cached_data = NULL;
482 gst_buffer_unref (demux->common.cached_buffer);
483 demux->common.cached_buffer = NULL;
486 /* free chapters TOC if any */
487 if (demux->common.toc) {
488 gst_toc_unref (demux->common.toc);
489 demux->common.toc = NULL;
492 demux->invalid_duration = FALSE;
496 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
502 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
504 GST_DEBUG ("decoding buffer %p", buf);
506 gst_buffer_map (buf, &map, GST_MAP_READ);
510 g_return_val_if_fail (size > 0, buf);
512 if (gst_matroska_decode_data (context->encodings, &data, &size,
513 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
514 gst_buffer_unmap (buf, &map);
515 gst_buffer_unref (buf);
516 return gst_buffer_new_wrapped (data, size);
518 GST_DEBUG ("decode data failed");
519 gst_buffer_unmap (buf, &map);
520 gst_buffer_unref (buf);
526 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
528 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
529 GstMatroskaTrackContext *context;
530 GstPadTemplate *templ = NULL;
531 GstCaps *caps = NULL;
532 gchar *padname = NULL;
534 guint32 id, riff_fourcc = 0;
535 guint16 riff_audio_fmt = 0;
536 GstTagList *list = NULL;
540 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
542 /* start with the master */
543 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
544 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
548 /* allocate generic... if we know the type, we'll g_renew()
549 * with the precise type */
550 context = g_new0 (GstMatroskaTrackContext, 1);
551 g_ptr_array_add (demux->common.src, context);
552 context->index = demux->common.num_streams;
553 context->index_writer_id = -1;
554 context->type = 0; /* no type yet */
555 context->default_duration = 0;
557 context->set_discont = TRUE;
558 context->timecodescale = 1.0;
560 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
561 GST_MATROSKA_TRACK_LACING;
562 context->last_flow = GST_FLOW_OK;
563 context->from_time = GST_CLOCK_TIME_NONE;
564 context->from_offset = -1;
565 context->to_offset = G_MAXINT64;
566 context->alignment = 1;
567 demux->common.num_streams++;
568 g_assert (demux->common.src->len == demux->common.num_streams);
570 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
572 /* try reading the trackentry headers */
573 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
574 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
578 /* track number (unique stream ID) */
579 case GST_MATROSKA_ID_TRACKNUMBER:{
582 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
586 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
587 ret = GST_FLOW_ERROR;
589 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
591 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
592 " is not unique", num);
593 ret = GST_FLOW_ERROR;
597 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
601 /* track UID (unique identifier) */
602 case GST_MATROSKA_ID_TRACKUID:{
605 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
609 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
610 ret = GST_FLOW_ERROR;
614 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
619 /* track type (video, audio, combined, subtitle, etc.) */
620 case GST_MATROSKA_ID_TRACKTYPE:{
623 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
627 if (context->type != 0 && context->type != track_type) {
628 GST_WARNING_OBJECT (demux,
629 "More than one tracktype defined in a TrackEntry - skipping");
631 } else if (track_type < 1 || track_type > 254) {
632 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
637 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
639 /* ok, so we're actually going to reallocate this thing */
640 switch (track_type) {
641 case GST_MATROSKA_TRACK_TYPE_VIDEO:
642 gst_matroska_track_init_video_context (&context);
644 case GST_MATROSKA_TRACK_TYPE_AUDIO:
645 gst_matroska_track_init_audio_context (&context);
647 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
648 gst_matroska_track_init_subtitle_context (&context);
650 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
651 case GST_MATROSKA_TRACK_TYPE_LOGO:
652 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
653 case GST_MATROSKA_TRACK_TYPE_CONTROL:
655 GST_WARNING_OBJECT (demux,
656 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
661 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
666 /* tracktype specific stuff for video */
667 case GST_MATROSKA_ID_TRACKVIDEO:{
668 GstMatroskaTrackVideoContext *videocontext;
670 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
672 if (!gst_matroska_track_init_video_context (&context)) {
673 GST_WARNING_OBJECT (demux,
674 "TrackVideo element in non-video track - ignoring track");
675 ret = GST_FLOW_ERROR;
677 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
680 videocontext = (GstMatroskaTrackVideoContext *) context;
681 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
684 while (ret == GST_FLOW_OK &&
685 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
686 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
690 /* Should be one level up but some broken muxers write it here. */
691 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
694 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
698 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
702 GST_DEBUG_OBJECT (demux,
703 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
704 context->default_duration = num;
708 /* video framerate */
709 /* NOTE: This one is here only for backward compatibility.
710 * Use _TRACKDEFAULDURATION one level up. */
711 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
714 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
718 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
722 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
723 if (context->default_duration == 0)
724 context->default_duration =
725 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
726 videocontext->default_fps = num;
730 /* width of the size to display the video at */
731 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
734 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
738 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
742 GST_DEBUG_OBJECT (demux,
743 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
744 videocontext->display_width = num;
748 /* height of the size to display the video at */
749 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
752 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
756 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
760 GST_DEBUG_OBJECT (demux,
761 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
762 videocontext->display_height = num;
766 /* width of the video in the file */
767 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
770 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
774 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
778 GST_DEBUG_OBJECT (demux,
779 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
780 videocontext->pixel_width = num;
784 /* height of the video in the file */
785 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
788 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
792 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
796 GST_DEBUG_OBJECT (demux,
797 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
798 videocontext->pixel_height = num;
802 /* whether the video is interlaced */
803 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
806 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
810 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
812 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
813 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
814 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
819 /* aspect ratio behaviour */
820 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
823 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
826 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
827 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
828 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
829 GST_WARNING_OBJECT (demux,
830 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
833 GST_DEBUG_OBJECT (demux,
834 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
835 videocontext->asr_mode = num;
839 /* colourspace (only matters for raw video) fourcc */
840 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
845 gst_ebml_read_binary (ebml, &id, &data,
846 &datalen)) != GST_FLOW_OK)
851 GST_WARNING_OBJECT (demux,
852 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
857 memcpy (&videocontext->fourcc, data, 4);
858 GST_DEBUG_OBJECT (demux,
859 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
860 GST_FOURCC_ARGS (videocontext->fourcc));
866 GST_WARNING_OBJECT (demux,
867 "Unknown TrackVideo subelement 0x%x - ignoring", id);
869 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
870 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
871 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
872 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
873 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
874 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
875 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
876 ret = gst_ebml_read_skip (ebml);
881 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
885 /* tracktype specific stuff for audio */
886 case GST_MATROSKA_ID_TRACKAUDIO:{
887 GstMatroskaTrackAudioContext *audiocontext;
889 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
891 if (!gst_matroska_track_init_audio_context (&context)) {
892 GST_WARNING_OBJECT (demux,
893 "TrackAudio element in non-audio track - ignoring track");
894 ret = GST_FLOW_ERROR;
898 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
901 audiocontext = (GstMatroskaTrackAudioContext *) context;
902 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
905 while (ret == GST_FLOW_OK &&
906 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
907 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
912 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
915 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
920 GST_WARNING_OBJECT (demux,
921 "Invalid TrackAudioSamplingFrequency %lf", num);
925 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
926 audiocontext->samplerate = num;
931 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
934 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
938 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
942 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
944 audiocontext->bitdepth = num;
949 case GST_MATROSKA_ID_AUDIOCHANNELS:{
952 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
956 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
960 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
962 audiocontext->channels = num;
967 GST_WARNING_OBJECT (demux,
968 "Unknown TrackAudio subelement 0x%x - ignoring", id);
970 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
971 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
972 ret = gst_ebml_read_skip (ebml);
977 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
982 /* codec identifier */
983 case GST_MATROSKA_ID_CODECID:{
986 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
989 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
990 context->codec_id = text;
994 /* codec private data */
995 case GST_MATROSKA_ID_CODECPRIVATE:{
1000 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
1003 context->codec_priv = data;
1004 context->codec_priv_size = size;
1006 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1011 /* name of the codec */
1012 case GST_MATROSKA_ID_CODECNAME:{
1015 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1018 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1019 context->codec_name = text;
1023 /* name of this track */
1024 case GST_MATROSKA_ID_TRACKNAME:{
1027 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1030 context->name = text;
1031 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1035 /* language (matters for audio/subtitles, mostly) */
1036 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1039 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1043 context->language = text;
1046 if (strlen (context->language) >= 4 && context->language[3] == '-')
1047 context->language[3] = '\0';
1049 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1050 GST_STR_NULL (context->language));
1054 /* whether this is actually used */
1055 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1058 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1062 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1064 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1066 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1067 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1071 /* whether it's the default for this track type */
1072 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1075 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1079 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1081 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1083 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1084 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1088 /* whether the track must be used during playback */
1089 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1092 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1096 context->flags |= GST_MATROSKA_TRACK_FORCED;
1098 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1100 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1101 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1105 /* lacing (like MPEG, where blocks don't end/start on frame
1107 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1110 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1114 context->flags |= GST_MATROSKA_TRACK_LACING;
1116 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1118 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1119 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1123 /* default length (in time) of one data block in this track */
1124 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1127 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1132 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1136 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1138 context->default_duration = num;
1142 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1143 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1148 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1151 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1155 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1159 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1160 context->timecodescale = num;
1165 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1168 /* we ignore these because they're nothing useful (i.e. crap)
1169 * or simply not implemented yet. */
1170 case GST_MATROSKA_ID_TRACKMINCACHE:
1171 case GST_MATROSKA_ID_TRACKMAXCACHE:
1172 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1173 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1174 case GST_MATROSKA_ID_TRACKOVERLAY:
1175 case GST_MATROSKA_ID_TRACKTRANSLATE:
1176 case GST_MATROSKA_ID_TRACKOFFSET:
1177 case GST_MATROSKA_ID_CODECSETTINGS:
1178 case GST_MATROSKA_ID_CODECINFOURL:
1179 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1180 case GST_MATROSKA_ID_CODECDECODEALL:
1181 ret = gst_ebml_read_skip (ebml);
1186 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1188 /* Decode codec private data if necessary */
1189 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1190 && context->codec_priv_size > 0) {
1191 if (!gst_matroska_decode_data (context->encodings,
1192 &context->codec_priv, &context->codec_priv_size,
1193 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1194 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1195 ret = GST_FLOW_ERROR;
1199 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1200 && ret != GST_FLOW_EOS)) {
1201 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1202 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1204 demux->common.num_streams--;
1205 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1206 g_assert (demux->common.src->len == demux->common.num_streams);
1208 gst_matroska_track_free (context);
1214 /* now create the GStreamer connectivity */
1215 switch (context->type) {
1216 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1217 GstMatroskaTrackVideoContext *videocontext =
1218 (GstMatroskaTrackVideoContext *) context;
1220 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1221 templ = gst_element_class_get_pad_template (klass, "video_%u");
1222 caps = gst_matroska_demux_video_caps (videocontext,
1223 context->codec_id, context->codec_priv,
1224 context->codec_priv_size, &codec, &riff_fourcc);
1227 list = gst_tag_list_new (GST_TAG_VIDEO_CODEC, codec, NULL);
1233 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1234 GstMatroskaTrackAudioContext *audiocontext =
1235 (GstMatroskaTrackAudioContext *) context;
1237 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1238 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1239 caps = gst_matroska_demux_audio_caps (audiocontext,
1240 context->codec_id, context->codec_priv, context->codec_priv_size,
1241 &codec, &riff_audio_fmt);
1244 list = gst_tag_list_new (GST_TAG_AUDIO_CODEC, codec, NULL);
1250 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1251 GstMatroskaTrackSubtitleContext *subtitlecontext =
1252 (GstMatroskaTrackSubtitleContext *) context;
1254 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1255 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1256 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1257 context->codec_id, context->codec_priv, context->codec_priv_size);
1261 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1262 case GST_MATROSKA_TRACK_TYPE_LOGO:
1263 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1264 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1266 /* we should already have quit by now */
1267 g_assert_not_reached ();
1270 if ((context->language == NULL || *context->language == '\0') &&
1271 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1272 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1273 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1274 context->language = g_strdup ("eng");
1277 if (context->language) {
1281 list = gst_tag_list_new_empty ();
1283 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1284 lang = gst_tag_get_language_code (context->language);
1285 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1286 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1290 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1291 "codec_id='%s'", context->codec_id);
1292 switch (context->type) {
1293 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1294 caps = gst_caps_new_empty_simple ("video/x-unknown");
1296 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1297 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1299 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1300 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1302 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1304 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1307 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1310 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1311 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1312 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1313 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1314 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1315 GST_FOURCC_ARGS (riff_fourcc));
1316 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1321 /* the pad in here */
1322 context->pad = gst_pad_new_from_template (templ, padname);
1323 context->caps = caps;
1325 gst_pad_set_event_function (context->pad,
1326 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1327 gst_pad_set_query_function (context->pad,
1328 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1330 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1333 context->pending_tags = list;
1335 gst_pad_set_element_private (context->pad, context);
1337 gst_pad_use_fixed_caps (context->pad);
1338 gst_pad_set_active (context->pad, TRUE);
1341 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1342 "%u", context->uid);
1343 gst_pad_push_event (context->pad, gst_event_new_stream_start (stream_id));
1345 gst_pad_set_caps (context->pad, context->caps);
1347 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1356 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1359 gboolean res = FALSE;
1360 GstMatroskaTrackContext *context = NULL;
1363 context = gst_pad_get_element_private (pad);
1366 switch (GST_QUERY_TYPE (query)) {
1367 case GST_QUERY_POSITION:
1371 gst_query_parse_position (query, &format, NULL);
1374 if (format == GST_FORMAT_TIME) {
1375 GST_OBJECT_LOCK (demux);
1377 gst_query_set_position (query, GST_FORMAT_TIME,
1378 MAX (context->pos, demux->stream_start_time) -
1379 demux->stream_start_time);
1381 gst_query_set_position (query, GST_FORMAT_TIME,
1382 MAX (demux->common.segment.position, demux->stream_start_time) -
1383 demux->stream_start_time);
1384 GST_OBJECT_UNLOCK (demux);
1385 } else if (format == GST_FORMAT_DEFAULT && context
1386 && context->default_duration) {
1387 GST_OBJECT_LOCK (demux);
1388 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1389 context->pos / context->default_duration);
1390 GST_OBJECT_UNLOCK (demux);
1392 GST_DEBUG_OBJECT (demux,
1393 "only position query in TIME and DEFAULT format is supported");
1399 case GST_QUERY_DURATION:
1403 gst_query_parse_duration (query, &format, NULL);
1406 if (format == GST_FORMAT_TIME) {
1407 GST_OBJECT_LOCK (demux);
1408 gst_query_set_duration (query, GST_FORMAT_TIME,
1409 demux->common.segment.duration);
1410 GST_OBJECT_UNLOCK (demux);
1411 } else if (format == GST_FORMAT_DEFAULT && context
1412 && context->default_duration) {
1413 GST_OBJECT_LOCK (demux);
1414 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1415 demux->common.segment.duration / context->default_duration);
1416 GST_OBJECT_UNLOCK (demux);
1418 GST_DEBUG_OBJECT (demux,
1419 "only duration query in TIME and DEFAULT format is supported");
1425 case GST_QUERY_SEEKING:
1429 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1430 GST_OBJECT_LOCK (demux);
1431 if (fmt == GST_FORMAT_TIME) {
1434 if (demux->streaming) {
1435 /* assuming we'll be able to get an index ... */
1436 seekable = demux->seekable;
1441 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1442 0, demux->common.segment.duration);
1445 GST_OBJECT_UNLOCK (demux);
1450 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1453 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1462 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1464 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1468 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1471 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1473 return gst_matroska_demux_query (demux, pad, query);
1476 /* returns FALSE if there are no pads to deliver event to,
1477 * otherwise TRUE (whatever the outcome of event sending),
1478 * takes ownership of the passed event! */
1480 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1482 gboolean is_segment;
1483 gboolean ret = FALSE;
1486 g_return_val_if_fail (event != NULL, FALSE);
1488 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1489 GST_EVENT_TYPE_NAME (event));
1491 is_segment = (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
1493 g_assert (demux->common.src->len == demux->common.num_streams);
1494 for (i = 0; i < demux->common.src->len; i++) {
1495 GstMatroskaTrackContext *stream;
1497 stream = g_ptr_array_index (demux->common.src, i);
1498 gst_event_ref (event);
1499 gst_pad_push_event (stream->pad, event);
1502 /* FIXME: send global tags before stream tags */
1503 if (G_UNLIKELY (is_segment && stream->pending_tags != NULL)) {
1504 GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
1505 GST_PTR_FORMAT, stream->pending_tags,
1506 GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
1507 gst_pad_push_event (stream->pad,
1508 gst_event_new_tag (stream->pending_tags));
1509 stream->pending_tags = NULL;
1513 if (G_UNLIKELY (is_segment && demux->common.global_tags != NULL)) {
1514 GstEvent *tag_event;
1515 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1516 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1517 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1518 demux->common.global_tags, demux->common.global_tags);
1520 tag_event = gst_event_new_tag (demux->common.global_tags);
1522 for (i = 0; i < demux->common.src->len; i++) {
1523 GstMatroskaTrackContext *stream;
1525 stream = g_ptr_array_index (demux->common.src, i);
1526 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1529 gst_event_unref (tag_event);
1530 demux->common.global_tags = NULL;
1533 gst_event_unref (event);
1538 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1540 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1543 g_return_val_if_fail (event != NULL, FALSE);
1545 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1546 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1548 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1549 GST_EVENT_TYPE_NAME (event));
1552 gst_event_unref (event);
1557 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1558 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1562 GST_OBJECT_LOCK (demux);
1565 /* seek (relative to matroska segment) */
1566 /* position might be invalid; will error when streaming resumes ... */
1567 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1568 demux->next_cluster_offset = 0;
1570 GST_DEBUG_OBJECT (demux,
1571 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1572 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1573 entry->block, GST_TIME_ARGS (entry->time));
1575 /* update the time */
1576 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1577 demux->common.segment.position = entry->time;
1578 demux->seek_block = entry->block;
1579 demux->seek_first = TRUE;
1580 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1583 for (i = 0; i < demux->common.src->len; i++) {
1584 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1587 stream->to_offset = G_MAXINT64;
1589 if (stream->from_offset != -1)
1590 stream->to_offset = stream->from_offset;
1592 stream->from_offset = -1;
1593 stream->from_time = GST_CLOCK_TIME_NONE;
1596 GST_OBJECT_UNLOCK (demux);
1602 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1612 /* searches for a cluster start from @pos,
1613 * return GST_FLOW_OK and cluster position in @pos if found */
1614 static GstFlowReturn
1615 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1617 gint64 newpos = *pos;
1619 GstFlowReturn ret = GST_FLOW_OK;
1620 const guint chunk = 64 * 1024;
1621 GstBuffer *buf = NULL;
1623 gpointer data = NULL;
1629 orig_offset = demux->common.offset;
1631 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1634 if (demux->clusters) {
1637 cpos = gst_util_array_binary_search (demux->clusters->data,
1638 demux->clusters->len, sizeof (gint64),
1639 (GCompareDataFunc) gst_matroska_cluster_compare,
1640 GST_SEARCH_MODE_AFTER, pos, NULL);
1643 GST_DEBUG_OBJECT (demux,
1644 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1645 demux->common.offset = *cpos;
1646 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1647 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1648 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1655 /* read in at newpos and scan for ebml cluster id */
1657 GstByteReader reader;
1661 gst_buffer_unmap (buf, &map);
1662 gst_buffer_unref (buf);
1665 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1666 if (ret != GST_FLOW_OK)
1668 GST_DEBUG_OBJECT (demux,
1669 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1670 gst_buffer_get_size (buf), newpos);
1671 gst_buffer_map (buf, &map, GST_MAP_READ);
1674 gst_byte_reader_init (&reader, data, size);
1676 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1677 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1678 if (cluster_pos >= 0) {
1679 newpos += cluster_pos;
1680 /* prepare resuming at next byte */
1681 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1682 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1685 GST_DEBUG_OBJECT (demux,
1686 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1687 /* extra checks whether we really sync'ed to a cluster:
1688 * - either it is the first and only cluster
1689 * - either there is a cluster after this one
1690 * - either cluster length is undefined
1692 /* ok if first cluster (there may not a subsequent one) */
1693 if (newpos == demux->first_cluster_offset) {
1694 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1697 demux->common.offset = newpos;
1698 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1699 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1700 if (ret != GST_FLOW_OK) {
1701 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1704 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1705 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1707 /* ok if undefined length or first cluster */
1708 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1709 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1713 demux->common.offset += length + needed;
1714 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1715 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1716 if (ret != GST_FLOW_OK)
1718 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1719 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1720 if (id == GST_MATROSKA_ID_CLUSTER)
1722 /* not ok, resume */
1725 /* partial cluster id may have been in tail of buffer */
1726 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1731 gst_buffer_unmap (buf, &map);
1732 gst_buffer_unref (buf);
1737 demux->common.offset = orig_offset;
1742 /* bisect and scan through file for cluster starting before @time,
1743 * returns fake index entry with corresponding info on cluster */
1744 static GstMatroskaIndex *
1745 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1747 GstMatroskaIndex *entry = NULL;
1748 GstMatroskaReadState current_state;
1749 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1750 gint64 opos, newpos, startpos = 0, current_offset;
1751 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1752 const guint chunk = 64 * 1024;
1758 /* (under)estimate new position, resync using cluster ebml id,
1759 * and scan forward to appropriate cluster
1760 * (and re-estimate if need to go backward) */
1762 prev_cluster_time = GST_CLOCK_TIME_NONE;
1764 /* store some current state */
1765 current_state = demux->common.state;
1766 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1768 current_cluster_offset = demux->cluster_offset;
1769 current_cluster_time = demux->cluster_time;
1770 current_offset = demux->common.offset;
1772 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1774 /* estimate using start and current position */
1775 GST_OBJECT_LOCK (demux);
1776 opos = demux->common.offset - demux->common.ebml_segment_start;
1777 otime = demux->common.segment.position;
1778 GST_OBJECT_UNLOCK (demux);
1781 time = MAX (time, demux->stream_start_time);
1783 /* avoid division by zero in first estimation below */
1784 if (otime <= demux->stream_start_time)
1788 GST_LOG_OBJECT (demux,
1789 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1790 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1791 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1792 GST_TIME_ARGS (otime - demux->stream_start_time),
1793 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1795 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1796 time - demux->stream_start_time,
1797 otime - demux->stream_start_time) - chunk;
1800 /* favour undershoot */
1801 newpos = newpos * 90 / 100;
1802 newpos += demux->common.ebml_segment_start;
1804 GST_DEBUG_OBJECT (demux,
1805 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1806 GST_TIME_ARGS (time), newpos);
1808 /* and at least start scanning before previous scan start to avoid looping */
1809 startpos = startpos * 90 / 100;
1810 if (startpos && startpos < newpos)
1813 /* read in at newpos and scan for ebml cluster id */
1817 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1818 if (ret == GST_FLOW_EOS) {
1819 /* heuristic HACK */
1820 newpos = startpos * 80 / 100;
1821 GST_DEBUG_OBJECT (demux, "EOS; "
1822 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1823 GST_TIME_ARGS (time), newpos);
1826 } else if (ret != GST_FLOW_OK) {
1833 /* then start scanning and parsing for cluster time,
1834 * re-estimate if overshoot, otherwise next cluster and so on */
1835 demux->common.offset = newpos;
1836 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1838 guint64 cluster_size = 0;
1840 /* peek and parse some elements */
1841 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1842 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1843 if (ret != GST_FLOW_OK)
1845 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1846 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1848 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1849 if (ret != GST_FLOW_OK)
1852 if (id == GST_MATROSKA_ID_CLUSTER) {
1853 cluster_time = GST_CLOCK_TIME_NONE;
1854 if (length == G_MAXUINT64)
1857 cluster_size = length + needed;
1859 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1860 cluster_time == GST_CLOCK_TIME_NONE) {
1861 cluster_time = demux->cluster_time * demux->common.time_scale;
1862 cluster_offset = demux->cluster_offset;
1863 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1864 " with time %" GST_TIME_FORMAT, cluster_offset,
1865 GST_TIME_ARGS (cluster_time));
1866 if (cluster_time > time) {
1867 GST_DEBUG_OBJECT (demux, "overshot target");
1868 /* cluster overshoots */
1869 if (cluster_offset == demux->first_cluster_offset) {
1870 /* but no prev one */
1871 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1872 prev_cluster_time = cluster_time;
1873 prev_cluster_offset = cluster_offset;
1876 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1877 /* prev cluster did not overshoot, so prev cluster is target */
1880 /* re-estimate using this new position info */
1881 opos = cluster_offset;
1882 otime = cluster_time;
1886 /* cluster undershoots, goto next one */
1887 prev_cluster_time = cluster_time;
1888 prev_cluster_offset = cluster_offset;
1889 /* skip cluster if length is defined,
1890 * otherwise will be skippingly parsed into */
1892 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1893 demux->common.offset = cluster_offset + cluster_size;
1894 demux->cluster_time = GST_CLOCK_TIME_NONE;
1896 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1903 if (ret == GST_FLOW_EOS) {
1904 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1910 entry = g_new0 (GstMatroskaIndex, 1);
1911 entry->time = prev_cluster_time;
1912 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1913 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1914 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1918 /* restore some state */
1919 demux->cluster_offset = current_cluster_offset;
1920 demux->cluster_time = current_cluster_time;
1921 demux->common.offset = current_offset;
1922 demux->common.state = current_state;
1928 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1929 GstPad * pad, GstEvent * event)
1931 GstMatroskaIndex *entry = NULL;
1932 GstMatroskaIndex scan_entry;
1934 GstSeekType cur_type, stop_type;
1936 gboolean flush, keyunit, before, after, snap_next;
1939 GstMatroskaTrackContext *track = NULL;
1940 GstSegment seeksegment = { 0, };
1941 gboolean update = TRUE;
1942 gboolean pad_locked = FALSE;
1945 track = gst_pad_get_element_private (pad);
1947 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1950 /* we can only seek on time */
1951 if (format != GST_FORMAT_TIME) {
1952 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1956 /* copy segment, we need this because we still need the old
1957 * segment when we close the current segment. */
1958 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1960 /* pull mode without index means that the actual duration is not known,
1961 * we might be playing a file that's still being recorded
1962 * so, invalidate our current duration, which is only a moving target,
1963 * and should not be used to clamp anything */
1964 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
1965 seeksegment.duration = GST_CLOCK_TIME_NONE;
1969 GST_DEBUG_OBJECT (demux, "configuring seek");
1970 gst_segment_do_seek (&seeksegment, rate, format, flags,
1971 cur_type, cur, stop_type, stop, &update);
1972 /* compensate for clip start time, but only for SET seeks,
1973 * otherwise it is already part of the segments */
1974 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
1975 if (cur_type == GST_SEEK_TYPE_SET) {
1977 seeksegment.position += demux->stream_start_time;
1978 seeksegment.start += demux->stream_start_time;
1980 if (stop_type == GST_SEEK_TYPE_SET
1981 && GST_CLOCK_TIME_IS_VALID (seeksegment.stop)) {
1983 seeksegment.position += demux->stream_start_time;
1984 seeksegment.stop += demux->stream_start_time;
1989 /* restore segment duration (if any effect),
1990 * would be determined again when parsing, but anyway ... */
1991 seeksegment.duration = demux->common.segment.duration;
1993 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
1994 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
1995 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
1996 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
1998 /* always do full update if flushing,
1999 * otherwise problems might arise downstream with missing keyframes etc */
2000 update = update || flush;
2002 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2004 /* check sanity before we start flushing and all that */
2005 snap_next = after && !before;
2006 if (seeksegment.rate < 0)
2007 snap_next = !snap_next;
2008 GST_OBJECT_LOCK (demux);
2009 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2010 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2011 seeksegment.position, &demux->seek_index, &demux->seek_entry,
2012 snap_next)) == NULL) {
2013 /* pull mode without index can scan later on */
2014 if (demux->streaming) {
2015 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2016 GST_OBJECT_UNLOCK (demux);
2018 } else if (rate < 0.0) {
2019 /* FIXME: We should build an index during playback or when scanning
2020 * that can be used here. The reverse playback code requires seek_index
2021 * and seek_entry to be set!
2023 GST_DEBUG_OBJECT (demux,
2024 "No matching seek entry in index, needed for reverse playback");
2025 GST_OBJECT_UNLOCK (demux);
2029 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2030 GST_OBJECT_UNLOCK (demux);
2033 /* only have to update some segment,
2034 * but also still have to honour flush and so on */
2035 GST_DEBUG_OBJECT (demux, "... no update");
2036 /* bad goto, bad ... */
2040 if (demux->streaming)
2045 GST_DEBUG_OBJECT (demux, "Starting flush");
2046 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_start ());
2047 gst_matroska_demux_send_event (demux, gst_event_new_flush_start ());
2049 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2050 gst_pad_pause_task (demux->common.sinkpad);
2056 /* now grab the stream lock so that streaming cannot continue, for
2057 * non flushing seeks when the element is in PAUSED this could block
2059 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2060 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2063 /* pull mode without index can do some scanning */
2064 if (!demux->streaming && !entry) {
2065 /* need to stop flushing upstream as we need it next */
2067 gst_pad_push_event (demux->common.sinkpad,
2068 gst_event_new_flush_stop (TRUE));
2069 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2070 /* keep local copy */
2072 scan_entry = *entry;
2074 entry = &scan_entry;
2076 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2078 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop (TRUE));
2085 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2086 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2087 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2088 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2089 seeksegment.position = seeksegment.start;
2090 seeksegment.time = seeksegment.start - demux->stream_start_time;
2093 if (demux->streaming) {
2094 GST_OBJECT_LOCK (demux);
2095 /* track real position we should start at */
2096 GST_DEBUG_OBJECT (demux, "storing segment start");
2097 demux->requested_seek_time = seeksegment.position;
2098 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2099 GST_OBJECT_UNLOCK (demux);
2100 /* need to seek to cluster start to pick up cluster time */
2101 /* upstream takes care of flushing and all that
2102 * ... and newsegment event handling takes care of the rest */
2103 return perform_seek_to_offset (demux, rate,
2104 entry->pos + demux->common.ebml_segment_start);
2109 GST_DEBUG_OBJECT (demux, "Stopping flush");
2110 gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_stop (TRUE));
2111 gst_matroska_demux_send_event (demux, gst_event_new_flush_stop (TRUE));
2114 GST_OBJECT_LOCK (demux);
2115 /* now update the real segment info */
2116 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2117 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2118 GST_OBJECT_UNLOCK (demux);
2120 /* update some (segment) state */
2121 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2124 /* notify start of new segment */
2125 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2128 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2129 GST_FORMAT_TIME, demux->common.segment.start);
2130 gst_element_post_message (GST_ELEMENT (demux), msg);
2133 GST_OBJECT_LOCK (demux);
2134 if (demux->new_segment)
2135 gst_event_unref (demux->new_segment);
2137 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2138 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2139 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2140 demux->to_time = demux->common.segment.position;
2142 demux->to_time = GST_CLOCK_TIME_NONE;
2143 GST_OBJECT_UNLOCK (demux);
2145 /* restart our task since it might have been stopped when we did the
2147 gst_pad_start_task (demux->common.sinkpad,
2148 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2150 /* streaming can continue now */
2152 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2160 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2162 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2168 * Handle whether we can perform the seek event or if we have to let the chain
2169 * function handle seeks to build the seek indexes first.
2172 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2176 GstSeekType cur_type, stop_type;
2181 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2186 /* we can only seek on time */
2187 if (format != GST_FORMAT_TIME) {
2188 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2192 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2193 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2197 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2198 GST_DEBUG_OBJECT (demux,
2199 "Non-flushing seek not supported in streaming mode");
2203 if (flags & GST_SEEK_FLAG_SEGMENT) {
2204 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2208 /* check for having parsed index already */
2209 if (!demux->common.index_parsed) {
2210 gboolean building_index;
2213 if (!demux->index_offset) {
2214 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2218 GST_OBJECT_LOCK (demux);
2219 /* handle the seek event in the chain function */
2220 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2221 /* no more seek can be issued until state reset to _DATA */
2223 /* copy the event */
2224 if (demux->seek_event)
2225 gst_event_unref (demux->seek_event);
2226 demux->seek_event = gst_event_ref (event);
2228 /* set the building_index flag so that only one thread can setup the
2229 * structures for index seeking. */
2230 building_index = demux->building_index;
2231 if (!building_index) {
2232 demux->building_index = TRUE;
2233 offset = demux->index_offset;
2235 GST_OBJECT_UNLOCK (demux);
2237 if (!building_index) {
2238 /* seek to the first subindex or legacy index */
2239 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2240 return perform_seek_to_offset (demux, rate, offset);
2243 /* well, we are handling it already */
2247 /* delegate to tweaked regular seek */
2248 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2252 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2255 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2256 gboolean res = TRUE;
2258 switch (GST_EVENT_TYPE (event)) {
2259 case GST_EVENT_SEEK:
2260 /* no seeking until we are (safely) ready */
2261 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2262 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2265 if (!demux->streaming)
2266 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2268 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2269 gst_event_unref (event);
2274 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2275 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2276 GstMatroskaTrackVideoContext *videocontext =
2277 (GstMatroskaTrackVideoContext *) context;
2279 GstClockTimeDiff diff;
2280 GstClockTime timestamp;
2282 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2284 GST_OBJECT_LOCK (demux);
2285 videocontext->earliest_time = timestamp + diff;
2286 GST_OBJECT_UNLOCK (demux);
2289 gst_event_unref (event);
2293 case GST_EVENT_TOC_SELECT:
2296 GstTocEntry *entry = NULL;
2297 GstEvent *seek_event;
2300 if (!demux->common.toc) {
2301 GST_DEBUG_OBJECT (demux, "no TOC to select");
2304 gst_event_parse_toc_select (event, &uid);
2306 GST_OBJECT_LOCK (demux);
2307 entry = gst_toc_find_entry (demux->common.toc, uid);
2308 if (entry == NULL) {
2309 GST_OBJECT_UNLOCK (demux);
2310 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2313 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2314 GST_OBJECT_UNLOCK (demux);
2315 seek_event = gst_event_new_seek (1.0,
2317 GST_SEEK_FLAG_FLUSH,
2318 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2319 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2320 gst_event_unref (seek_event);
2324 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2328 gst_event_unref (event);
2332 /* events we don't need to handle */
2333 case GST_EVENT_NAVIGATION:
2334 gst_event_unref (event);
2338 case GST_EVENT_LATENCY:
2340 res = gst_pad_push_event (demux->common.sinkpad, event);
2347 static GstFlowReturn
2348 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2350 GstFlowReturn ret = GST_FLOW_EOS;
2351 gboolean done = TRUE;
2354 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2355 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2358 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2360 if (!demux->seek_entry) {
2361 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2365 for (i = 0; i < demux->common.src->len; i++) {
2366 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2368 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2369 ", stream %d at %" GST_TIME_FORMAT,
2370 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2371 GST_TIME_ARGS (stream->from_time));
2372 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2373 if (stream->from_time > demux->common.segment.start) {
2374 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2378 /* nothing pushed for this stream;
2379 * likely seek entry did not start at keyframe, so all was skipped.
2380 * So we need an earlier entry */
2386 GstMatroskaIndex *entry;
2388 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2389 --demux->seek_entry);
2390 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2400 static GstFlowReturn
2401 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2403 GstFlowReturn ret = GST_FLOW_OK;
2406 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2408 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2409 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2413 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2414 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2418 /* one track within the "all-tracks" header */
2419 case GST_MATROSKA_ID_TRACKENTRY:
2420 ret = gst_matroska_demux_add_stream (demux, ebml);
2424 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2429 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2431 demux->tracks_parsed = TRUE;
2437 * Read signed/unsigned "EBML" numbers.
2438 * Return: number of bytes processed.
2442 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2444 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2452 while (read <= 8 && !(total & len_mask)) {
2459 if ((total &= (len_mask - 1)) == len_mask - 1)
2464 if (data[n] == 0xff)
2466 total = (total << 8) | data[n];
2470 if (read == num_ffs && total != 0)
2479 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2484 /* read as unsigned number first */
2485 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2489 if (unum == G_MAXUINT64)
2492 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2498 * Mostly used for subtitles. We add void filler data for each
2499 * lagging stream to make sure we don't deadlock.
2503 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2507 GST_OBJECT_LOCK (demux);
2509 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2510 GST_TIME_ARGS (demux->common.segment.position));
2512 g_assert (demux->common.num_streams == demux->common.src->len);
2513 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2514 GstMatroskaTrackContext *context;
2516 context = g_ptr_array_index (demux->common.src, stream_nr);
2518 GST_LOG_OBJECT (demux,
2519 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2520 GST_TIME_ARGS (context->pos));
2522 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2523 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2527 /* does it lag? 0.5 seconds is a random threshold...
2528 * lag need only be considered if we have advanced into requested segment */
2529 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2530 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2531 demux->common.segment.position > demux->common.segment.start &&
2532 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2535 guint64 start = context->pos;
2536 guint64 stop = demux->common.segment.position - (GST_SECOND / 2);
2538 GST_DEBUG_OBJECT (demux,
2539 "Synchronizing stream %d with other by advancing time from %"
2540 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2541 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2543 context->pos = stop;
2545 event = gst_event_new_gap (start, stop - start);
2546 GST_OBJECT_UNLOCK (demux);
2547 gst_pad_push_event (context->pad, event);
2548 GST_OBJECT_LOCK (demux);
2552 GST_OBJECT_UNLOCK (demux);
2555 static GstFlowReturn
2556 gst_matroska_demux_push_hdr_buf (GstMatroskaDemux * demux,
2557 GstMatroskaTrackContext * stream, guint8 * data, guint len)
2559 GstFlowReturn ret, cret;
2560 GstBuffer *header_buf;
2562 header_buf = gst_buffer_new_wrapped (g_memdup (data, len), len);
2564 if (stream->set_discont) {
2565 GST_BUFFER_FLAG_SET (header_buf, GST_BUFFER_FLAG_DISCONT);
2566 stream->set_discont = FALSE;
2569 ret = gst_pad_push (stream->pad, header_buf);
2572 cret = gst_matroska_demux_combine_flows (demux, stream, ret);
2577 static GstFlowReturn
2578 gst_matroska_demux_push_flac_codec_priv_data (GstMatroskaDemux * demux,
2579 GstMatroskaTrackContext * stream)
2585 GST_LOG_OBJECT (demux, "priv data size = %" G_GSIZE_FORMAT,
2586 stream->codec_priv_size);
2588 pdata = (guint8 *) stream->codec_priv;
2590 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2591 if (stream->codec_priv_size < ((4) + (4 + 34))) {
2592 GST_WARNING_OBJECT (demux, "not enough codec priv data for flac headers");
2593 return GST_FLOW_ERROR;
2596 if (memcmp (pdata, "fLaC", 4) != 0) {
2597 GST_WARNING_OBJECT (demux, "no flac marker at start of stream headers");
2598 return GST_FLOW_ERROR;
2601 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 4);
2602 if (ret != GST_FLOW_OK)
2605 off = 4; /* skip fLaC marker */
2606 while (off < stream->codec_priv_size) {
2607 len = GST_READ_UINT8 (pdata + off + 1) << 16;
2608 len |= GST_READ_UINT8 (pdata + off + 2) << 8;
2609 len |= GST_READ_UINT8 (pdata + off + 3);
2611 GST_DEBUG_OBJECT (demux, "header packet: len=%u bytes, flags=0x%02x",
2612 len, (guint) pdata[off]);
2614 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata + off, len + 4);
2615 if (ret != GST_FLOW_OK)
2623 static GstFlowReturn
2624 gst_matroska_demux_push_speex_codec_priv_data (GstMatroskaDemux * demux,
2625 GstMatroskaTrackContext * stream)
2628 guint8 *pdata = stream->codec_priv;
2630 GST_LOG_OBJECT (demux, "priv data size = %" G_GSIZE_FORMAT,
2631 stream->codec_priv_size);
2633 /* need at least 'fLaC' marker + STREAMINFO metadata block */
2634 if (stream->codec_priv_size < 80) {
2635 GST_WARNING_OBJECT (demux, "not enough codec priv data for speex headers");
2636 return GST_FLOW_ERROR;
2639 if (memcmp (pdata, "Speex ", 8) != 0) {
2640 GST_WARNING_OBJECT (demux, "no Speex marker at start of stream headers");
2641 return GST_FLOW_ERROR;
2644 ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 80);
2645 if (ret != GST_FLOW_OK)
2648 if (stream->codec_priv_size == 80)
2651 return gst_matroska_demux_push_hdr_buf (demux, stream, pdata + 80,
2652 stream->codec_priv_size - 80);
2655 static GstFlowReturn
2656 gst_matroska_demux_push_xiph_codec_priv_data (GstMatroskaDemux * demux,
2657 GstMatroskaTrackContext * stream)
2660 guint8 *p = stream->codec_priv;
2661 gint i, offset, num_packets;
2662 guint *length, last;
2664 if (stream->codec_priv == NULL || stream->codec_priv_size == 0) {
2665 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
2666 ("Missing codec private data for xiph headers, broken file"));
2667 return GST_FLOW_ERROR;
2670 /* start of the stream and vorbis audio or theora video, need to
2671 * send the codec_priv data as first three packets */
2672 num_packets = p[0] + 1;
2673 GST_DEBUG_OBJECT (demux,
2674 "%u stream headers, total length=%" G_GSIZE_FORMAT " bytes",
2675 (guint) num_packets, stream->codec_priv_size);
2677 length = g_alloca (num_packets * sizeof (guint));
2681 /* first packets, read length values */
2682 for (i = 0; i < num_packets - 1; i++) {
2684 while (offset < stream->codec_priv_size) {
2685 length[i] += p[offset];
2686 if (p[offset++] != 0xff)
2691 if (offset + last > stream->codec_priv_size)
2692 return GST_FLOW_ERROR;
2694 /* last packet is the remaining size */
2695 length[i] = stream->codec_priv_size - offset - last;
2697 for (i = 0; i < num_packets; i++) {
2698 GST_DEBUG_OBJECT (demux, "buffer %d: length=%u bytes", i,
2700 if (offset + length[i] > stream->codec_priv_size)
2701 return GST_FLOW_ERROR;
2704 gst_matroska_demux_push_hdr_buf (demux, stream, p + offset, length[i]);
2705 if (ret != GST_FLOW_OK)
2708 offset += length[i];
2714 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2715 GstMatroskaTrackContext * stream)
2719 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2721 if (!stream->codec_priv)
2724 /* ideally, VobSub private data should be parsed and stored more convenient
2725 * elsewhere, but for now, only interested in a small part */
2727 /* make sure we have terminating 0 */
2728 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2730 /* just locate and parse palette part */
2731 start = strstr (buf, "palette:");
2736 guint8 r, g, b, y, u, v;
2739 while (g_ascii_isspace (*start))
2741 for (i = 0; i < 16; i++) {
2742 if (sscanf (start, "%06x", &col) != 1)
2745 while ((*start == ',') || g_ascii_isspace (*start))
2747 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2748 r = (col >> 16) & 0xff;
2749 g = (col >> 8) & 0xff;
2751 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2753 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2754 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2755 clut[i] = (y << 16) | (u << 8) | v;
2758 /* got them all without problems; build and send event */
2762 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2763 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2764 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2765 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2766 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2767 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2768 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2769 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2770 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2771 G_TYPE_INT, clut[15], NULL);
2773 gst_pad_push_event (stream->pad,
2774 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
2780 static GstFlowReturn
2781 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2782 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2785 guint seq_header_len;
2786 guint32 header, tmp;
2788 if (stream->codec_state) {
2789 seq_header = stream->codec_state;
2790 seq_header_len = stream->codec_state_size;
2791 } else if (stream->codec_priv) {
2792 seq_header = stream->codec_priv;
2793 seq_header_len = stream->codec_priv_size;
2798 /* Sequence header only needed for keyframes */
2799 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2802 if (gst_buffer_get_size (*buf) < 4)
2805 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2806 header = GUINT32_FROM_BE (tmp);
2808 /* Sequence start code, if not found prepend */
2809 if (header != 0x000001b3) {
2812 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2814 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2817 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2818 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2819 gst_buffer_get_size (*buf));
2821 gst_buffer_unref (*buf);
2828 static GstFlowReturn
2829 gst_matroska_demux_add_wvpk_header (GstElement * element,
2830 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2832 GstMatroskaTrackAudioContext *audiocontext =
2833 (GstMatroskaTrackAudioContext *) stream;
2834 GstBuffer *newbuf = NULL;
2835 GstMapInfo map, outmap;
2836 guint8 *buf_data, *data;
2844 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2847 wvh.total_samples = -1;
2848 wvh.block_index = audiocontext->wvpk_block_index;
2850 if (audiocontext->channels <= 2) {
2851 guint32 block_samples, tmp;
2852 gsize size = gst_buffer_get_size (*buf);
2854 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2855 block_samples = GUINT32_FROM_LE (tmp);
2856 /* we need to reconstruct the header of the wavpack block */
2858 /* -20 because ck_size is the size of the wavpack block -8
2859 * and lace_size is the size of the wavpack block + 12
2860 * (the three guint32 of the header that already are in the buffer) */
2861 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2863 /* block_samples, flags and crc are already in the buffer */
2864 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2866 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2872 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2873 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2874 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2875 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2876 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2877 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2879 /* Append data from buf: */
2880 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2881 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2883 gst_buffer_unref (*buf);
2885 audiocontext->wvpk_block_index += block_samples;
2887 guint8 *outdata = NULL;
2889 gsize buf_size, size, out_size = 0;
2890 guint32 block_samples, flags, crc, blocksize;
2892 gst_buffer_map (*buf, &map, GST_MAP_READ);
2893 buf_data = map.data;
2894 buf_size = map.size;
2897 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2898 gst_buffer_unmap (*buf, &map);
2899 return GST_FLOW_ERROR;
2905 block_samples = GST_READ_UINT32_LE (data);
2910 flags = GST_READ_UINT32_LE (data);
2913 crc = GST_READ_UINT32_LE (data);
2916 blocksize = GST_READ_UINT32_LE (data);
2920 if (blocksize == 0 || size < blocksize)
2923 g_assert ((newbuf == NULL) == (outdata == NULL));
2925 if (newbuf == NULL) {
2926 out_size = sizeof (Wavpack4Header) + blocksize;
2927 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2929 gst_buffer_copy_into (newbuf, *buf,
2930 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2933 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2934 outdata = outmap.data;
2936 gst_buffer_unmap (newbuf, &outmap);
2937 out_size += sizeof (Wavpack4Header) + blocksize;
2938 gst_buffer_set_size (newbuf, out_size);
2939 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2940 outdata = outmap.data;
2943 outdata[outpos] = 'w';
2944 outdata[outpos + 1] = 'v';
2945 outdata[outpos + 2] = 'p';
2946 outdata[outpos + 3] = 'k';
2949 GST_WRITE_UINT32_LE (outdata + outpos,
2950 blocksize + sizeof (Wavpack4Header) - 8);
2951 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2952 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2953 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2954 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2955 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2956 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2957 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2958 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2961 g_memmove (outdata + outpos, data, blocksize);
2962 outpos += blocksize;
2966 gst_buffer_unmap (*buf, &map);
2967 gst_buffer_unref (*buf);
2970 gst_buffer_unmap (newbuf, &outmap);
2973 audiocontext->wvpk_block_index += block_samples;
2979 /* @text must be null-terminated */
2981 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2986 g_return_val_if_fail (text != NULL, FALSE);
2988 /* yes, this might all lead to false positives ... */
2989 tag = (gchar *) text;
2990 while ((tag = strchr (tag, '<'))) {
2992 if (*tag != '\0' && *(tag + 1) == '>') {
2993 /* some common convenience ones */
2994 /* maybe any character will do here ? */
3007 if (strstr (text, "<span"))
3013 static GstFlowReturn
3014 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
3015 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3017 GstMatroskaTrackSubtitleContext *sub_stream;
3018 const gchar *encoding;
3024 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3026 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
3029 if (!sub_stream->invalid_utf8) {
3030 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
3033 GST_WARNING_OBJECT (element, "subtitle stream %d is not valid UTF-8, this "
3034 "is broken according to the matroska specification", stream->num);
3035 sub_stream->invalid_utf8 = TRUE;
3038 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3039 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3040 if (encoding == NULL || *encoding == '\0') {
3041 /* if local encoding is UTF-8 and no encoding specified
3042 * via the environment variable, assume ISO-8859-15 */
3043 if (g_get_charset (&encoding)) {
3044 encoding = "ISO-8859-15";
3049 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3050 (char *) "*", NULL, NULL, &err);
3053 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3054 encoding, err->message);
3058 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3059 encoding = "ISO-8859-15";
3061 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3062 encoding, (char *) "*", NULL, NULL, NULL);
3065 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3066 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3069 utf8 = g_strdup ("invalid subtitle");
3071 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3072 gst_buffer_copy_into (newbuf, *buf,
3073 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3075 gst_buffer_unmap (*buf, &map);
3076 gst_buffer_unref (*buf);
3079 gst_buffer_map (*buf, &map, GST_MAP_READ);
3082 if (sub_stream->check_markup) {
3083 /* caps claim markup text, so we need to escape text,
3084 * except if text is already markup and then needs no further escaping */
3085 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3086 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3088 if (!sub_stream->seen_markup_tag) {
3089 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3091 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3092 gst_buffer_copy_into (newbuf, *buf,
3093 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3094 GST_BUFFER_COPY_META, 0, -1);
3095 gst_buffer_unmap (*buf, &map);
3096 gst_buffer_unref (*buf);
3105 static GstFlowReturn
3106 gst_matroska_demux_check_aac (GstElement * element,
3107 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3112 gst_buffer_extract (*buf, 0, data, 2);
3113 size = gst_buffer_get_size (*buf);
3115 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3118 /* tss, ADTS data, remove codec_data
3119 * still assume it is at least parsed */
3120 stream->caps = gst_caps_make_writable (stream->caps);
3121 s = gst_caps_get_structure (stream->caps, 0);
3123 gst_structure_remove_field (s, "codec_data");
3124 gst_pad_set_caps (stream->pad, stream->caps);
3125 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3126 "new caps: %" GST_PTR_FORMAT, stream->caps);
3129 /* disable subsequent checking */
3130 stream->postprocess_frame = NULL;
3136 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3137 GstBuffer * buffer, gsize alignment)
3141 gst_buffer_map (buffer, &map, GST_MAP_READ);
3143 if (map.size < sizeof (guintptr)) {
3144 gst_buffer_unmap (buffer, &map);
3148 if (((guintptr) map.data) & (alignment - 1)) {
3149 GstBuffer *new_buffer;
3150 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3152 new_buffer = gst_buffer_new_allocate (NULL,
3153 gst_buffer_get_size (buffer), ¶ms);
3155 /* Copy data "by hand", so ensure alignment is kept: */
3156 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3158 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3159 GST_DEBUG_OBJECT (demux,
3160 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3163 gst_buffer_unmap (buffer, &map);
3164 gst_buffer_unref (buffer);
3169 gst_buffer_unmap (buffer, &map);
3173 static GstFlowReturn
3174 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3175 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3176 gboolean is_simpleblock)
3178 GstMatroskaTrackContext *stream = NULL;
3179 GstFlowReturn ret = GST_FLOW_OK;
3180 gboolean readblock = FALSE;
3182 guint64 block_duration = -1;
3183 GstBuffer *buf = NULL;
3185 gint stream_num = -1, n, laces = 0;
3187 gint *lace_size = NULL;
3190 gint64 referenceblock = 0;
3193 offset = gst_ebml_read_get_offset (ebml);
3195 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3196 if (!is_simpleblock) {
3197 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3201 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3205 /* one block inside the group. Note, block parsing is one
3206 * of the harder things, so this code is a bit complicated.
3207 * See http://www.matroska.org/ for documentation. */
3208 case GST_MATROSKA_ID_SIMPLEBLOCK:
3209 case GST_MATROSKA_ID_BLOCK:
3215 gst_buffer_unmap (buf, &map);
3216 gst_buffer_unref (buf);
3219 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3222 gst_buffer_map (buf, &map, GST_MAP_READ);
3226 /* first byte(s): blocknum */
3227 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3232 /* fetch stream from num */
3233 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3235 if (G_UNLIKELY (size < 3)) {
3236 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3237 /* non-fatal, try next block(group) */
3240 } else if (G_UNLIKELY (stream_num < 0 ||
3241 stream_num >= demux->common.num_streams)) {
3242 /* let's not give up on a stray invalid track number */
3243 GST_WARNING_OBJECT (demux,
3244 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3245 "; ignoring block", stream_num, num);
3249 stream = g_ptr_array_index (demux->common.src, stream_num);
3251 /* time (relative to cluster time) */
3252 time = ((gint16) GST_READ_UINT16_BE (data));
3255 flags = GST_READ_UINT8 (data);
3259 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3262 switch ((flags & 0x06) >> 1) {
3263 case 0x0: /* no lacing */
3265 lace_size = g_new (gint, 1);
3266 lace_size[0] = size;
3269 case 0x1: /* xiph lacing */
3270 case 0x2: /* fixed-size lacing */
3271 case 0x3: /* EBML lacing */
3273 goto invalid_lacing;
3274 laces = GST_READ_UINT8 (data) + 1;
3277 lace_size = g_new0 (gint, laces);
3279 switch ((flags & 0x06) >> 1) {
3280 case 0x1: /* xiph lacing */ {
3281 guint temp, total = 0;
3283 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3286 goto invalid_lacing;
3287 temp = GST_READ_UINT8 (data);
3288 lace_size[n] += temp;
3294 total += lace_size[n];
3296 lace_size[n] = size - total;
3300 case 0x2: /* fixed-size lacing */
3301 for (n = 0; n < laces; n++)
3302 lace_size[n] = size / laces;
3305 case 0x3: /* EBML lacing */ {
3308 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3312 total = lace_size[0] = num;
3313 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3317 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3321 lace_size[n] = lace_size[n - 1] + snum;
3322 total += lace_size[n];
3325 lace_size[n] = size - total;
3332 if (stream->send_xiph_headers) {
3333 ret = gst_matroska_demux_push_xiph_codec_priv_data (demux, stream);
3334 stream->send_xiph_headers = FALSE;
3337 if (stream->send_flac_headers) {
3338 ret = gst_matroska_demux_push_flac_codec_priv_data (demux, stream);
3339 stream->send_flac_headers = FALSE;
3342 if (stream->send_speex_headers) {
3343 ret = gst_matroska_demux_push_speex_codec_priv_data (demux, stream);
3344 stream->send_speex_headers = FALSE;
3347 if (stream->send_dvd_event) {
3348 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
3349 /* FIXME: should we send this event again after (flushing) seek ? */
3350 stream->send_dvd_event = FALSE;
3353 if (ret != GST_FLOW_OK)
3360 case GST_MATROSKA_ID_BLOCKDURATION:{
3361 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3362 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3367 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3368 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3369 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3374 case GST_MATROSKA_ID_CODECSTATE:{
3376 guint64 data_len = 0;
3379 gst_ebml_read_binary (ebml, &id, &data,
3380 &data_len)) != GST_FLOW_OK)
3383 if (G_UNLIKELY (stream == NULL)) {
3384 GST_WARNING_OBJECT (demux,
3385 "Unexpected CodecState subelement - ignoring");
3389 g_free (stream->codec_state);
3390 stream->codec_state = data;
3391 stream->codec_state_size = data_len;
3393 /* Decode if necessary */
3394 if (stream->encodings && stream->encodings->len > 0
3395 && stream->codec_state && stream->codec_state_size > 0) {
3396 if (!gst_matroska_decode_data (stream->encodings,
3397 &stream->codec_state, &stream->codec_state_size,
3398 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3399 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3403 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3404 stream->codec_state_size);
3409 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3413 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3414 case GST_MATROSKA_ID_BLOCKADDITIONS:
3415 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3416 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3417 case GST_MATROSKA_ID_SLICES:
3418 GST_DEBUG_OBJECT (demux,
3419 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3420 ret = gst_ebml_read_skip (ebml);
3428 /* reading a number or so could have failed */
3429 if (ret != GST_FLOW_OK)
3432 if (ret == GST_FLOW_OK && readblock) {
3433 guint64 duration = 0;
3434 gint64 lace_time = 0;
3435 gboolean delta_unit;
3437 stream = g_ptr_array_index (demux->common.src, stream_num);
3439 if (cluster_time != GST_CLOCK_TIME_NONE) {
3440 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3441 * Drop unless the lace contains timestamp 0? */
3442 if (time < 0 && (-time) > cluster_time) {
3445 if (stream->timecodescale == 1.0)
3446 lace_time = (cluster_time + time) * demux->common.time_scale;
3449 gst_util_guint64_to_gdouble ((cluster_time + time) *
3450 demux->common.time_scale) * stream->timecodescale;
3453 lace_time = GST_CLOCK_TIME_NONE;
3456 /* need to refresh segment info ASAP */
3457 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3458 GstSegment *segment = &demux->common.segment;
3461 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3462 demux->stream_start_time = lace_time;
3463 GST_DEBUG_OBJECT (demux,
3464 "Setting stream start time to %" GST_TIME_FORMAT,
3465 GST_TIME_ARGS (lace_time));
3467 clace_time = MAX (lace_time, demux->stream_start_time);
3468 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3469 demux->common.segment.position != 0) {
3470 GST_DEBUG_OBJECT (demux,
3471 "using stored seek position %" GST_TIME_FORMAT,
3472 GST_TIME_ARGS (demux->common.segment.position));
3473 clace_time = demux->common.segment.position + demux->stream_start_time;
3474 segment->position = GST_CLOCK_TIME_NONE;
3476 segment->start = clace_time;
3477 segment->stop = GST_CLOCK_TIME_NONE;
3478 segment->time = segment->start - demux->stream_start_time;
3479 segment->position = segment->start - demux->stream_start_time;
3480 GST_DEBUG_OBJECT (demux,
3481 "generated segment starting at %" GST_TIME_FORMAT ": %"
3482 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3483 /* now convey our segment notion downstream */
3484 gst_matroska_demux_send_event (demux, gst_event_new_segment (segment));
3485 demux->need_segment = FALSE;
3488 if (block_duration != -1) {
3489 if (stream->timecodescale == 1.0)
3490 duration = gst_util_uint64_scale (block_duration,
3491 demux->common.time_scale, 1);
3494 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3495 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3496 1)) * stream->timecodescale);
3497 } else if (stream->default_duration) {
3498 duration = stream->default_duration * laces;
3500 /* else duration is diff between timecode of this and next block */
3502 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3503 a ReferenceBlock implies that this is not a keyframe. In either
3504 case, it only makes sense for video streams. */
3505 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3506 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
3508 if (delta_unit && stream->set_discont) {
3509 /* When doing seeks or such, we need to restart on key frames or
3510 * decoders might choke. */
3511 GST_DEBUG_OBJECT (demux, "skipping delta unit");
3515 for (n = 0; n < laces; n++) {
3518 if (G_UNLIKELY (lace_size[n] > size)) {
3519 GST_WARNING_OBJECT (demux, "Invalid lace size");
3523 /* QoS for video track with an index. the assumption is that
3524 index entries point to keyframes, but if that is not true we
3525 will instad skip until the next keyframe. */
3526 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3527 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3528 stream->index_table && demux->common.segment.rate > 0.0) {
3529 GstMatroskaTrackVideoContext *videocontext =
3530 (GstMatroskaTrackVideoContext *) stream;
3531 GstClockTime earliest_time;
3532 GstClockTime earliest_stream_time;
3534 GST_OBJECT_LOCK (demux);
3535 earliest_time = videocontext->earliest_time;
3536 GST_OBJECT_UNLOCK (demux);
3537 earliest_stream_time = gst_segment_to_position (&demux->common.segment,
3538 GST_FORMAT_TIME, earliest_time);
3540 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3541 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3542 lace_time <= earliest_stream_time) {
3543 /* find index entry (keyframe) <= earliest_stream_time */
3544 GstMatroskaIndex *entry =
3545 gst_util_array_binary_search (stream->index_table->data,
3546 stream->index_table->len, sizeof (GstMatroskaIndex),
3547 (GCompareDataFunc) gst_matroska_index_seek_find,
3548 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3550 /* if that entry (keyframe) is after the current the current
3551 buffer, we can skip pushing (and thus decoding) all
3552 buffers until that keyframe. */
3553 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3554 entry->time > lace_time) {
3555 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3556 stream->set_discont = TRUE;
3562 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3563 gst_buffer_get_size (buf) - size, lace_size[n]);
3564 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3567 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3569 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3571 if (stream->encodings != NULL && stream->encodings->len > 0)
3572 sub = gst_matroska_decode_buffer (stream, sub);
3575 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3579 GST_BUFFER_TIMESTAMP (sub) = lace_time;
3581 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3582 GstClockTime last_stop_end;
3584 /* Check if this stream is after segment stop */
3585 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3586 lace_time >= demux->common.segment.stop) {
3587 GST_DEBUG_OBJECT (demux,
3588 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3589 GST_TIME_ARGS (demux->common.segment.stop));
3590 gst_buffer_unref (sub);
3593 if (offset >= stream->to_offset
3594 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3595 && lace_time > demux->to_time)) {
3596 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3598 gst_buffer_unref (sub);
3602 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3603 * that landed us with timestamps not quite intended */
3604 GST_OBJECT_LOCK (demux);
3605 if (demux->max_gap_time &&
3606 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3607 demux->common.segment.rate > 0.0) {
3608 GstClockTimeDiff diff;
3610 /* only send segments with increasing start times,
3611 * otherwise if these go back and forth downstream (sinks) increase
3612 * accumulated time and running_time */
3613 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3614 if (diff > 0 && diff > demux->max_gap_time
3615 && lace_time > demux->common.segment.start
3616 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3617 || lace_time < demux->common.segment.stop)) {
3619 GstEvent *event1, *event2;
3620 GST_DEBUG_OBJECT (demux,
3621 "Gap of %" G_GINT64_FORMAT " ns detected in"
3622 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3623 "Sending updated SEGMENT events", diff,
3624 stream->index, GST_TIME_ARGS (stream->pos),
3625 GST_TIME_ARGS (lace_time));
3626 /* send segment events such that the gap is not accounted in
3627 * segment base time, hence running_time */
3628 /* close ahead of gap */
3629 segment = demux->common.segment;
3630 segment.start = demux->last_stop_end;
3631 segment.stop = demux->last_stop_end;
3632 segment.position = demux->last_stop_end;
3633 event1 = gst_event_new_segment (&segment);
3635 segment.start = lace_time;
3636 segment.stop = demux->common.segment.stop;
3637 segment.position = lace_time;
3638 event2 = gst_event_new_segment (&segment);
3639 GST_OBJECT_UNLOCK (demux);
3640 gst_matroska_demux_send_event (demux, event1);
3641 gst_matroska_demux_send_event (demux, event2);
3642 GST_OBJECT_LOCK (demux);
3643 /* align segment view with downstream,
3644 * prevents double-counting base time when closing segment */
3645 /* FIXME: in 0.10, the segment base/accum got updated here, but
3646 * maybe we don't need that because of the double accounting
3647 * mentioned above? */
3648 demux->common.segment = segment;
3652 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3653 || demux->common.segment.position < lace_time) {
3654 demux->common.segment.position = lace_time;
3656 GST_OBJECT_UNLOCK (demux);
3658 last_stop_end = lace_time;
3660 GST_BUFFER_DURATION (sub) = duration / laces;
3661 last_stop_end += GST_BUFFER_DURATION (sub);
3664 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3665 demux->last_stop_end < last_stop_end)
3666 demux->last_stop_end = last_stop_end;
3668 GST_OBJECT_LOCK (demux);
3669 if (demux->common.segment.duration == -1 ||
3670 demux->stream_start_time + demux->common.segment.duration <
3672 demux->common.segment.duration =
3673 last_stop_end - demux->stream_start_time;
3674 GST_OBJECT_UNLOCK (demux);
3675 if (!demux->invalid_duration) {
3676 gst_element_post_message (GST_ELEMENT_CAST (demux),
3677 gst_message_new_duration (GST_OBJECT_CAST (demux),
3678 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
3679 demux->invalid_duration = TRUE;
3682 GST_OBJECT_UNLOCK (demux);
3686 stream->pos = lace_time;
3688 gst_matroska_demux_sync_streams (demux);
3690 if (stream->set_discont) {
3691 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3692 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3693 stream->set_discont = FALSE;
3696 /* reverse playback book-keeping */
3697 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3698 stream->from_time = lace_time;
3699 if (stream->from_offset == -1)
3700 stream->from_offset = offset;
3702 GST_DEBUG_OBJECT (demux,
3703 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3704 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3705 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3706 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
3707 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3710 if (demux->common.element_index) {
3711 if (stream->index_writer_id == -1)
3712 gst_index_get_writer_id (demux->common.element_index,
3713 GST_OBJECT (stream->pad), &stream->index_writer_id);
3715 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3716 G_GUINT64_FORMAT " for writer id %d",
3717 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
3718 stream->index_writer_id);
3719 gst_index_add_association (demux->common.element_index,
3720 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3721 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3722 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
3723 cluster_offset, NULL);
3727 /* Postprocess the buffers depending on the codec used */
3728 if (stream->postprocess_frame) {
3729 GST_LOG_OBJECT (demux, "running post process");
3730 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3733 /* At this point, we have a sub-buffer pointing at data within a larger
3734 buffer. This data might not be aligned with anything. If the data is
3735 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3736 for 32 bit samples, etc), or bad things will happen downstream as
3737 elements typically assume minimal alignment.
3738 Therefore, create an aligned copy if necessary. */
3739 g_assert (stream->alignment <= G_MEM_ALIGN);
3740 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3742 ret = gst_pad_push (stream->pad, sub);
3744 if (demux->common.segment.rate < 0) {
3745 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3746 /* In reverse playback we can get a GST_FLOW_EOS when
3747 * we are at the end of the segment, so we just need to jump
3748 * back to the previous section. */
3749 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3754 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3757 size -= lace_size[n];
3758 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3759 lace_time += duration / laces;
3761 lace_time = GST_CLOCK_TIME_NONE;
3767 gst_buffer_unmap (buf, &map);
3768 gst_buffer_unref (buf);
3780 ret = gst_matroska_demux_combine_flows (demux, stream, ret);
3785 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3786 /* non-fatal, try next block(group) */
3792 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3793 /* non-fatal, try next block(group) */
3799 /* return FALSE if block(group) should be skipped (due to a seek) */
3800 static inline gboolean
3801 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3803 if (G_UNLIKELY (demux->seek_block)) {
3804 if (!(--demux->seek_block)) {
3807 GST_LOG_OBJECT (demux, "should skip block due to seek");
3815 static GstFlowReturn
3816 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3820 guint64 seek_pos = (guint64) - 1;
3821 guint32 seek_id = 0;
3824 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3826 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3827 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3831 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3832 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3836 case GST_MATROSKA_ID_SEEKID:
3840 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3843 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3848 case GST_MATROSKA_ID_SEEKPOSITION:
3852 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3855 if (t > G_MAXINT64) {
3856 GST_WARNING_OBJECT (demux,
3857 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3861 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3867 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3873 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3876 if (!seek_id || seek_pos == (guint64) - 1) {
3877 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3878 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3883 case GST_MATROSKA_ID_SEEKHEAD:
3886 case GST_MATROSKA_ID_CUES:
3887 case GST_MATROSKA_ID_TAGS:
3888 case GST_MATROSKA_ID_TRACKS:
3889 case GST_MATROSKA_ID_SEGMENTINFO:
3890 case GST_MATROSKA_ID_ATTACHMENTS:
3891 case GST_MATROSKA_ID_CHAPTERS:
3893 guint64 before_pos, length;
3897 length = gst_matroska_read_common_get_length (&demux->common);
3898 before_pos = demux->common.offset;
3900 if (length == (guint64) - 1) {
3901 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3905 /* check for validity */
3906 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3907 GST_WARNING_OBJECT (demux,
3908 "SeekHead reference lies outside file!" " (%"
3909 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3910 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3915 /* only pick up index location when streaming */
3916 if (demux->streaming) {
3917 if (seek_id == GST_MATROSKA_ID_CUES) {
3918 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3919 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3920 demux->index_offset);
3926 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3929 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3930 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3934 if (id != seek_id) {
3935 GST_WARNING_OBJECT (demux,
3936 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3937 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3940 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3945 demux->common.offset = before_pos;
3949 case GST_MATROSKA_ID_CLUSTER:
3951 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3953 GST_LOG_OBJECT (demux, "Cluster position");
3954 if (G_UNLIKELY (!demux->clusters))
3955 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3956 g_array_append_val (demux->clusters, pos);
3961 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3964 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3969 static GstFlowReturn
3970 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3972 GstFlowReturn ret = GST_FLOW_OK;
3975 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3977 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3978 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3982 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3983 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3987 case GST_MATROSKA_ID_SEEKENTRY:
3989 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3990 /* Ignore EOS and errors here */
3991 if (ret != GST_FLOW_OK) {
3992 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3999 ret = gst_matroska_read_common_parse_skip (&demux->common,
4000 ebml, "SeekHead", id);
4005 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4007 /* Sort clusters by position for easier searching */
4008 if (demux->clusters)
4009 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4014 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
4016 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4018 static inline GstFlowReturn
4019 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4021 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4022 /* only a few blocks are expected/allowed to be large,
4023 * and will be recursed into, whereas others will be read and must fit */
4024 if (demux->streaming) {
4025 /* fatal in streaming case, as we can't step over easily */
4026 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4027 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4028 "file might be corrupt.", bytes));
4029 return GST_FLOW_ERROR;
4031 /* indicate higher level to quietly give up */
4032 GST_DEBUG_OBJECT (demux,
4033 "too large block of size %" G_GUINT64_FORMAT, bytes);
4034 return GST_FLOW_ERROR;
4041 /* returns TRUE if we truely are in error state, and should give up */
4042 static inline gboolean
4043 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4045 if (!demux->streaming && demux->next_cluster_offset > 0) {
4046 /* just repositioning to where next cluster should be and try from there */
4047 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4048 G_GUINT64_FORMAT, demux->next_cluster_offset);
4049 demux->common.offset = demux->next_cluster_offset;
4050 demux->next_cluster_offset = 0;
4055 /* sigh, one last attempt above and beyond call of duty ...;
4056 * search for cluster mark following current pos */
4057 pos = demux->common.offset;
4058 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4059 if (gst_matroska_demux_search_cluster (demux, &pos) != GST_FLOW_OK) {
4060 /* did not work, give up */
4063 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4064 /* try that position */
4065 demux->common.offset = pos;
4071 static inline GstFlowReturn
4072 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4074 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4075 demux->common.offset += flush;
4076 if (demux->streaming) {
4079 /* hard to skip large blocks when streaming */
4080 ret = gst_matroska_demux_check_read_size (demux, flush);
4081 if (ret != GST_FLOW_OK)
4083 if (flush <= gst_adapter_available (demux->common.adapter))
4084 gst_adapter_flush (demux->common.adapter, flush);
4086 return GST_FLOW_EOS;
4091 /* initializes @ebml with @bytes from input stream at current offset.
4092 * Returns EOS if insufficient available,
4093 * ERROR if too much was attempted to read. */
4094 static inline GstFlowReturn
4095 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4098 GstBuffer *buffer = NULL;
4099 GstFlowReturn ret = GST_FLOW_OK;
4101 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4103 ret = gst_matroska_demux_check_read_size (demux, bytes);
4104 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4105 if (!demux->streaming) {
4106 /* in pull mode, we can skip */
4107 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4108 ret = GST_FLOW_OVERFLOW;
4110 /* otherwise fatal */
4111 ret = GST_FLOW_ERROR;
4115 if (demux->streaming) {
4116 if (gst_adapter_available (demux->common.adapter) >= bytes)
4117 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4121 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4122 demux->common.offset, bytes, &buffer, NULL);
4123 if (G_LIKELY (buffer)) {
4124 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4125 demux->common.offset);
4126 demux->common.offset += bytes;
4133 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4136 gboolean seekable = FALSE;
4137 gint64 start = -1, stop = -1;
4139 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4140 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4141 GST_DEBUG_OBJECT (demux, "seeking query failed");
4145 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4147 /* try harder to query upstream size if we didn't get it the first time */
4148 if (seekable && stop == -1) {
4149 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4150 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4154 /* if upstream doesn't know the size, it's likely that it's not seekable in
4155 * practice even if it technically may be seekable */
4156 if (seekable && (start != 0 || stop <= start)) {
4157 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4162 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4163 G_GUINT64_FORMAT ")", seekable, start, stop);
4164 demux->seekable = seekable;
4166 gst_query_unref (query);
4169 static GstFlowReturn
4170 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4176 GstFlowReturn ret = GST_FLOW_OK;
4178 GST_WARNING_OBJECT (demux,
4179 "Found Cluster element before Tracks, searching Tracks");
4182 before_pos = demux->common.offset;
4184 /* Search Tracks element */
4186 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4187 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4188 if (ret != GST_FLOW_OK)
4191 if (id != GST_MATROSKA_ID_TRACKS) {
4192 /* we may be skipping large cluster here, so forego size check etc */
4193 /* ... but we can't skip undefined size; force error */
4194 if (length == G_MAXUINT64) {
4195 ret = gst_matroska_demux_check_read_size (demux, length);
4198 demux->common.offset += needed;
4199 demux->common.offset += length;
4204 /* will lead to track parsing ... */
4205 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4210 demux->common.offset = before_pos;
4215 #define GST_READ_CHECK(stmt) \
4217 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4218 if (ret == GST_FLOW_OVERFLOW) { \
4219 ret = GST_FLOW_OK; \
4225 static GstFlowReturn
4226 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4227 guint64 length, guint needed)
4229 GstEbmlRead ebml = { 0, };
4230 GstFlowReturn ret = GST_FLOW_OK;
4233 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4234 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4236 /* if we plan to read and parse this element, we need prefix (id + length)
4237 * and the contents */
4238 /* mind about overflow wrap-around when dealing with undefined size */
4240 if (G_LIKELY (length != G_MAXUINT64))
4243 switch (demux->common.state) {
4244 case GST_MATROSKA_READ_STATE_START:
4246 case GST_EBML_ID_HEADER:
4247 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4248 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4249 if (ret != GST_FLOW_OK)
4251 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4252 gst_matroska_demux_check_seekability (demux);
4255 goto invalid_header;
4259 case GST_MATROSKA_READ_STATE_SEGMENT:
4261 case GST_MATROSKA_ID_SEGMENT:
4262 /* eat segment prefix */
4263 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4264 GST_DEBUG_OBJECT (demux,
4265 "Found Segment start at offset %" G_GUINT64_FORMAT,
4266 demux->common.offset);
4267 /* seeks are from the beginning of the segment,
4268 * after the segment ID/length */
4269 demux->common.ebml_segment_start = demux->common.offset;
4270 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4273 GST_WARNING_OBJECT (demux,
4274 "Expected a Segment ID (0x%x), but received 0x%x!",
4275 GST_MATROSKA_ID_SEGMENT, id);
4276 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4280 case GST_MATROSKA_READ_STATE_SCANNING:
4281 if (id != GST_MATROSKA_ID_CLUSTER &&
4282 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4285 case GST_MATROSKA_READ_STATE_HEADER:
4286 case GST_MATROSKA_READ_STATE_DATA:
4287 case GST_MATROSKA_READ_STATE_SEEK:
4289 case GST_MATROSKA_ID_SEGMENTINFO:
4290 if (!demux->common.segmentinfo_parsed) {
4291 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4292 ret = gst_matroska_read_common_parse_info (&demux->common,
4293 GST_ELEMENT_CAST (demux), &ebml);
4295 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4298 case GST_MATROSKA_ID_TRACKS:
4299 if (!demux->tracks_parsed) {
4300 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4301 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4303 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4306 case GST_MATROSKA_ID_CLUSTER:
4307 if (G_UNLIKELY (!demux->tracks_parsed)) {
4308 if (demux->streaming) {
4309 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4310 goto not_streamable;
4312 ret = gst_matroska_demux_find_tracks (demux);
4313 if (!demux->tracks_parsed)
4317 if (G_UNLIKELY (demux->common.state
4318 == GST_MATROSKA_READ_STATE_HEADER)) {
4319 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4320 demux->first_cluster_offset = demux->common.offset;
4321 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4322 gst_element_no_more_pads (GST_ELEMENT (demux));
4323 /* send initial segment - we wait till we know the first
4324 incoming timestamp, so we can properly set the start of
4326 demux->need_segment = TRUE;
4328 demux->cluster_time = GST_CLOCK_TIME_NONE;
4329 demux->cluster_offset = demux->common.offset;
4330 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4331 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4332 " not found in Cluster, trying next Cluster's first block instead",
4334 demux->seek_block = 0;
4336 demux->seek_first = FALSE;
4337 /* record next cluster for recovery */
4338 if (read != G_MAXUINT64)
4339 demux->next_cluster_offset = demux->cluster_offset + read;
4340 /* eat cluster prefix */
4341 gst_matroska_demux_flush (demux, needed);
4343 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4347 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4348 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4350 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4351 demux->cluster_time = num;
4353 if (demux->common.element_index) {
4354 if (demux->common.element_index_writer_id == -1)
4355 gst_index_get_writer_id (demux->common.element_index,
4356 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4357 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4358 G_GUINT64_FORMAT " for writer id %d",
4359 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4360 demux->common.element_index_writer_id);
4361 gst_index_add_association (demux->common.element_index,
4362 demux->common.element_index_writer_id,
4363 GST_ASSOCIATION_FLAG_KEY_UNIT,
4364 GST_FORMAT_TIME, demux->cluster_time,
4365 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4370 case GST_MATROSKA_ID_BLOCKGROUP:
4371 if (!gst_matroska_demux_seek_block (demux))
4373 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4374 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4375 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4376 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4377 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4379 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4381 case GST_MATROSKA_ID_SIMPLEBLOCK:
4382 if (!gst_matroska_demux_seek_block (demux))
4384 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4385 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4386 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4387 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4388 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4390 case GST_MATROSKA_ID_ATTACHMENTS:
4391 if (!demux->common.attachments_parsed) {
4392 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4393 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4394 GST_ELEMENT_CAST (demux), &ebml);
4396 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4399 case GST_MATROSKA_ID_TAGS:
4400 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4401 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4402 GST_ELEMENT_CAST (demux), &ebml);
4404 case GST_MATROSKA_ID_CHAPTERS:
4405 if (!demux->common.chapters_parsed) {
4406 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4408 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4410 if (demux->common.toc) {
4411 gst_matroska_demux_send_event (demux,
4412 gst_event_new_toc (demux->common.toc, FALSE));
4415 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4417 case GST_MATROSKA_ID_SEEKHEAD:
4418 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4419 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4421 case GST_MATROSKA_ID_CUES:
4422 if (demux->common.index_parsed) {
4423 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4426 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4427 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4428 /* only push based; delayed index building */
4429 if (ret == GST_FLOW_OK
4430 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4433 GST_OBJECT_LOCK (demux);
4434 event = demux->seek_event;
4435 demux->seek_event = NULL;
4436 GST_OBJECT_UNLOCK (demux);
4439 /* unlikely to fail, since we managed to seek to this point */
4440 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
4442 /* resume data handling, main thread clear to seek again */
4443 GST_OBJECT_LOCK (demux);
4444 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4445 GST_OBJECT_UNLOCK (demux);
4448 case GST_MATROSKA_ID_POSITION:
4449 case GST_MATROSKA_ID_PREVSIZE:
4450 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4451 case GST_MATROSKA_ID_SILENTTRACKS:
4452 GST_DEBUG_OBJECT (demux,
4453 "Skipping Cluster subelement 0x%x - ignoring", id);
4457 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4458 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4464 if (ret == GST_FLOW_PARSE)
4468 gst_ebml_read_clear (&ebml);
4474 /* simply exit, maybe not enough data yet */
4475 /* no ebml to clear if read error */
4480 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4481 ("Failed to parse Element 0x%x", id));
4482 ret = GST_FLOW_ERROR;
4487 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4488 ("File layout does not permit streaming"));
4489 ret = GST_FLOW_ERROR;
4494 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4495 ("No Tracks element found"));
4496 ret = GST_FLOW_ERROR;
4501 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4502 ret = GST_FLOW_ERROR;
4507 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4508 ret = GST_FLOW_ERROR;
4514 gst_matroska_demux_loop (GstPad * pad)
4516 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4522 /* If we have to close a segment, send a new segment to do this now */
4523 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4524 if (G_UNLIKELY (demux->new_segment)) {
4525 gst_matroska_demux_send_event (demux, demux->new_segment);
4526 demux->new_segment = NULL;
4530 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4531 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4532 if (ret == GST_FLOW_EOS)
4534 if (ret != GST_FLOW_OK) {
4535 if (gst_matroska_demux_check_parse_error (demux))
4541 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4542 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4545 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4546 if (ret == GST_FLOW_EOS)
4548 if (ret != GST_FLOW_OK)
4551 /* check if we're at the end of a configured segment */
4552 if (G_LIKELY (demux->common.src->len)) {
4555 g_assert (demux->common.num_streams == demux->common.src->len);
4556 for (i = 0; i < demux->common.src->len; i++) {
4557 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4559 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4560 GST_TIME_ARGS (context->pos));
4561 if (context->eos == FALSE)
4565 GST_INFO_OBJECT (demux, "All streams are EOS");
4571 if (G_UNLIKELY (demux->common.offset ==
4572 gst_matroska_read_common_get_length (&demux->common))) {
4573 GST_LOG_OBJECT (demux, "Reached end of stream");
4583 if (demux->common.segment.rate < 0.0) {
4584 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4585 if (ret == GST_FLOW_OK)
4592 const gchar *reason = gst_flow_get_name (ret);
4593 gboolean push_eos = FALSE;
4595 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4596 gst_pad_pause_task (demux->common.sinkpad);
4598 if (ret == GST_FLOW_EOS) {
4599 /* perform EOS logic */
4601 /* If we were in the headers, make sure we send no-more-pads.
4602 This will ensure decodebin2 does not get stuck thinking
4603 the chain is not complete yet, and waiting indefinitely. */
4604 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4605 if (demux->common.src->len == 0) {
4606 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4607 ("No pads created"));
4609 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4610 ("Failed to finish reading headers"));
4612 gst_element_no_more_pads (GST_ELEMENT (demux));
4615 /* Close the segment, i.e. update segment stop with the duration
4616 * if no stop was set */
4617 if (GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
4618 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
4619 GST_CLOCK_TIME_IS_VALID (demux->common.segment.start) &&
4620 demux->last_stop_end > demux->common.segment.start) {
4621 GstSegment segment = demux->common.segment;
4624 segment.stop = demux->last_stop_end;
4625 event = gst_event_new_segment (&segment);
4626 gst_matroska_demux_send_event (demux, event);
4629 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4632 /* for segment playback we need to post when (in stream time)
4633 * we stopped, this is either stop (when set) or the duration. */
4634 if ((stop = demux->common.segment.stop) == -1)
4635 stop = demux->last_stop_end;
4637 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4638 gst_element_post_message (GST_ELEMENT (demux),
4639 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4641 gst_matroska_demux_send_event (demux,
4642 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4646 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4647 /* for fatal errors we post an error message */
4648 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4649 ("stream stopped, reason %s", reason));
4653 /* send EOS, and prevent hanging if no streams yet */
4654 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4655 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4656 (ret == GST_FLOW_EOS)) {
4657 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4658 (NULL), ("got eos but no streams (yet)"));
4666 * Create and push a flushing seek event upstream
4669 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset)
4674 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4677 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4678 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4679 GST_SEEK_TYPE_NONE, -1);
4681 res = gst_pad_push_event (demux->common.sinkpad, event);
4683 /* segment event will update offset */
4687 static GstFlowReturn
4688 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4690 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4692 GstFlowReturn ret = GST_FLOW_OK;
4697 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4698 GST_DEBUG_OBJECT (demux, "got DISCONT");
4699 gst_adapter_clear (demux->common.adapter);
4700 GST_OBJECT_LOCK (demux);
4701 gst_matroska_read_common_reset_streams (&demux->common,
4702 GST_CLOCK_TIME_NONE, FALSE);
4703 GST_OBJECT_UNLOCK (demux);
4706 gst_adapter_push (demux->common.adapter, buffer);
4710 available = gst_adapter_available (demux->common.adapter);
4712 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4713 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4714 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS))
4717 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4718 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4719 demux->common.offset, id, length, needed, available);
4721 if (needed > available)
4724 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4725 if (ret == GST_FLOW_EOS) {
4726 /* need more data */
4728 } else if (ret != GST_FLOW_OK) {
4735 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4738 gboolean res = TRUE;
4739 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4741 GST_DEBUG_OBJECT (demux,
4742 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4744 switch (GST_EVENT_TYPE (event)) {
4745 case GST_EVENT_SEGMENT:
4747 const GstSegment *segment;
4749 /* some debug output */
4750 gst_event_parse_segment (event, &segment);
4751 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4752 GST_DEBUG_OBJECT (demux,
4753 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4756 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4757 GST_DEBUG_OBJECT (demux, "still starting");
4761 /* we only expect a BYTE segment, e.g. following a seek */
4762 if (segment->format != GST_FORMAT_BYTES) {
4763 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4767 GST_DEBUG_OBJECT (demux, "clearing segment state");
4768 GST_OBJECT_LOCK (demux);
4769 /* clear current segment leftover */
4770 gst_adapter_clear (demux->common.adapter);
4771 /* and some streaming setup */
4772 demux->common.offset = segment->start;
4773 /* accumulate base based on current position */
4774 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4775 demux->common.segment.base +=
4776 (MAX (demux->common.segment.position, demux->stream_start_time)
4777 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4778 /* do not know where we are;
4779 * need to come across a cluster and generate segment */
4780 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4781 demux->cluster_time = GST_CLOCK_TIME_NONE;
4782 demux->cluster_offset = 0;
4783 demux->need_segment = TRUE;
4784 /* but keep some of the upstream segment */
4785 demux->common.segment.rate = segment->rate;
4786 /* also check if need to keep some of the requested seek position */
4787 if (demux->seek_offset == segment->start) {
4788 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4789 demux->common.segment.position = demux->requested_seek_time;
4791 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4793 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4794 demux->seek_offset = -1;
4795 GST_OBJECT_UNLOCK (demux);
4797 /* chain will send initial segment after pads have been added,
4798 * or otherwise come up with one */
4799 GST_DEBUG_OBJECT (demux, "eating event");
4800 gst_event_unref (event);
4806 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4807 gst_event_unref (event);
4808 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4809 (NULL), ("got eos and didn't receive a complete header object"));
4810 } else if (demux->common.num_streams == 0) {
4811 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4812 (NULL), ("got eos but no streams (yet)"));
4814 gst_matroska_demux_send_event (demux, event);
4818 case GST_EVENT_FLUSH_STOP:
4822 gst_adapter_clear (demux->common.adapter);
4823 GST_OBJECT_LOCK (demux);
4824 gst_matroska_read_common_reset_streams (&demux->common,
4825 GST_CLOCK_TIME_NONE, TRUE);
4826 dur = demux->common.segment.duration;
4827 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4828 demux->common.segment.duration = dur;
4829 demux->cluster_time = GST_CLOCK_TIME_NONE;
4830 demux->cluster_offset = 0;
4831 GST_OBJECT_UNLOCK (demux);
4835 res = gst_pad_event_default (pad, parent, event);
4843 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4845 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4847 gboolean pull_mode = FALSE;
4849 query = gst_query_new_scheduling ();
4851 if (gst_pad_peer_query (sinkpad, query))
4852 pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL);
4854 gst_query_unref (query);
4857 GST_DEBUG ("going to pull mode");
4858 demux->streaming = FALSE;
4859 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4861 GST_DEBUG ("going to push (streaming) mode");
4862 demux->streaming = TRUE;
4863 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4868 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4869 GstPadMode mode, gboolean active)
4872 case GST_PAD_MODE_PULL:
4874 /* if we have a scheduler we can start the task */
4875 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4878 gst_pad_stop_task (sinkpad);
4881 case GST_PAD_MODE_PUSH:
4889 gst_duration_to_fraction (guint64 duration, gint * dest_n, gint * dest_d)
4891 static const int common_den[] = { 1, 2, 3, 4, 1001 };
4896 for (i = 0; i < G_N_ELEMENTS (common_den); i++) {
4898 n = floor (0.5 + (d * 1e9) / duration);
4899 a = gst_util_uint64_scale_int (1000000000, d, n);
4900 if (duration >= a - 1 && duration <= a + 1) {
4905 gst_util_double_to_fraction (1e9 / duration, &n, &d);
4914 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4915 videocontext, const gchar * codec_id, guint8 * data, guint size,
4916 gchar ** codec_name, guint32 * riff_fourcc)
4918 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4919 GstCaps *caps = NULL;
4921 g_assert (videocontext != NULL);
4922 g_assert (codec_name != NULL);
4924 context->send_xiph_headers = FALSE;
4925 context->send_flac_headers = FALSE;
4926 context->send_speex_headers = FALSE;
4931 /* TODO: check if we have all codec types from matroska-ids.h
4932 * check if we have to do more special things with codec_private
4935 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4936 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4939 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4940 gst_riff_strf_vids *vids = NULL;
4943 GstBuffer *buf = NULL;
4945 vids = (gst_riff_strf_vids *) data;
4947 /* assure size is big enough */
4949 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4952 if (size < sizeof (gst_riff_strf_vids)) {
4953 vids = g_new (gst_riff_strf_vids, 1);
4954 memcpy (vids, data, size);
4957 /* little-endian -> byte-order */
4958 vids->size = GUINT32_FROM_LE (vids->size);
4959 vids->width = GUINT32_FROM_LE (vids->width);
4960 vids->height = GUINT32_FROM_LE (vids->height);
4961 vids->planes = GUINT16_FROM_LE (vids->planes);
4962 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4963 vids->compression = GUINT32_FROM_LE (vids->compression);
4964 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4965 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4966 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4967 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4968 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4970 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4971 gsize offset = sizeof (gst_riff_strf_vids);
4974 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
4975 size - offset), size - offset);
4979 *riff_fourcc = vids->compression;
4981 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4982 buf, NULL, codec_name);
4985 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4986 GST_FOURCC_ARGS (vids->compression));
4990 gst_buffer_unref (buf);
4992 if (vids != (gst_riff_strf_vids *) data)
4995 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4996 const gchar *format = NULL;
4998 switch (videocontext->fourcc) {
4999 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5000 *codec_name = g_strdup ("Raw planar YUV 4:2:0");
5003 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5004 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
5007 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5008 *codec_name = g_strdup ("Raw packed YUV 4:2:0");
5011 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5012 *codec_name = g_strdup ("Raw packed YUV 4:2:2");
5015 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5016 *codec_name = g_strdup ("Raw packed YUV 4:4:4 with alpha channel");
5021 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5022 GST_FOURCC_ARGS (videocontext->fourcc));
5026 caps = gst_caps_new_simple ("video/x-raw",
5027 "format", G_TYPE_STRING, format, NULL);
5028 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5029 caps = gst_caps_new_simple ("video/x-divx",
5030 "divxversion", G_TYPE_INT, 4, NULL);
5031 *codec_name = g_strdup ("MPEG-4 simple profile");
5032 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5033 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5035 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5036 "divxversion", G_TYPE_INT, 5, NULL),
5037 gst_structure_new ("video/x-xvid", NULL),
5038 gst_structure_new ("video/mpeg",
5039 "mpegversion", G_TYPE_INT, 4,
5040 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
5042 caps = gst_caps_new_simple ("video/mpeg",
5043 "mpegversion", G_TYPE_INT, 4,
5044 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5048 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5049 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5050 gst_buffer_unref (priv);
5052 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5053 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5055 *codec_name = g_strdup ("MPEG-4 advanced profile");
5056 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5058 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5059 "divxversion", G_TYPE_INT, 3, NULL),
5060 gst_structure_new ("video/x-msmpeg",
5061 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5063 caps = gst_caps_new_simple ("video/x-msmpeg",
5064 "msmpegversion", G_TYPE_INT, 43, NULL);
5065 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5066 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5067 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5070 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5075 caps = gst_caps_new_simple ("video/mpeg",
5076 "systemstream", G_TYPE_BOOLEAN, FALSE,
5077 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5078 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5079 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5080 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5081 caps = gst_caps_new_empty_simple ("image/jpeg");
5082 *codec_name = g_strdup ("Motion-JPEG");
5083 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5084 caps = gst_caps_new_empty_simple ("video/x-h264");
5088 /* First byte is the version, second is the profile indication, and third
5089 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5090 * level indication. */
5091 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5094 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5095 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5096 gst_buffer_unref (priv);
5098 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5099 "alignment", G_TYPE_STRING, "au", NULL);
5101 GST_WARNING ("No codec data found, assuming output is byte-stream");
5102 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5105 *codec_name = g_strdup ("H264");
5106 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5107 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5108 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5109 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5110 gint rmversion = -1;
5112 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5114 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5116 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5118 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5121 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5122 "rmversion", G_TYPE_INT, rmversion, NULL);
5123 GST_DEBUG ("data:%p, size:0x%x", data, size);
5124 /* We need to extract the extradata ! */
5125 if (data && (size >= 0x22)) {
5130 subformat = GST_READ_UINT32_BE (data + 0x1a);
5131 rformat = GST_READ_UINT32_BE (data + 0x1e);
5134 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5136 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5137 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5138 gst_buffer_unref (priv);
5141 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5142 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5143 caps = gst_caps_new_empty_simple ("video/x-theora");
5144 context->send_xiph_headers = TRUE;
5145 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5146 caps = gst_caps_new_empty_simple ("video/x-dirac");
5147 *codec_name = g_strdup_printf ("Dirac");
5148 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5149 caps = gst_caps_new_empty_simple ("video/x-vp8");
5150 *codec_name = g_strdup_printf ("On2 VP8");
5152 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5158 GstStructure *structure;
5160 for (i = 0; i < gst_caps_get_size (caps); i++) {
5161 structure = gst_caps_get_structure (caps, i);
5163 /* FIXME: use the real unit here! */
5164 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5165 videocontext->pixel_width,
5166 videocontext->pixel_height,
5167 videocontext->display_width, videocontext->display_height);
5169 /* pixel width and height are the w and h of the video in pixels */
5170 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5171 gint w = videocontext->pixel_width;
5172 gint h = videocontext->pixel_height;
5174 gst_structure_set (structure,
5175 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5178 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5181 if (videocontext->display_width <= 0)
5182 videocontext->display_width = videocontext->pixel_width;
5183 if (videocontext->display_height <= 0)
5184 videocontext->display_height = videocontext->pixel_height;
5186 /* calculate the pixel aspect ratio using the display and pixel w/h */
5187 n = videocontext->display_width * videocontext->pixel_height;
5188 d = videocontext->display_height * videocontext->pixel_width;
5189 GST_DEBUG ("setting PAR to %d/%d", n, d);
5190 gst_structure_set (structure, "pixel-aspect-ratio",
5192 videocontext->display_width * videocontext->pixel_height,
5193 videocontext->display_height * videocontext->pixel_width, NULL);
5196 if (videocontext->default_fps > 0.0) {
5197 GValue fps_double = { 0, };
5198 GValue fps_fraction = { 0, };
5200 g_value_init (&fps_double, G_TYPE_DOUBLE);
5201 g_value_init (&fps_fraction, GST_TYPE_FRACTION);
5202 g_value_set_double (&fps_double, videocontext->default_fps);
5203 g_value_transform (&fps_double, &fps_fraction);
5205 GST_DEBUG ("using default fps %f", videocontext->default_fps);
5207 gst_structure_set_value (structure, "framerate", &fps_fraction);
5208 g_value_unset (&fps_double);
5209 g_value_unset (&fps_fraction);
5210 } else if (context->default_duration > 0) {
5213 gst_duration_to_fraction (context->default_duration, &fps_n, &fps_d);
5215 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5216 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5218 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5219 fps_n, fps_d, NULL);
5221 /* sort of a hack to get most codecs to support,
5222 * even if the default_duration is missing */
5223 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5227 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5228 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5232 caps = gst_caps_simplify (caps);
5239 * Some AAC specific code... *sigh*
5240 * FIXME: maybe we should use '15' and code the sample rate explicitly
5241 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5245 aac_rate_idx (gint rate)
5249 else if (75132 <= rate)
5251 else if (55426 <= rate)
5253 else if (46009 <= rate)
5255 else if (37566 <= rate)
5257 else if (27713 <= rate)
5259 else if (23004 <= rate)
5261 else if (18783 <= rate)
5263 else if (13856 <= rate)
5265 else if (11502 <= rate)
5267 else if (9391 <= rate)
5274 aac_profile_idx (const gchar * codec_id)
5278 if (strlen (codec_id) <= 12)
5280 else if (!strncmp (&codec_id[12], "MAIN", 4))
5282 else if (!strncmp (&codec_id[12], "LC", 2))
5284 else if (!strncmp (&codec_id[12], "SSR", 3))
5292 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5295 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5296 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5297 gchar ** codec_name, guint16 * riff_audio_fmt)
5299 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5300 GstCaps *caps = NULL;
5302 g_assert (audiocontext != NULL);
5303 g_assert (codec_name != NULL);
5306 *riff_audio_fmt = 0;
5308 context->send_xiph_headers = FALSE;
5309 context->send_flac_headers = FALSE;
5310 context->send_speex_headers = FALSE;
5312 /* TODO: check if we have all codec types from matroska-ids.h
5313 * check if we have to do more special things with codec_private
5314 * check if we need bitdepth in different places too
5315 * implement channel position magic
5317 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5318 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5319 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5320 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5323 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5324 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5325 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5328 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5330 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5335 caps = gst_caps_new_simple ("audio/mpeg",
5336 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5337 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5338 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5339 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5342 GstAudioFormat format;
5344 sign = (audiocontext->bitdepth != 8);
5345 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5346 endianness = G_BIG_ENDIAN;
5348 endianness = G_LITTLE_ENDIAN;
5350 format = gst_audio_format_build_integer (sign, endianness,
5351 audiocontext->bitdepth, audiocontext->bitdepth);
5353 /* FIXME: Channel mask and reordering */
5354 caps = gst_caps_new_simple ("audio/x-raw",
5355 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5356 "layout", G_TYPE_STRING, "interleaved", NULL);
5358 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5359 audiocontext->bitdepth);
5360 context->alignment = audiocontext->bitdepth / 8;
5361 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5362 const gchar *format;
5363 if (audiocontext->bitdepth == 32)
5367 /* FIXME: Channel mask and reordering */
5368 caps = gst_caps_new_simple ("audio/x-raw",
5369 "format", G_TYPE_STRING, format,
5370 "layout", G_TYPE_STRING, "interleaved", NULL);
5371 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5372 audiocontext->bitdepth);
5373 context->alignment = audiocontext->bitdepth / 8;
5374 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5375 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5376 caps = gst_caps_new_simple ("audio/x-ac3",
5377 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5378 *codec_name = g_strdup ("AC-3 audio");
5379 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5380 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5381 caps = gst_caps_new_simple ("audio/x-eac3",
5382 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5383 *codec_name = g_strdup ("E-AC-3 audio");
5384 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5385 caps = gst_caps_new_empty_simple ("audio/x-dts");
5386 *codec_name = g_strdup ("DTS audio");
5387 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5388 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5389 context->send_xiph_headers = TRUE;
5390 /* vorbis decoder does tags */
5391 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5392 caps = gst_caps_new_empty_simple ("audio/x-flac");
5393 context->send_flac_headers = TRUE;
5394 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5395 caps = gst_caps_new_empty_simple ("audio/x-speex");
5396 context->send_speex_headers = TRUE;
5397 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5398 gst_riff_strf_auds auds;
5401 GstBuffer *codec_data;
5403 /* little-endian -> byte-order */
5404 auds.format = GST_READ_UINT16_LE (data);
5405 auds.channels = GST_READ_UINT16_LE (data + 2);
5406 auds.rate = GST_READ_UINT32_LE (data + 4);
5407 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5408 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5409 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5411 /* 18 is the waveformatex size */
5412 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5413 data + 18, auds.bits_per_sample, 0, auds.bits_per_sample, NULL, NULL);
5416 *riff_audio_fmt = auds.format;
5418 /* FIXME: Handle reorder map */
5419 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5420 codec_data, codec_name, NULL);
5421 gst_buffer_unref (codec_data);
5424 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5427 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5428 GstBuffer *priv = NULL;
5430 gint rate_idx, profile;
5431 guint8 *data = NULL;
5433 /* unspecified AAC profile with opaque private codec data */
5434 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5435 if (context->codec_priv_size >= 2) {
5436 guint obj_type, freq_index, explicit_freq_bytes = 0;
5438 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5440 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5441 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5442 if (freq_index == 15)
5443 explicit_freq_bytes = 3;
5444 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5445 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5446 context->codec_priv_size), context->codec_priv_size);
5447 /* assume SBR if samplerate <= 24kHz */
5448 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5449 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5450 audiocontext->samplerate *= 2;
5453 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5454 /* this is pretty broken;
5455 * maybe we need to make up some default private,
5456 * or maybe ADTS data got dumped in.
5457 * Let's set up some private data now, and check actual data later */
5458 /* just try this and see what happens ... */
5459 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5460 context->postprocess_frame = gst_matroska_demux_check_aac;
5464 /* make up decoder-specific data if it is not supplied */
5468 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5469 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5471 rate_idx = aac_rate_idx (audiocontext->samplerate);
5472 profile = aac_profile_idx (codec_id);
5474 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5475 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5477 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5478 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5480 gst_buffer_unmap (priv, &map);
5481 gst_buffer_set_size (priv, 2);
5482 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5483 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5486 if (g_strrstr (codec_id, "SBR")) {
5487 /* HE-AAC (aka SBR AAC) */
5488 audiocontext->samplerate *= 2;
5489 rate_idx = aac_rate_idx (audiocontext->samplerate);
5490 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5491 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5492 data[4] = (1 << 7) | (rate_idx << 3);
5493 gst_buffer_unmap (priv, &map);
5495 gst_buffer_unmap (priv, &map);
5496 gst_buffer_set_size (priv, 2);
5499 gst_buffer_unmap (priv, &map);
5500 gst_buffer_unref (priv);
5502 GST_ERROR ("Unknown AAC profile and no codec private data");
5507 caps = gst_caps_new_simple ("audio/mpeg",
5508 "mpegversion", G_TYPE_INT, mpegversion,
5509 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5510 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5511 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5512 gst_buffer_unref (priv);
5514 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5515 caps = gst_caps_new_simple ("audio/x-tta",
5516 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5517 *codec_name = g_strdup ("TTA audio");
5518 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5519 caps = gst_caps_new_simple ("audio/x-wavpack",
5520 "width", G_TYPE_INT, audiocontext->bitdepth,
5521 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5522 *codec_name = g_strdup ("Wavpack audio");
5523 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5524 audiocontext->wvpk_block_index = 0;
5525 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5526 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5527 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5528 gint raversion = -1;
5530 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5532 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5537 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5538 "raversion", G_TYPE_INT, raversion, NULL);
5539 /* Extract extra information from caps, mapping varies based on codec */
5540 if (data && (size >= 0x50)) {
5547 guint extra_data_size;
5549 GST_ERROR ("real audio raversion:%d", raversion);
5550 if (raversion == 8) {
5552 flavor = GST_READ_UINT16_BE (data + 22);
5553 packet_size = GST_READ_UINT32_BE (data + 24);
5554 height = GST_READ_UINT16_BE (data + 40);
5555 leaf_size = GST_READ_UINT16_BE (data + 44);
5556 sample_width = GST_READ_UINT16_BE (data + 58);
5557 extra_data_size = GST_READ_UINT32_BE (data + 74);
5560 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5561 flavor, packet_size, height, leaf_size, sample_width,
5563 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5564 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5565 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5567 if ((size - 78) >= extra_data_size) {
5568 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5570 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5571 gst_buffer_unref (priv);
5576 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5577 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5578 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5579 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5580 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5581 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5582 *codec_name = g_strdup ("Real Audio Lossless");
5583 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5584 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5585 *codec_name = g_strdup ("Sony ATRAC3");
5587 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5592 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5595 for (i = 0; i < gst_caps_get_size (caps); i++) {
5596 gst_structure_set (gst_caps_get_structure (caps, i),
5597 "channels", G_TYPE_INT, audiocontext->channels,
5598 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5602 caps = gst_caps_simplify (caps);
5609 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5610 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5612 GstCaps *caps = NULL;
5613 GstMatroskaTrackContext *context =
5614 (GstMatroskaTrackContext *) subtitlecontext;
5616 /* for backwards compatibility */
5617 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5618 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5619 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5620 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5621 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5622 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5623 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5624 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5626 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5627 * Check if we have to do something with codec_private */
5628 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5629 /* well, plain text simply does not have a lot of markup ... */
5630 caps = gst_caps_new_empty_simple ("text/x-pango-markup");
5631 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5632 subtitlecontext->check_markup = TRUE;
5633 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5634 caps = gst_caps_new_empty_simple ("application/x-ssa");
5635 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5636 subtitlecontext->check_markup = FALSE;
5637 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5638 caps = gst_caps_new_empty_simple ("application/x-ass");
5639 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5640 subtitlecontext->check_markup = FALSE;
5641 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5642 caps = gst_caps_new_empty_simple ("application/x-usf");
5643 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5644 subtitlecontext->check_markup = FALSE;
5645 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5646 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5647 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5648 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5649 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5650 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5651 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5652 context->send_xiph_headers = TRUE;
5654 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5655 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5658 if (data != NULL && size > 0) {
5661 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5662 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5663 gst_buffer_unref (buf);
5671 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5673 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5675 GST_OBJECT_LOCK (demux);
5676 if (demux->common.element_index)
5677 gst_object_unref (demux->common.element_index);
5678 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5679 GST_OBJECT_UNLOCK (demux);
5680 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5681 demux->common.element_index);
5685 gst_matroska_demux_get_index (GstElement * element)
5687 GstIndex *result = NULL;
5688 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5690 GST_OBJECT_LOCK (demux);
5691 if (demux->common.element_index)
5692 result = gst_object_ref (demux->common.element_index);
5693 GST_OBJECT_UNLOCK (demux);
5695 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5701 static GstStateChangeReturn
5702 gst_matroska_demux_change_state (GstElement * element,
5703 GstStateChange transition)
5705 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5706 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5708 /* handle upwards state changes here */
5709 switch (transition) {
5714 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5716 /* handle downwards state changes */
5717 switch (transition) {
5718 case GST_STATE_CHANGE_PAUSED_TO_READY:
5719 gst_matroska_demux_reset (GST_ELEMENT (demux));
5729 gst_matroska_demux_set_property (GObject * object,
5730 guint prop_id, const GValue * value, GParamSpec * pspec)
5732 GstMatroskaDemux *demux;
5734 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5735 demux = GST_MATROSKA_DEMUX (object);
5738 case ARG_MAX_GAP_TIME:
5739 GST_OBJECT_LOCK (demux);
5740 demux->max_gap_time = g_value_get_uint64 (value);
5741 GST_OBJECT_UNLOCK (demux);
5744 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5750 gst_matroska_demux_get_property (GObject * object,
5751 guint prop_id, GValue * value, GParamSpec * pspec)
5753 GstMatroskaDemux *demux;
5755 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5756 demux = GST_MATROSKA_DEMUX (object);
5759 case ARG_MAX_GAP_TIME:
5760 GST_OBJECT_LOCK (demux);
5761 g_value_set_uint64 (value, demux->max_gap_time);
5762 GST_OBJECT_UNLOCK (demux);
5765 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5771 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5775 /* parser helper separate debug */
5776 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5777 0, "EBML stream helper class");
5779 /* create an elementfactory for the matroska_demux element */
5780 if (!gst_element_register (plugin, "matroskademux",
5781 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))