1 /* GStreamer Matroska muxer/demuxer
2 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3 * (c) 2006 Tim-Philipp Müller <tim centricular net>
4 * (c) 2008 Sebastian Dröge <slomo@circular-chaos.org>
5 * (c) 2011 Debarshi Ray <rishi@gnu.org>
7 * matroska-demux.c: matroska file/stream demuxer
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
25 /* TODO: check CRC32 if present
26 * TODO: there can be a segment after the first segment. Handle like
27 * chained oggs. Fixes #334082
28 * TODO: Test samples: http://www.matroska.org/samples/matrix/index.html
29 * http://samples.mplayerhq.hu/Matroska/
30 * TODO: check if demuxing is done correct for all codecs according to spec
31 * TODO: seeking with incomplete or without CUE
35 * SECTION:element-matroskademux
37 * matroskademux demuxes a Matroska file into the different contained streams.
40 * <title>Example launch line</title>
42 * gst-launch-1.0 -v filesrc location=/path/to/mkv ! matroskademux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
43 * ]| This pipeline demuxes a Matroska file and outputs the contained Vorbis audio.
54 #include <glib/gprintf.h>
56 /* For AVI compatibility mode
57 and for fourcc stuff */
58 #include <gst/riff/riff-read.h>
59 #include <gst/riff/riff-ids.h>
60 #include <gst/riff/riff-media.h>
62 #include <gst/audio/audio.h>
63 #include <gst/tag/tag.h>
64 #include <gst/pbutils/pbutils.h>
65 #include <gst/video/video.h>
67 #include "matroska-demux.h"
68 #include "matroska-ids.h"
70 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
71 #define GST_CAT_DEFAULT matroskademux_debug
73 #define DEBUG_ELEMENT_START(demux, ebml, element) \
74 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
75 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
77 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
78 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
79 " finished with '%s'", gst_flow_get_name (ret))
89 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
91 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
94 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
95 "video/x-matroska-3d; audio/webm; video/webm")
98 /* TODO: fill in caps! */
100 static GstStaticPadTemplate audio_src_templ =
101 GST_STATIC_PAD_TEMPLATE ("audio_%u",
104 GST_STATIC_CAPS ("ANY")
107 static GstStaticPadTemplate video_src_templ =
108 GST_STATIC_PAD_TEMPLATE ("video_%u",
111 GST_STATIC_CAPS ("ANY")
114 static GstStaticPadTemplate subtitle_src_templ =
115 GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
118 GST_STATIC_CAPS ("text/x-raw, format=pango-markup; application/x-ssa; "
119 "application/x-ass;application/x-usf; subpicture/x-dvd; "
120 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
123 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
124 guint32 id, guint64 length, guint needed);
126 /* element functions */
127 static void gst_matroska_demux_loop (GstPad * pad);
129 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
131 static gboolean gst_matroska_demux_element_query (GstElement * element,
135 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad,
137 static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
138 GstObject * parent, GstPadMode mode, gboolean active);
140 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
141 GstPad * pad, GstEvent * event);
142 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
143 GstObject * parent, GstEvent * event);
144 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
145 GstObject * parent, GstQuery * query);
147 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
148 GstObject * parent, GstEvent * event);
149 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
150 GstObject * object, GstBuffer * buffer);
152 static GstStateChangeReturn
153 gst_matroska_demux_change_state (GstElement * element,
154 GstStateChange transition);
157 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
158 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
162 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
163 * videocontext, const gchar * codec_id, guint8 * data, guint size,
164 gchar ** codec_name, guint32 * riff_fourcc);
165 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
166 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
167 gchar ** codec_name, guint16 * riff_audio_fmt);
169 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
170 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
173 static void gst_matroska_demux_reset (GstElement * element);
174 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
175 gdouble rate, guint64 offset, guint32 seqnum);
177 /* gobject functions */
178 static void gst_matroska_demux_set_property (GObject * object,
179 guint prop_id, const GValue * value, GParamSpec * pspec);
180 static void gst_matroska_demux_get_property (GObject * object,
181 guint prop_id, GValue * value, GParamSpec * pspec);
183 GType gst_matroska_demux_get_type (void);
184 #define parent_class gst_matroska_demux_parent_class
185 G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
188 gst_matroska_demux_finalize (GObject * object)
190 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
192 gst_matroska_read_common_finalize (&demux->common);
193 gst_flow_combiner_free (demux->flowcombiner);
194 G_OBJECT_CLASS (parent_class)->finalize (object);
198 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
200 GObjectClass *gobject_class = (GObjectClass *) klass;
201 GstElementClass *gstelement_class = (GstElementClass *) klass;
203 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
206 gobject_class->finalize = gst_matroska_demux_finalize;
208 gobject_class->get_property = gst_matroska_demux_get_property;
209 gobject_class->set_property = gst_matroska_demux_set_property;
211 g_object_class_install_property (gobject_class, PROP_MAX_GAP_TIME,
212 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
213 "The demuxer sends out segment events for skipping "
214 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
215 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
217 gstelement_class->change_state =
218 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
219 gstelement_class->send_event =
220 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
221 gstelement_class->query =
222 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
224 gstelement_class->set_index =
225 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
226 gstelement_class->get_index =
227 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
230 gst_element_class_add_pad_template (gstelement_class,
231 gst_static_pad_template_get (&video_src_templ));
232 gst_element_class_add_pad_template (gstelement_class,
233 gst_static_pad_template_get (&audio_src_templ));
234 gst_element_class_add_pad_template (gstelement_class,
235 gst_static_pad_template_get (&subtitle_src_templ));
236 gst_element_class_add_pad_template (gstelement_class,
237 gst_static_pad_template_get (&sink_templ));
239 gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
241 "Demuxes Matroska/WebM streams into video/audio/subtitles",
242 "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
246 gst_matroska_demux_init (GstMatroskaDemux * demux)
248 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
250 gst_pad_set_activate_function (demux->common.sinkpad,
251 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
252 gst_pad_set_activatemode_function (demux->common.sinkpad,
253 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
254 gst_pad_set_chain_function (demux->common.sinkpad,
255 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
256 gst_pad_set_event_function (demux->common.sinkpad,
257 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
258 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
260 /* init defaults for common read context */
261 gst_matroska_read_common_init (&demux->common);
263 /* property defaults */
264 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
266 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
268 demux->flowcombiner = gst_flow_combiner_new ();
271 gst_matroska_demux_reset (GST_ELEMENT (demux));
275 gst_matroska_demux_reset (GstElement * element)
277 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
279 GST_DEBUG_OBJECT (demux, "Resetting state");
281 gst_matroska_read_common_reset (GST_ELEMENT (demux), &demux->common);
283 demux->num_a_streams = 0;
284 demux->num_t_streams = 0;
285 demux->num_v_streams = 0;
287 demux->have_group_id = FALSE;
288 demux->group_id = G_MAXUINT;
291 demux->tracks_parsed = FALSE;
293 if (demux->clusters) {
294 g_array_free (demux->clusters, TRUE);
295 demux->clusters = NULL;
298 g_list_foreach (demux->seek_parsed,
299 (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
300 g_list_free (demux->seek_parsed);
301 demux->seek_parsed = NULL;
303 demux->last_stop_end = GST_CLOCK_TIME_NONE;
304 demux->seek_block = 0;
305 demux->stream_start_time = GST_CLOCK_TIME_NONE;
306 demux->to_time = GST_CLOCK_TIME_NONE;
307 demux->cluster_time = GST_CLOCK_TIME_NONE;
308 demux->cluster_offset = 0;
309 demux->next_cluster_offset = 0;
310 demux->index_offset = 0;
311 demux->seekable = FALSE;
312 demux->need_segment = FALSE;
313 demux->segment_seqnum = 0;
314 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
315 demux->seek_offset = -1;
316 demux->building_index = FALSE;
317 if (demux->seek_event) {
318 gst_event_unref (demux->seek_event);
319 demux->seek_event = NULL;
322 demux->seek_index = NULL;
323 demux->seek_entry = 0;
325 if (demux->new_segment) {
326 gst_event_unref (demux->new_segment);
327 demux->new_segment = NULL;
330 demux->invalid_duration = FALSE;
332 demux->cached_length = G_MAXUINT64;
334 gst_flow_combiner_clear (demux->flowcombiner);
338 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
344 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
346 GST_DEBUG ("decoding buffer %p", buf);
348 gst_buffer_map (buf, &map, GST_MAP_READ);
352 g_return_val_if_fail (size > 0, buf);
354 if (gst_matroska_decode_data (context->encodings, &data, &size,
355 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
356 gst_buffer_unmap (buf, &map);
357 gst_buffer_unref (buf);
358 return gst_buffer_new_wrapped (data, size);
360 GST_DEBUG ("decode data failed");
361 gst_buffer_unmap (buf, &map);
362 gst_buffer_unref (buf);
368 gst_matroska_demux_add_stream_headers_to_caps (GstMatroskaDemux * demux,
369 GstBufferList * list, GstCaps * caps)
372 GValue arr_val = G_VALUE_INIT;
373 GValue buf_val = G_VALUE_INIT;
376 g_assert (gst_caps_is_writable (caps));
378 g_value_init (&arr_val, GST_TYPE_ARRAY);
379 g_value_init (&buf_val, GST_TYPE_BUFFER);
381 num = gst_buffer_list_length (list);
382 for (i = 0; i < num; ++i) {
383 g_value_set_boxed (&buf_val, gst_buffer_list_get (list, i));
384 gst_value_array_append_value (&arr_val, &buf_val);
387 s = gst_caps_get_structure (caps, 0);
388 gst_structure_take_value (s, "streamheader", &arr_val);
389 g_value_unset (&buf_val);
393 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
395 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
396 GstMatroskaTrackContext *context;
397 GstPadTemplate *templ = NULL;
398 GstStreamFlags stream_flags;
399 GstCaps *caps = NULL;
400 GstTagList *cached_taglist;
401 gchar *padname = NULL;
403 guint32 id, riff_fourcc = 0;
404 guint16 riff_audio_fmt = 0;
405 GstEvent *stream_start;
409 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
411 /* start with the master */
412 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
413 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
417 /* allocate generic... if we know the type, we'll g_renew()
418 * with the precise type */
419 context = g_new0 (GstMatroskaTrackContext, 1);
420 g_ptr_array_add (demux->common.src, context);
421 context->index = demux->common.num_streams;
422 context->index_writer_id = -1;
423 context->type = 0; /* no type yet */
424 context->default_duration = 0;
426 context->set_discont = TRUE;
427 context->timecodescale = 1.0;
429 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
430 GST_MATROSKA_TRACK_LACING;
431 context->from_time = GST_CLOCK_TIME_NONE;
432 context->from_offset = -1;
433 context->to_offset = G_MAXINT64;
434 context->alignment = 1;
435 context->dts_only = FALSE;
436 context->intra_only = FALSE;
437 context->tags = gst_tag_list_new_empty ();
438 demux->common.num_streams++;
439 g_assert (demux->common.src->len == demux->common.num_streams);
441 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
443 /* try reading the trackentry headers */
444 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
445 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
449 /* track number (unique stream ID) */
450 case GST_MATROSKA_ID_TRACKNUMBER:{
453 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
457 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
458 ret = GST_FLOW_ERROR;
460 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
462 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
463 " is not unique", num);
464 ret = GST_FLOW_ERROR;
468 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
472 /* track UID (unique identifier) */
473 case GST_MATROSKA_ID_TRACKUID:{
476 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
480 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
481 ret = GST_FLOW_ERROR;
485 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
490 /* track type (video, audio, combined, subtitle, etc.) */
491 case GST_MATROSKA_ID_TRACKTYPE:{
494 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
498 if (context->type != 0 && context->type != track_type) {
499 GST_WARNING_OBJECT (demux,
500 "More than one tracktype defined in a TrackEntry - skipping");
502 } else if (track_type < 1 || track_type > 254) {
503 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
508 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
510 /* ok, so we're actually going to reallocate this thing */
511 switch (track_type) {
512 case GST_MATROSKA_TRACK_TYPE_VIDEO:
513 gst_matroska_track_init_video_context (&context);
515 case GST_MATROSKA_TRACK_TYPE_AUDIO:
516 gst_matroska_track_init_audio_context (&context);
518 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
519 gst_matroska_track_init_subtitle_context (&context);
521 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
522 case GST_MATROSKA_TRACK_TYPE_LOGO:
523 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
524 case GST_MATROSKA_TRACK_TYPE_CONTROL:
526 GST_WARNING_OBJECT (demux,
527 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
532 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
537 /* tracktype specific stuff for video */
538 case GST_MATROSKA_ID_TRACKVIDEO:{
539 GstMatroskaTrackVideoContext *videocontext;
541 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
543 if (!gst_matroska_track_init_video_context (&context)) {
544 GST_WARNING_OBJECT (demux,
545 "TrackVideo element in non-video track - ignoring track");
546 ret = GST_FLOW_ERROR;
548 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
551 videocontext = (GstMatroskaTrackVideoContext *) context;
552 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
555 while (ret == GST_FLOW_OK &&
556 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
557 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
561 /* Should be one level up but some broken muxers write it here. */
562 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
565 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
569 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
573 GST_DEBUG_OBJECT (demux,
574 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
575 context->default_duration = num;
579 /* video framerate */
580 /* NOTE: This one is here only for backward compatibility.
581 * Use _TRACKDEFAULDURATION one level up. */
582 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
585 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
589 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
593 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
594 if (context->default_duration == 0)
595 context->default_duration =
596 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
597 videocontext->default_fps = num;
601 /* width of the size to display the video at */
602 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
605 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
609 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
613 GST_DEBUG_OBJECT (demux,
614 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
615 videocontext->display_width = num;
619 /* height of the size to display the video at */
620 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
623 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
627 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
631 GST_DEBUG_OBJECT (demux,
632 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
633 videocontext->display_height = num;
637 /* width of the video in the file */
638 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
641 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
645 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
649 GST_DEBUG_OBJECT (demux,
650 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
651 videocontext->pixel_width = num;
655 /* height of the video in the file */
656 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
659 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
663 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
667 GST_DEBUG_OBJECT (demux,
668 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
669 videocontext->pixel_height = num;
673 /* whether the video is interlaced */
674 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
677 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
681 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
683 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
684 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
685 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
690 /* aspect ratio behaviour */
691 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
694 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
697 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
698 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
699 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
700 GST_WARNING_OBJECT (demux,
701 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
704 GST_DEBUG_OBJECT (demux,
705 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
706 videocontext->asr_mode = num;
710 /* colourspace (only matters for raw video) fourcc */
711 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
716 gst_ebml_read_binary (ebml, &id, &data,
717 &datalen)) != GST_FLOW_OK)
722 GST_WARNING_OBJECT (demux,
723 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
728 memcpy (&videocontext->fourcc, data, 4);
729 GST_DEBUG_OBJECT (demux,
730 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
731 GST_FOURCC_ARGS (videocontext->fourcc));
735 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
739 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
742 GST_DEBUG_OBJECT (demux, "StereoMode: %" G_GUINT64_FORMAT, num);
745 case GST_MATROSKA_STEREO_MODE_SBS_RL:
746 videocontext->multiview_flags =
747 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
749 case GST_MATROSKA_STEREO_MODE_SBS_LR:
750 videocontext->multiview_mode =
751 GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
753 case GST_MATROSKA_STEREO_MODE_TB_RL:
754 videocontext->multiview_flags =
755 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
757 case GST_MATROSKA_STEREO_MODE_TB_LR:
758 videocontext->multiview_mode =
759 GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM;
761 case GST_MATROSKA_STEREO_MODE_CHECKER_RL:
762 videocontext->multiview_flags =
763 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
765 case GST_MATROSKA_STEREO_MODE_CHECKER_LR:
766 videocontext->multiview_mode =
767 GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD;
769 case GST_MATROSKA_STEREO_MODE_FBF_RL:
770 videocontext->multiview_flags =
771 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
773 case GST_MATROSKA_STEREO_MODE_FBF_LR:
774 videocontext->multiview_mode =
775 GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
776 /* FIXME: In frame-by-frame mode, left/right frame buffers are
777 * laced within one block, and we'll need to apply FIRST_IN_BUNDLE
778 * accordingly. See http://www.matroska.org/technical/specs/index.html#StereoMode */
779 GST_FIXME_OBJECT (demux,
780 "Frame-by-frame stereoscopic mode not fully implemented");
787 GST_WARNING_OBJECT (demux,
788 "Unknown TrackVideo subelement 0x%x - ignoring", id);
790 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
791 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
792 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
793 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
794 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
795 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
796 ret = gst_ebml_read_skip (ebml);
801 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
805 /* tracktype specific stuff for audio */
806 case GST_MATROSKA_ID_TRACKAUDIO:{
807 GstMatroskaTrackAudioContext *audiocontext;
809 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
811 if (!gst_matroska_track_init_audio_context (&context)) {
812 GST_WARNING_OBJECT (demux,
813 "TrackAudio element in non-audio track - ignoring track");
814 ret = GST_FLOW_ERROR;
818 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
821 audiocontext = (GstMatroskaTrackAudioContext *) context;
822 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
825 while (ret == GST_FLOW_OK &&
826 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
827 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
832 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
835 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
840 GST_WARNING_OBJECT (demux,
841 "Invalid TrackAudioSamplingFrequency %lf", num);
845 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
846 audiocontext->samplerate = num;
851 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
854 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
858 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
862 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
864 audiocontext->bitdepth = num;
869 case GST_MATROSKA_ID_AUDIOCHANNELS:{
872 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
876 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
880 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
882 audiocontext->channels = num;
887 GST_WARNING_OBJECT (demux,
888 "Unknown TrackAudio subelement 0x%x - ignoring", id);
890 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
891 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
892 ret = gst_ebml_read_skip (ebml);
897 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
902 /* codec identifier */
903 case GST_MATROSKA_ID_CODECID:{
906 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
909 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
910 context->codec_id = text;
914 /* codec private data */
915 case GST_MATROSKA_ID_CODECPRIVATE:{
920 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
923 context->codec_priv = data;
924 context->codec_priv_size = size;
926 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
931 /* name of the codec */
932 case GST_MATROSKA_ID_CODECNAME:{
935 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
938 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
939 context->codec_name = text;
944 case GST_MATROSKA_ID_CODECDELAY:{
947 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
950 context->codec_delay = num;
952 GST_DEBUG_OBJECT (demux, "CodecDelay: %" GST_TIME_FORMAT,
953 GST_TIME_ARGS (num));
958 case GST_MATROSKA_ID_SEEKPREROLL:{
961 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
964 context->seek_preroll = num;
966 GST_DEBUG_OBJECT (demux, "SeekPreroll: %" GST_TIME_FORMAT,
967 GST_TIME_ARGS (num));
971 /* name of this track */
972 case GST_MATROSKA_ID_TRACKNAME:{
975 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
978 context->name = text;
979 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
983 /* language (matters for audio/subtitles, mostly) */
984 case GST_MATROSKA_ID_TRACKLANGUAGE:{
987 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
991 context->language = text;
994 if (strlen (context->language) >= 4 && context->language[3] == '-')
995 context->language[3] = '\0';
997 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
998 GST_STR_NULL (context->language));
1002 /* whether this is actually used */
1003 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1006 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1010 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1012 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1014 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1015 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1019 /* whether it's the default for this track type */
1020 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1023 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1027 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1029 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1031 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1032 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
1036 /* whether the track must be used during playback */
1037 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1040 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1044 context->flags |= GST_MATROSKA_TRACK_FORCED;
1046 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1048 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1049 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
1053 /* lacing (like MPEG, where blocks don't end/start on frame
1055 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1058 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1062 context->flags |= GST_MATROSKA_TRACK_LACING;
1064 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1066 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1067 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
1071 /* default length (in time) of one data block in this track */
1072 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1075 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1080 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1084 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1086 context->default_duration = num;
1090 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1091 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1096 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1099 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1103 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1107 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1108 context->timecodescale = num;
1113 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1116 /* we ignore these because they're nothing useful (i.e. crap)
1117 * or simply not implemented yet. */
1118 case GST_MATROSKA_ID_TRACKMINCACHE:
1119 case GST_MATROSKA_ID_TRACKMAXCACHE:
1120 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1121 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1122 case GST_MATROSKA_ID_TRACKOVERLAY:
1123 case GST_MATROSKA_ID_TRACKTRANSLATE:
1124 case GST_MATROSKA_ID_TRACKOFFSET:
1125 case GST_MATROSKA_ID_CODECSETTINGS:
1126 case GST_MATROSKA_ID_CODECINFOURL:
1127 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1128 case GST_MATROSKA_ID_CODECDECODEALL:
1129 ret = gst_ebml_read_skip (ebml);
1134 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1136 /* Decode codec private data if necessary */
1137 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1138 && context->codec_priv_size > 0) {
1139 if (!gst_matroska_decode_data (context->encodings,
1140 &context->codec_priv, &context->codec_priv_size,
1141 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1142 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1143 ret = GST_FLOW_ERROR;
1147 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1148 && ret != GST_FLOW_EOS)) {
1149 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1150 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1152 demux->common.num_streams--;
1153 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1154 g_assert (demux->common.src->len == demux->common.num_streams);
1155 gst_matroska_track_free (context);
1160 /* check for a cached track taglist */
1162 (GstTagList *) g_hash_table_lookup (demux->common.cached_track_taglists,
1163 GUINT_TO_POINTER (context->uid));
1165 gst_tag_list_insert (context->tags, cached_taglist, GST_TAG_MERGE_APPEND);
1167 /* now create the GStreamer connectivity */
1168 switch (context->type) {
1169 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1170 GstMatroskaTrackVideoContext *videocontext =
1171 (GstMatroskaTrackVideoContext *) context;
1173 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1174 templ = gst_element_class_get_pad_template (klass, "video_%u");
1175 caps = gst_matroska_demux_video_caps (videocontext,
1176 context->codec_id, context->codec_priv,
1177 context->codec_priv_size, &codec, &riff_fourcc);
1180 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1181 GST_TAG_VIDEO_CODEC, codec, NULL);
1182 context->tags_changed = TRUE;
1188 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1189 GstMatroskaTrackAudioContext *audiocontext =
1190 (GstMatroskaTrackAudioContext *) context;
1192 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1193 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1194 caps = gst_matroska_demux_audio_caps (audiocontext,
1195 context->codec_id, context->codec_priv, context->codec_priv_size,
1196 &codec, &riff_audio_fmt);
1199 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1200 GST_TAG_AUDIO_CODEC, codec, NULL);
1201 context->tags_changed = TRUE;
1207 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1208 GstMatroskaTrackSubtitleContext *subtitlecontext =
1209 (GstMatroskaTrackSubtitleContext *) context;
1211 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1212 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1213 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1214 context->codec_id, context->codec_priv, context->codec_priv_size);
1218 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1219 case GST_MATROSKA_TRACK_TYPE_LOGO:
1220 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1221 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1223 /* we should already have quit by now */
1224 g_assert_not_reached ();
1227 if ((context->language == NULL || *context->language == '\0') &&
1228 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1229 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1230 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1231 context->language = g_strdup ("eng");
1234 if (context->language) {
1237 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1238 lang = gst_tag_get_language_code (context->language);
1239 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1240 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1241 context->tags_changed = TRUE;
1245 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1246 "codec_id='%s'", context->codec_id);
1247 switch (context->type) {
1248 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1249 caps = gst_caps_new_empty_simple ("video/x-unknown");
1251 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1252 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1254 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1255 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1257 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1259 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1262 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1265 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1266 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1267 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1268 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1269 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1270 GST_FOURCC_ARGS (riff_fourcc));
1271 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1274 } else if (context->stream_headers != NULL) {
1275 gst_matroska_demux_add_stream_headers_to_caps (demux,
1276 context->stream_headers, caps);
1279 /* the pad in here */
1280 context->pad = gst_pad_new_from_template (templ, padname);
1281 context->caps = caps;
1283 gst_pad_set_event_function (context->pad,
1284 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1285 gst_pad_set_query_function (context->pad,
1286 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1288 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1291 gst_pad_set_element_private (context->pad, context);
1293 gst_pad_use_fixed_caps (context->pad);
1294 gst_pad_set_active (context->pad, TRUE);
1297 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1298 "%03" G_GUINT64_FORMAT ":%03" G_GUINT64_FORMAT,
1299 context->num, context->uid);
1301 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1304 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1305 demux->have_group_id = TRUE;
1307 demux->have_group_id = FALSE;
1308 gst_event_unref (stream_start);
1309 } else if (!demux->have_group_id) {
1310 demux->have_group_id = TRUE;
1311 demux->group_id = gst_util_group_id_next ();
1314 stream_start = gst_event_new_stream_start (stream_id);
1316 if (demux->have_group_id)
1317 gst_event_set_group_id (stream_start, demux->group_id);
1318 stream_flags = GST_STREAM_FLAG_NONE;
1319 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1320 stream_flags |= GST_STREAM_FLAG_SPARSE;
1321 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1322 stream_flags |= GST_STREAM_FLAG_SELECT;
1323 gst_event_set_stream_flags (stream_start, stream_flags);
1324 gst_pad_push_event (context->pad, stream_start);
1325 gst_pad_set_caps (context->pad, context->caps);
1328 if (demux->common.global_tags) {
1329 GstEvent *tag_event;
1331 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1332 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1333 GST_DEBUG_OBJECT (context->pad, "Sending global_tags %p: %" GST_PTR_FORMAT,
1334 demux->common.global_tags, demux->common.global_tags);
1337 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1339 gst_pad_push_event (context->pad, tag_event);
1342 if (G_UNLIKELY (context->tags_changed)) {
1343 GST_DEBUG_OBJECT (context->pad, "Sending tags %p: %"
1344 GST_PTR_FORMAT, context->tags, context->tags);
1345 gst_pad_push_event (context->pad,
1346 gst_event_new_tag (gst_tag_list_copy (context->tags)));
1347 context->tags_changed = FALSE;
1350 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1351 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1360 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1363 gboolean res = FALSE;
1364 GstMatroskaTrackContext *context = NULL;
1367 context = gst_pad_get_element_private (pad);
1370 switch (GST_QUERY_TYPE (query)) {
1371 case GST_QUERY_POSITION:
1375 gst_query_parse_position (query, &format, NULL);
1378 if (format == GST_FORMAT_TIME) {
1379 GST_OBJECT_LOCK (demux);
1381 gst_query_set_position (query, GST_FORMAT_TIME,
1382 MAX (context->pos, demux->stream_start_time) -
1383 demux->stream_start_time);
1385 gst_query_set_position (query, GST_FORMAT_TIME,
1386 MAX (demux->common.segment.position, demux->stream_start_time) -
1387 demux->stream_start_time);
1388 GST_OBJECT_UNLOCK (demux);
1389 } else if (format == GST_FORMAT_DEFAULT && context
1390 && context->default_duration) {
1391 GST_OBJECT_LOCK (demux);
1392 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1393 context->pos / context->default_duration);
1394 GST_OBJECT_UNLOCK (demux);
1396 GST_DEBUG_OBJECT (demux,
1397 "only position query in TIME and DEFAULT format is supported");
1403 case GST_QUERY_DURATION:
1407 gst_query_parse_duration (query, &format, NULL);
1410 if (format == GST_FORMAT_TIME) {
1411 GST_OBJECT_LOCK (demux);
1412 gst_query_set_duration (query, GST_FORMAT_TIME,
1413 demux->common.segment.duration);
1414 GST_OBJECT_UNLOCK (demux);
1415 } else if (format == GST_FORMAT_DEFAULT && context
1416 && context->default_duration) {
1417 GST_OBJECT_LOCK (demux);
1418 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1419 demux->common.segment.duration / context->default_duration);
1420 GST_OBJECT_UNLOCK (demux);
1422 GST_DEBUG_OBJECT (demux,
1423 "only duration query in TIME and DEFAULT format is supported");
1429 case GST_QUERY_SEEKING:
1433 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1434 GST_OBJECT_LOCK (demux);
1435 if (fmt == GST_FORMAT_TIME) {
1438 if (demux->streaming) {
1439 /* assuming we'll be able to get an index ... */
1440 seekable = demux->seekable;
1445 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1446 0, demux->common.segment.duration);
1449 GST_OBJECT_UNLOCK (demux);
1452 case GST_QUERY_SEGMENT:
1457 format = demux->common.segment.format;
1460 gst_segment_to_stream_time (&demux->common.segment, format,
1461 demux->common.segment.start);
1462 if ((stop = demux->common.segment.stop) == -1)
1463 stop = demux->common.segment.duration;
1466 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1468 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1475 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1478 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1487 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1489 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1493 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1496 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1498 return gst_matroska_demux_query (demux, pad, query);
1501 /* returns FALSE if there are no pads to deliver event to,
1502 * otherwise TRUE (whatever the outcome of event sending),
1503 * takes ownership of the passed event! */
1505 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1507 gboolean ret = FALSE;
1510 g_return_val_if_fail (event != NULL, FALSE);
1512 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1513 GST_EVENT_TYPE_NAME (event));
1515 g_assert (demux->common.src->len == demux->common.num_streams);
1516 for (i = 0; i < demux->common.src->len; i++) {
1517 GstMatroskaTrackContext *stream;
1519 stream = g_ptr_array_index (demux->common.src, i);
1520 gst_event_ref (event);
1521 gst_pad_push_event (stream->pad, event);
1525 gst_event_unref (event);
1530 gst_matroska_demux_send_tags (GstMatroskaDemux * demux)
1534 if (G_UNLIKELY (demux->common.global_tags_changed)) {
1535 GstEvent *tag_event;
1536 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1537 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1538 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1539 demux->common.global_tags, demux->common.global_tags);
1542 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1544 for (i = 0; i < demux->common.src->len; i++) {
1545 GstMatroskaTrackContext *stream;
1547 stream = g_ptr_array_index (demux->common.src, i);
1548 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1551 gst_event_unref (tag_event);
1552 demux->common.global_tags_changed = FALSE;
1555 g_assert (demux->common.src->len == demux->common.num_streams);
1556 for (i = 0; i < demux->common.src->len; i++) {
1557 GstMatroskaTrackContext *stream;
1559 stream = g_ptr_array_index (demux->common.src, i);
1561 if (G_UNLIKELY (stream->tags_changed)) {
1562 GST_DEBUG_OBJECT (demux, "Sending tags %p for pad %s:%s : %"
1563 GST_PTR_FORMAT, stream->tags,
1564 GST_DEBUG_PAD_NAME (stream->pad), stream->tags);
1565 gst_pad_push_event (stream->pad,
1566 gst_event_new_tag (gst_tag_list_copy (stream->tags)));
1567 stream->tags_changed = FALSE;
1573 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1575 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1578 g_return_val_if_fail (event != NULL, FALSE);
1580 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1581 /* no seeking until we are (safely) ready */
1582 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
1583 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
1584 gst_event_unref (event);
1587 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1589 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1590 GST_EVENT_TYPE_NAME (event));
1593 gst_event_unref (event);
1598 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1599 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1603 GST_OBJECT_LOCK (demux);
1606 /* seek (relative to matroska segment) */
1607 /* position might be invalid; will error when streaming resumes ... */
1608 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1609 demux->next_cluster_offset = 0;
1611 GST_DEBUG_OBJECT (demux,
1612 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1613 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1614 entry->block, GST_TIME_ARGS (entry->time));
1616 /* update the time */
1617 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1618 gst_flow_combiner_reset (demux->flowcombiner);
1619 demux->common.segment.position = entry->time;
1620 demux->seek_block = entry->block;
1621 demux->seek_first = TRUE;
1622 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1625 for (i = 0; i < demux->common.src->len; i++) {
1626 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1629 stream->to_offset = G_MAXINT64;
1631 if (stream->from_offset != -1)
1632 stream->to_offset = stream->from_offset;
1634 stream->from_offset = -1;
1635 stream->from_time = GST_CLOCK_TIME_NONE;
1638 GST_OBJECT_UNLOCK (demux);
1644 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1654 /* searches for a cluster start from @pos,
1655 * return GST_FLOW_OK and cluster position in @pos if found */
1656 static GstFlowReturn
1657 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1659 gint64 newpos = *pos;
1661 GstFlowReturn ret = GST_FLOW_OK;
1662 const guint chunk = 64 * 1024;
1663 GstBuffer *buf = NULL;
1665 gpointer data = NULL;
1670 gint64 oldpos, oldlength;
1672 orig_offset = demux->common.offset;
1674 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1677 if (demux->clusters) {
1680 cpos = gst_util_array_binary_search (demux->clusters->data,
1681 demux->clusters->len, sizeof (gint64),
1682 (GCompareDataFunc) gst_matroska_cluster_compare,
1683 GST_SEARCH_MODE_AFTER, pos, NULL);
1686 GST_DEBUG_OBJECT (demux,
1687 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1688 demux->common.offset = *cpos;
1689 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1690 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1691 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1698 /* read in at newpos and scan for ebml cluster id */
1699 oldpos = oldlength = -1;
1701 GstByteReader reader;
1705 gst_buffer_unmap (buf, &map);
1706 gst_buffer_unref (buf);
1709 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1710 if (ret != GST_FLOW_OK)
1712 GST_DEBUG_OBJECT (demux,
1713 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1714 gst_buffer_get_size (buf), newpos);
1715 gst_buffer_map (buf, &map, GST_MAP_READ);
1718 if (oldpos == newpos && oldlength == map.size) {
1719 GST_ERROR_OBJECT (demux, "Stuck at same position");
1720 ret = GST_FLOW_ERROR;
1724 oldlength = map.size;
1727 gst_byte_reader_init (&reader, data, size);
1729 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1730 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1731 if (cluster_pos >= 0) {
1732 newpos += cluster_pos;
1733 /* prepare resuming at next byte */
1734 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1735 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1738 GST_DEBUG_OBJECT (demux,
1739 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1740 /* extra checks whether we really sync'ed to a cluster:
1741 * - either it is the first and only cluster
1742 * - either there is a cluster after this one
1743 * - either cluster length is undefined
1745 /* ok if first cluster (there may not a subsequent one) */
1746 if (newpos == demux->first_cluster_offset) {
1747 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1750 demux->common.offset = newpos;
1751 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1752 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1753 if (ret != GST_FLOW_OK) {
1754 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1757 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1758 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1760 /* ok if undefined length or first cluster */
1761 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1762 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1766 demux->common.offset += length + needed;
1767 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1768 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1769 if (ret != GST_FLOW_OK)
1771 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1772 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1773 if (id == GST_MATROSKA_ID_CLUSTER)
1775 /* not ok, resume */
1778 /* partial cluster id may have been in tail of buffer */
1779 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1784 gst_buffer_unmap (buf, &map);
1785 gst_buffer_unref (buf);
1790 demux->common.offset = orig_offset;
1795 /* bisect and scan through file for cluster starting before @time,
1796 * returns fake index entry with corresponding info on cluster */
1797 static GstMatroskaIndex *
1798 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1800 GstMatroskaIndex *entry = NULL;
1801 GstMatroskaReadState current_state;
1802 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1803 gint64 opos, newpos, startpos = 0, current_offset;
1804 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1805 const guint chunk = 64 * 1024;
1811 /* (under)estimate new position, resync using cluster ebml id,
1812 * and scan forward to appropriate cluster
1813 * (and re-estimate if need to go backward) */
1815 prev_cluster_time = GST_CLOCK_TIME_NONE;
1817 /* store some current state */
1818 current_state = demux->common.state;
1819 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1821 current_cluster_offset = demux->cluster_offset;
1822 current_cluster_time = demux->cluster_time;
1823 current_offset = demux->common.offset;
1825 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1827 /* estimate using start and current position */
1828 GST_OBJECT_LOCK (demux);
1829 opos = demux->common.offset - demux->common.ebml_segment_start;
1830 otime = demux->common.segment.position;
1831 GST_OBJECT_UNLOCK (demux);
1834 time = MAX (time, demux->stream_start_time);
1836 /* avoid division by zero in first estimation below */
1837 if (otime <= demux->stream_start_time)
1841 GST_LOG_OBJECT (demux,
1842 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1843 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1844 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1845 GST_TIME_ARGS (otime - demux->stream_start_time),
1846 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1848 if (otime <= demux->stream_start_time) {
1852 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1853 time - demux->stream_start_time,
1854 otime - demux->stream_start_time) - chunk;
1858 /* favour undershoot */
1859 newpos = newpos * 90 / 100;
1860 newpos += demux->common.ebml_segment_start;
1862 GST_DEBUG_OBJECT (demux,
1863 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1864 GST_TIME_ARGS (time), newpos);
1866 /* and at least start scanning before previous scan start to avoid looping */
1867 startpos = startpos * 90 / 100;
1868 if (startpos && startpos < newpos)
1871 /* read in at newpos and scan for ebml cluster id */
1875 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1876 if (ret == GST_FLOW_EOS) {
1877 /* heuristic HACK */
1878 newpos = startpos * 80 / 100;
1879 GST_DEBUG_OBJECT (demux, "EOS; "
1880 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1881 GST_TIME_ARGS (time), newpos);
1884 } else if (ret != GST_FLOW_OK) {
1891 /* then start scanning and parsing for cluster time,
1892 * re-estimate if overshoot, otherwise next cluster and so on */
1893 demux->common.offset = newpos;
1894 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1896 guint64 cluster_size = 0;
1898 /* peek and parse some elements */
1899 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1900 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1901 if (ret != GST_FLOW_OK)
1903 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1904 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1906 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1907 if (ret != GST_FLOW_OK)
1910 if (id == GST_MATROSKA_ID_CLUSTER) {
1911 cluster_time = GST_CLOCK_TIME_NONE;
1912 if (length == G_MAXUINT64)
1915 cluster_size = length + needed;
1917 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1918 cluster_time == GST_CLOCK_TIME_NONE) {
1919 cluster_time = demux->cluster_time * demux->common.time_scale;
1920 cluster_offset = demux->cluster_offset;
1921 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1922 " with time %" GST_TIME_FORMAT, cluster_offset,
1923 GST_TIME_ARGS (cluster_time));
1924 if (cluster_time > time) {
1925 GST_DEBUG_OBJECT (demux, "overshot target");
1926 /* cluster overshoots */
1927 if (cluster_offset == demux->first_cluster_offset) {
1928 /* but no prev one */
1929 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1930 prev_cluster_time = cluster_time;
1931 prev_cluster_offset = cluster_offset;
1934 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1935 /* prev cluster did not overshoot, so prev cluster is target */
1938 /* re-estimate using this new position info */
1939 opos = cluster_offset;
1940 otime = cluster_time;
1944 /* cluster undershoots, goto next one */
1945 prev_cluster_time = cluster_time;
1946 prev_cluster_offset = cluster_offset;
1947 /* skip cluster if length is defined,
1948 * otherwise will be skippingly parsed into */
1950 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1951 demux->common.offset = cluster_offset + cluster_size;
1952 demux->cluster_time = GST_CLOCK_TIME_NONE;
1954 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1961 if (ret == GST_FLOW_EOS) {
1962 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1968 entry = g_new0 (GstMatroskaIndex, 1);
1969 entry->time = prev_cluster_time;
1970 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1971 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1972 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1976 /* restore some state */
1977 demux->cluster_offset = current_cluster_offset;
1978 demux->cluster_time = current_cluster_time;
1979 demux->common.offset = current_offset;
1980 demux->common.state = current_state;
1986 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1987 GstPad * pad, GstEvent * event)
1989 GstMatroskaIndex *entry = NULL;
1990 GstMatroskaIndex scan_entry;
1992 GstSeekType cur_type, stop_type;
1994 gboolean flush, keyunit, before, after, snap_next;
1997 GstMatroskaTrackContext *track = NULL;
1998 GstSegment seeksegment = { 0, };
1999 gboolean update = TRUE;
2000 gboolean pad_locked = FALSE;
2002 GstSearchMode snap_dir;
2004 g_return_val_if_fail (event != NULL, FALSE);
2007 track = gst_pad_get_element_private (pad);
2009 GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
2011 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2013 seqnum = gst_event_get_seqnum (event);
2015 /* we can only seek on time */
2016 if (format != GST_FORMAT_TIME) {
2017 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2021 /* copy segment, we need this because we still need the old
2022 * segment when we close the current segment. */
2023 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
2025 /* pull mode without index means that the actual duration is not known,
2026 * we might be playing a file that's still being recorded
2027 * so, invalidate our current duration, which is only a moving target,
2028 * and should not be used to clamp anything */
2029 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
2030 seeksegment.duration = GST_CLOCK_TIME_NONE;
2033 GST_DEBUG_OBJECT (demux, "configuring seek");
2034 /* Subtract stream_start_time so we always seek on a segment
2036 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2037 seeksegment.start -= demux->stream_start_time;
2038 seeksegment.position -= demux->stream_start_time;
2039 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2040 seeksegment.stop -= demux->stream_start_time;
2042 seeksegment.stop = seeksegment.duration;
2045 gst_segment_do_seek (&seeksegment, rate, format, flags,
2046 cur_type, cur, stop_type, stop, &update);
2048 /* Restore the clip timestamp offset */
2049 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2050 seeksegment.position += demux->stream_start_time;
2051 seeksegment.start += demux->stream_start_time;
2052 if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2053 seeksegment.stop = seeksegment.duration;
2054 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2055 seeksegment.stop += demux->stream_start_time;
2058 /* restore segment duration (if any effect),
2059 * would be determined again when parsing, but anyway ... */
2060 seeksegment.duration = demux->common.segment.duration;
2062 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2063 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2064 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
2065 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
2067 /* always do full update if flushing,
2068 * otherwise problems might arise downstream with missing keyframes etc */
2069 update = update || flush;
2071 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2073 /* check sanity before we start flushing and all that */
2074 snap_next = after && !before;
2075 if (seeksegment.rate < 0)
2076 snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
2078 snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
2080 GST_OBJECT_LOCK (demux);
2081 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2082 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2083 seeksegment.position, &demux->seek_index, &demux->seek_entry,
2084 snap_dir)) == NULL) {
2085 /* pull mode without index can scan later on */
2086 if (demux->streaming) {
2087 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2088 GST_OBJECT_UNLOCK (demux);
2090 } else if (rate < 0.0) {
2091 /* FIXME: We should build an index during playback or when scanning
2092 * that can be used here. The reverse playback code requires seek_index
2093 * and seek_entry to be set!
2095 GST_DEBUG_OBJECT (demux,
2096 "No matching seek entry in index, needed for reverse playback");
2097 GST_OBJECT_UNLOCK (demux);
2101 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2102 GST_OBJECT_UNLOCK (demux);
2105 /* only have to update some segment,
2106 * but also still have to honour flush and so on */
2107 GST_DEBUG_OBJECT (demux, "... no update");
2108 /* bad goto, bad ... */
2112 if (demux->streaming)
2117 GstEvent *flush_event = gst_event_new_flush_start ();
2118 gst_event_set_seqnum (flush_event, seqnum);
2119 GST_DEBUG_OBJECT (demux, "Starting flush");
2120 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2121 gst_matroska_demux_send_event (demux, flush_event);
2123 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2124 gst_pad_pause_task (demux->common.sinkpad);
2128 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2133 /* now grab the stream lock so that streaming cannot continue, for
2134 * non flushing seeks when the element is in PAUSED this could block
2136 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2137 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2140 /* pull mode without index can do some scanning */
2141 if (!demux->streaming && !entry) {
2142 GstEvent *flush_event;
2144 /* need to stop flushing upstream as we need it next */
2146 flush_event = gst_event_new_flush_stop (TRUE);
2147 gst_event_set_seqnum (flush_event, seqnum);
2148 gst_pad_push_event (demux->common.sinkpad, flush_event);
2150 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2151 /* keep local copy */
2153 scan_entry = *entry;
2155 entry = &scan_entry;
2157 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2159 flush_event = gst_event_new_flush_stop (TRUE);
2160 gst_event_set_seqnum (flush_event, seqnum);
2161 gst_matroska_demux_send_event (demux, flush_event);
2169 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2170 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2171 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2172 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2173 seeksegment.position = seeksegment.start;
2174 seeksegment.time = seeksegment.start - demux->stream_start_time;
2177 if (demux->streaming) {
2178 GST_OBJECT_LOCK (demux);
2179 /* track real position we should start at */
2180 GST_DEBUG_OBJECT (demux, "storing segment start");
2181 demux->requested_seek_time = seeksegment.position;
2182 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2183 GST_OBJECT_UNLOCK (demux);
2184 /* need to seek to cluster start to pick up cluster time */
2185 /* upstream takes care of flushing and all that
2186 * ... and newsegment event handling takes care of the rest */
2187 return perform_seek_to_offset (demux, rate,
2188 entry->pos + demux->common.ebml_segment_start, seqnum);
2193 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2194 gst_event_set_seqnum (flush_event, seqnum);
2195 GST_DEBUG_OBJECT (demux, "Stopping flush");
2196 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2197 gst_matroska_demux_send_event (demux, flush_event);
2200 GST_OBJECT_LOCK (demux);
2201 /* now update the real segment info */
2202 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2203 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2204 GST_OBJECT_UNLOCK (demux);
2206 /* update some (segment) state */
2207 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2210 /* notify start of new segment */
2211 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2214 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2215 GST_FORMAT_TIME, demux->common.segment.start);
2216 gst_message_set_seqnum (msg, seqnum);
2217 gst_element_post_message (GST_ELEMENT (demux), msg);
2220 GST_OBJECT_LOCK (demux);
2221 if (demux->new_segment)
2222 gst_event_unref (demux->new_segment);
2224 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2225 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2226 gst_event_set_seqnum (demux->new_segment, seqnum);
2227 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2228 demux->to_time = demux->common.segment.position;
2230 demux->to_time = GST_CLOCK_TIME_NONE;
2231 GST_OBJECT_UNLOCK (demux);
2233 /* restart our task since it might have been stopped when we did the
2235 gst_pad_start_task (demux->common.sinkpad,
2236 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2238 /* streaming can continue now */
2240 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2248 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2250 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2256 * Handle whether we can perform the seek event or if we have to let the chain
2257 * function handle seeks to build the seek indexes first.
2260 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2264 GstSeekType cur_type, stop_type;
2269 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2274 /* we can only seek on time */
2275 if (format != GST_FORMAT_TIME) {
2276 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2280 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2281 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2285 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2286 GST_DEBUG_OBJECT (demux,
2287 "Non-flushing seek not supported in streaming mode");
2291 if (flags & GST_SEEK_FLAG_SEGMENT) {
2292 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2296 /* check for having parsed index already */
2297 if (!demux->common.index_parsed) {
2298 gboolean building_index;
2301 if (!demux->index_offset) {
2302 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2306 GST_OBJECT_LOCK (demux);
2307 /* handle the seek event in the chain function */
2308 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2309 /* no more seek can be issued until state reset to _DATA */
2311 /* copy the event */
2312 if (demux->seek_event)
2313 gst_event_unref (demux->seek_event);
2314 demux->seek_event = gst_event_ref (event);
2316 /* set the building_index flag so that only one thread can setup the
2317 * structures for index seeking. */
2318 building_index = demux->building_index;
2319 if (!building_index) {
2320 demux->building_index = TRUE;
2321 offset = demux->index_offset;
2323 GST_OBJECT_UNLOCK (demux);
2325 if (!building_index) {
2326 /* seek to the first subindex or legacy index */
2327 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2328 return perform_seek_to_offset (demux, rate, offset,
2329 gst_event_get_seqnum (event));
2332 /* well, we are handling it already */
2336 /* delegate to tweaked regular seek */
2337 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2341 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2344 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2345 gboolean res = TRUE;
2347 switch (GST_EVENT_TYPE (event)) {
2348 case GST_EVENT_SEEK:
2349 /* no seeking until we are (safely) ready */
2350 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2351 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2352 gst_event_unref (event);
2355 if (!demux->streaming)
2356 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2358 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2359 gst_event_unref (event);
2364 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2365 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2366 GstMatroskaTrackVideoContext *videocontext =
2367 (GstMatroskaTrackVideoContext *) context;
2369 GstClockTimeDiff diff;
2370 GstClockTime timestamp;
2372 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2374 GST_OBJECT_LOCK (demux);
2375 videocontext->earliest_time = timestamp + diff;
2376 GST_OBJECT_UNLOCK (demux);
2379 gst_event_unref (event);
2383 case GST_EVENT_TOC_SELECT:
2386 GstTocEntry *entry = NULL;
2387 GstEvent *seek_event;
2390 if (!demux->common.toc) {
2391 GST_DEBUG_OBJECT (demux, "no TOC to select");
2394 gst_event_parse_toc_select (event, &uid);
2396 GST_OBJECT_LOCK (demux);
2397 entry = gst_toc_find_entry (demux->common.toc, uid);
2398 if (entry == NULL) {
2399 GST_OBJECT_UNLOCK (demux);
2400 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2403 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2404 GST_OBJECT_UNLOCK (demux);
2405 seek_event = gst_event_new_seek (1.0,
2407 GST_SEEK_FLAG_FLUSH,
2408 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2409 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2410 gst_event_unref (seek_event);
2414 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2418 gst_event_unref (event);
2422 /* events we don't need to handle */
2423 case GST_EVENT_NAVIGATION:
2424 gst_event_unref (event);
2428 case GST_EVENT_LATENCY:
2430 res = gst_pad_push_event (demux->common.sinkpad, event);
2437 static GstFlowReturn
2438 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2440 GstFlowReturn ret = GST_FLOW_EOS;
2441 gboolean done = TRUE;
2444 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2445 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2448 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2450 if (!demux->seek_entry) {
2451 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2455 for (i = 0; i < demux->common.src->len; i++) {
2456 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2458 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2459 ", stream %d at %" GST_TIME_FORMAT,
2460 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2461 GST_TIME_ARGS (stream->from_time));
2462 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2463 if (stream->from_time > demux->common.segment.start) {
2464 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2468 /* nothing pushed for this stream;
2469 * likely seek entry did not start at keyframe, so all was skipped.
2470 * So we need an earlier entry */
2476 GstMatroskaIndex *entry;
2478 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2479 --demux->seek_entry);
2480 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2490 static GstFlowReturn
2491 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2493 GstFlowReturn ret = GST_FLOW_OK;
2496 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2498 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2499 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2503 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2504 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2508 /* one track within the "all-tracks" header */
2509 case GST_MATROSKA_ID_TRACKENTRY:
2510 ret = gst_matroska_demux_add_stream (demux, ebml);
2514 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2519 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2521 demux->tracks_parsed = TRUE;
2527 * Read signed/unsigned "EBML" numbers.
2528 * Return: number of bytes processed.
2532 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2534 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2542 while (read <= 8 && !(total & len_mask)) {
2549 if ((total &= (len_mask - 1)) == len_mask - 1)
2554 if (data[n] == 0xff)
2556 total = (total << 8) | data[n];
2560 if (read == num_ffs && total != 0)
2569 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2574 /* read as unsigned number first */
2575 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2579 if (unum == G_MAXUINT64)
2582 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2588 * Mostly used for subtitles. We add void filler data for each
2589 * lagging stream to make sure we don't deadlock.
2593 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2595 GstClockTime gap_threshold;
2598 GST_OBJECT_LOCK (demux);
2600 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2601 GST_TIME_ARGS (demux->common.segment.position));
2603 g_assert (demux->common.num_streams == demux->common.src->len);
2604 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2605 GstMatroskaTrackContext *context;
2607 context = g_ptr_array_index (demux->common.src, stream_nr);
2609 GST_LOG_OBJECT (demux,
2610 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2611 GST_TIME_ARGS (context->pos));
2613 /* Only send gap events on non-subtitle streams if lagging way behind.
2614 * The 0.5 second threshold for subtitle streams is also quite random. */
2615 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
2616 gap_threshold = GST_SECOND / 2;
2618 gap_threshold = 3 * GST_SECOND;
2620 /* Lag need only be considered if we have advanced into requested segment */
2621 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2622 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2623 demux->common.segment.position > demux->common.segment.start &&
2624 context->pos + gap_threshold < demux->common.segment.position) {
2627 guint64 start = context->pos;
2628 guint64 stop = demux->common.segment.position - gap_threshold;
2630 GST_DEBUG_OBJECT (demux,
2631 "Synchronizing stream %d with other by advancing time from %"
2632 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2633 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2635 context->pos = stop;
2637 event = gst_event_new_gap (start, stop - start);
2638 GST_OBJECT_UNLOCK (demux);
2639 gst_pad_push_event (context->pad, event);
2640 GST_OBJECT_LOCK (demux);
2644 GST_OBJECT_UNLOCK (demux);
2647 static GstFlowReturn
2648 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2649 GstMatroskaTrackContext * stream)
2651 GstFlowReturn ret = GST_FLOW_OK;
2654 num = gst_buffer_list_length (stream->stream_headers);
2655 for (i = 0; i < num; ++i) {
2658 buf = gst_buffer_list_get (stream->stream_headers, i);
2659 buf = gst_buffer_copy (buf);
2661 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2663 if (stream->set_discont) {
2664 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2665 stream->set_discont = FALSE;
2667 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2670 /* push out all headers in one go and use last flow return */
2671 ret = gst_pad_push (stream->pad, buf);
2674 /* don't need these any longer */
2675 gst_buffer_list_unref (stream->stream_headers);
2676 stream->stream_headers = NULL;
2679 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2685 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2686 GstMatroskaTrackContext * stream)
2690 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2692 if (!stream->codec_priv)
2695 /* ideally, VobSub private data should be parsed and stored more convenient
2696 * elsewhere, but for now, only interested in a small part */
2698 /* make sure we have terminating 0 */
2699 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2701 /* just locate and parse palette part */
2702 start = strstr (buf, "palette:");
2707 guint8 r, g, b, y, u, v;
2710 while (g_ascii_isspace (*start))
2712 for (i = 0; i < 16; i++) {
2713 if (sscanf (start, "%06x", &col) != 1)
2716 while ((*start == ',') || g_ascii_isspace (*start))
2718 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2719 r = (col >> 16) & 0xff;
2720 g = (col >> 8) & 0xff;
2722 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2724 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2725 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2726 clut[i] = (y << 16) | (u << 8) | v;
2729 /* got them all without problems; build and send event */
2733 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2734 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2735 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2736 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2737 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2738 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2739 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2740 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2741 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2742 G_TYPE_INT, clut[15], NULL);
2744 gst_pad_push_event (stream->pad,
2745 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2752 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2756 GST_OBJECT_LOCK (demux);
2758 g_assert (demux->common.num_streams == demux->common.src->len);
2759 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2760 GstMatroskaTrackContext *stream;
2762 stream = g_ptr_array_index (demux->common.src, stream_nr);
2764 if (stream->send_stream_headers) {
2765 if (stream->stream_headers != NULL) {
2766 gst_matroska_demux_push_stream_headers (demux, stream);
2768 /* FIXME: perhaps we can just disable and skip this stream then */
2769 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2770 ("Failed to extract stream headers from codec private data"));
2772 stream->send_stream_headers = FALSE;
2775 if (stream->send_dvd_event) {
2776 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2777 /* FIXME: should we send this event again after (flushing) seek ? */
2778 stream->send_dvd_event = FALSE;
2782 GST_OBJECT_UNLOCK (demux);
2785 static GstFlowReturn
2786 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2787 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2790 guint seq_header_len;
2791 guint32 header, tmp;
2793 if (stream->codec_state) {
2794 seq_header = stream->codec_state;
2795 seq_header_len = stream->codec_state_size;
2796 } else if (stream->codec_priv) {
2797 seq_header = stream->codec_priv;
2798 seq_header_len = stream->codec_priv_size;
2803 /* Sequence header only needed for keyframes */
2804 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2807 if (gst_buffer_get_size (*buf) < 4)
2810 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2811 header = GUINT32_FROM_BE (tmp);
2813 /* Sequence start code, if not found prepend */
2814 if (header != 0x000001b3) {
2817 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2819 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2822 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2823 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2824 gst_buffer_get_size (*buf));
2826 gst_buffer_unref (*buf);
2833 static GstFlowReturn
2834 gst_matroska_demux_add_wvpk_header (GstElement * element,
2835 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2837 GstMatroskaTrackAudioContext *audiocontext =
2838 (GstMatroskaTrackAudioContext *) stream;
2839 GstBuffer *newbuf = NULL;
2840 GstMapInfo map, outmap;
2841 guint8 *buf_data, *data;
2849 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2852 wvh.total_samples = -1;
2853 wvh.block_index = audiocontext->wvpk_block_index;
2855 if (audiocontext->channels <= 2) {
2856 guint32 block_samples, tmp;
2857 gsize size = gst_buffer_get_size (*buf);
2859 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2860 block_samples = GUINT32_FROM_LE (tmp);
2861 /* we need to reconstruct the header of the wavpack block */
2863 /* -20 because ck_size is the size of the wavpack block -8
2864 * and lace_size is the size of the wavpack block + 12
2865 * (the three guint32 of the header that already are in the buffer) */
2866 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2868 /* block_samples, flags and crc are already in the buffer */
2869 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2871 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2877 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2878 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2879 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2880 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2881 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2882 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2883 gst_buffer_unmap (newbuf, &outmap);
2885 /* Append data from buf: */
2886 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2887 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2889 gst_buffer_unref (*buf);
2891 audiocontext->wvpk_block_index += block_samples;
2893 guint8 *outdata = NULL;
2895 gsize buf_size, size, out_size = 0;
2896 guint32 block_samples, flags, crc, blocksize;
2898 gst_buffer_map (*buf, &map, GST_MAP_READ);
2899 buf_data = map.data;
2900 buf_size = map.size;
2903 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2904 gst_buffer_unmap (*buf, &map);
2905 return GST_FLOW_ERROR;
2911 block_samples = GST_READ_UINT32_LE (data);
2916 flags = GST_READ_UINT32_LE (data);
2919 crc = GST_READ_UINT32_LE (data);
2922 blocksize = GST_READ_UINT32_LE (data);
2926 if (blocksize == 0 || size < blocksize)
2929 g_assert ((newbuf == NULL) == (outdata == NULL));
2931 if (newbuf == NULL) {
2932 out_size = sizeof (Wavpack4Header) + blocksize;
2933 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2935 gst_buffer_copy_into (newbuf, *buf,
2936 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2939 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2940 outdata = outmap.data;
2942 gst_buffer_unmap (newbuf, &outmap);
2943 out_size += sizeof (Wavpack4Header) + blocksize;
2944 gst_buffer_set_size (newbuf, out_size);
2945 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2946 outdata = outmap.data;
2949 outdata[outpos] = 'w';
2950 outdata[outpos + 1] = 'v';
2951 outdata[outpos + 2] = 'p';
2952 outdata[outpos + 3] = 'k';
2955 GST_WRITE_UINT32_LE (outdata + outpos,
2956 blocksize + sizeof (Wavpack4Header) - 8);
2957 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2958 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2959 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2960 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2961 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2962 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2963 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2964 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2967 memmove (outdata + outpos, data, blocksize);
2968 outpos += blocksize;
2972 gst_buffer_unmap (*buf, &map);
2973 gst_buffer_unref (*buf);
2976 gst_buffer_unmap (newbuf, &outmap);
2979 audiocontext->wvpk_block_index += block_samples;
2985 static GstFlowReturn
2986 gst_matroska_demux_add_prores_header (GstElement * element,
2987 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2989 GstBuffer *newbuf = gst_buffer_new_allocate (NULL, 8, NULL);
2993 if (!gst_buffer_map (newbuf, &map, GST_MAP_WRITE)) {
2994 GST_ERROR ("Failed to map newly allocated buffer");
2995 return GST_FLOW_ERROR;
2998 frame_size = gst_buffer_get_size (*buf);
3000 GST_WRITE_UINT32_BE (map.data, frame_size);
3006 gst_buffer_unmap (newbuf, &map);
3007 *buf = gst_buffer_append (newbuf, *buf);
3012 /* @text must be null-terminated */
3014 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
3019 g_return_val_if_fail (text != NULL, FALSE);
3021 /* yes, this might all lead to false positives ... */
3022 tag = (gchar *) text;
3023 while ((tag = strchr (tag, '<'))) {
3025 if (*tag != '\0' && *(tag + 1) == '>') {
3026 /* some common convenience ones */
3027 /* maybe any character will do here ? */
3040 if (strstr (text, "<span"))
3046 static GstFlowReturn
3047 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
3048 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3050 GstMatroskaTrackSubtitleContext *sub_stream;
3051 const gchar *encoding;
3056 gboolean needs_unmap = TRUE;
3058 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3060 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
3063 /* The subtitle buffer we push out should not include a NUL terminator as
3064 * part of the data. */
3065 if (map.data[map.size - 1] == '\0') {
3066 gst_buffer_set_size (*buf, map.size - 1);
3067 gst_buffer_unmap (*buf, &map);
3068 gst_buffer_map (*buf, &map, GST_MAP_READ);
3071 if (!sub_stream->invalid_utf8) {
3072 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
3075 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
3076 " is not valid UTF-8, this is broken according to the matroska"
3077 " specification", stream->num);
3078 sub_stream->invalid_utf8 = TRUE;
3081 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3082 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3083 if (encoding == NULL || *encoding == '\0') {
3084 /* if local encoding is UTF-8 and no encoding specified
3085 * via the environment variable, assume ISO-8859-15 */
3086 if (g_get_charset (&encoding)) {
3087 encoding = "ISO-8859-15";
3092 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3093 (char *) "*", NULL, NULL, &err);
3096 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3097 encoding, err->message);
3101 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3102 encoding = "ISO-8859-15";
3104 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3105 encoding, (char *) "*", NULL, NULL, NULL);
3108 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3109 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3112 utf8 = g_strdup ("invalid subtitle");
3114 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3115 gst_buffer_unmap (*buf, &map);
3116 gst_buffer_copy_into (newbuf, *buf,
3117 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3119 gst_buffer_unref (*buf);
3122 gst_buffer_map (*buf, &map, GST_MAP_READ);
3126 if (sub_stream->check_markup) {
3127 /* caps claim markup text, so we need to escape text,
3128 * except if text is already markup and then needs no further escaping */
3129 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3130 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3132 if (!sub_stream->seen_markup_tag) {
3133 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3135 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3136 gst_buffer_unmap (*buf, &map);
3137 gst_buffer_copy_into (newbuf, *buf,
3138 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3139 GST_BUFFER_COPY_META, 0, -1);
3140 gst_buffer_unref (*buf);
3143 needs_unmap = FALSE;
3148 gst_buffer_unmap (*buf, &map);
3153 static GstFlowReturn
3154 gst_matroska_demux_check_aac (GstElement * element,
3155 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3160 gst_buffer_extract (*buf, 0, data, 2);
3161 size = gst_buffer_get_size (*buf);
3163 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3166 /* tss, ADTS data, remove codec_data
3167 * still assume it is at least parsed */
3168 stream->caps = gst_caps_make_writable (stream->caps);
3169 s = gst_caps_get_structure (stream->caps, 0);
3171 gst_structure_remove_field (s, "codec_data");
3172 gst_pad_set_caps (stream->pad, stream->caps);
3173 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3174 "new caps: %" GST_PTR_FORMAT, stream->caps);
3177 /* disable subsequent checking */
3178 stream->postprocess_frame = NULL;
3184 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3185 GstBuffer * buffer, gsize alignment)
3189 gst_buffer_map (buffer, &map, GST_MAP_READ);
3191 if (map.size < sizeof (guintptr)) {
3192 gst_buffer_unmap (buffer, &map);
3196 if (((guintptr) map.data) & (alignment - 1)) {
3197 GstBuffer *new_buffer;
3198 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3200 new_buffer = gst_buffer_new_allocate (NULL,
3201 gst_buffer_get_size (buffer), ¶ms);
3203 /* Copy data "by hand", so ensure alignment is kept: */
3204 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3206 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3207 GST_DEBUG_OBJECT (demux,
3208 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3211 gst_buffer_unmap (buffer, &map);
3212 gst_buffer_unref (buffer);
3217 gst_buffer_unmap (buffer, &map);
3221 static GstFlowReturn
3222 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3223 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3224 gboolean is_simpleblock)
3226 GstMatroskaTrackContext *stream = NULL;
3227 GstFlowReturn ret = GST_FLOW_OK;
3228 gboolean readblock = FALSE;
3230 guint64 block_duration = -1;
3231 gint64 block_discardpadding = 0;
3232 GstBuffer *buf = NULL;
3234 gint stream_num = -1, n, laces = 0;
3236 gint *lace_size = NULL;
3239 gint64 referenceblock = 0;
3241 GstClockTime buffer_timestamp;
3243 offset = gst_ebml_read_get_offset (ebml);
3245 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3246 if (!is_simpleblock) {
3247 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3251 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3255 /* one block inside the group. Note, block parsing is one
3256 * of the harder things, so this code is a bit complicated.
3257 * See http://www.matroska.org/ for documentation. */
3258 case GST_MATROSKA_ID_SIMPLEBLOCK:
3259 case GST_MATROSKA_ID_BLOCK:
3265 gst_buffer_unmap (buf, &map);
3266 gst_buffer_unref (buf);
3269 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3272 gst_buffer_map (buf, &map, GST_MAP_READ);
3276 /* first byte(s): blocknum */
3277 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3282 /* fetch stream from num */
3283 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3285 if (G_UNLIKELY (size < 3)) {
3286 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3287 /* non-fatal, try next block(group) */
3290 } else if (G_UNLIKELY (stream_num < 0 ||
3291 stream_num >= demux->common.num_streams)) {
3292 /* let's not give up on a stray invalid track number */
3293 GST_WARNING_OBJECT (demux,
3294 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3295 "; ignoring block", stream_num, num);
3299 stream = g_ptr_array_index (demux->common.src, stream_num);
3301 /* time (relative to cluster time) */
3302 time = ((gint16) GST_READ_UINT16_BE (data));
3305 flags = GST_READ_UINT8 (data);
3309 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3312 switch ((flags & 0x06) >> 1) {
3313 case 0x0: /* no lacing */
3315 lace_size = g_new (gint, 1);
3316 lace_size[0] = size;
3319 case 0x1: /* xiph lacing */
3320 case 0x2: /* fixed-size lacing */
3321 case 0x3: /* EBML lacing */
3323 goto invalid_lacing;
3324 laces = GST_READ_UINT8 (data) + 1;
3327 lace_size = g_new0 (gint, laces);
3329 switch ((flags & 0x06) >> 1) {
3330 case 0x1: /* xiph lacing */ {
3331 guint temp, total = 0;
3333 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3336 goto invalid_lacing;
3337 temp = GST_READ_UINT8 (data);
3338 lace_size[n] += temp;
3344 total += lace_size[n];
3346 lace_size[n] = size - total;
3350 case 0x2: /* fixed-size lacing */
3351 for (n = 0; n < laces; n++)
3352 lace_size[n] = size / laces;
3355 case 0x3: /* EBML lacing */ {
3358 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3362 total = lace_size[0] = num;
3363 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3367 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3371 lace_size[n] = lace_size[n - 1] + snum;
3372 total += lace_size[n];
3375 lace_size[n] = size - total;
3382 if (ret != GST_FLOW_OK)
3389 case GST_MATROSKA_ID_BLOCKDURATION:{
3390 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3391 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3396 case GST_MATROSKA_ID_DISCARDPADDING:{
3397 ret = gst_ebml_read_sint (ebml, &id, &block_discardpadding);
3398 GST_DEBUG_OBJECT (demux, "DiscardPadding: %" GST_STIME_FORMAT,
3399 GST_STIME_ARGS (block_discardpadding));
3403 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3404 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3405 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3410 case GST_MATROSKA_ID_CODECSTATE:{
3412 guint64 data_len = 0;
3415 gst_ebml_read_binary (ebml, &id, &data,
3416 &data_len)) != GST_FLOW_OK)
3419 if (G_UNLIKELY (stream == NULL)) {
3420 GST_WARNING_OBJECT (demux,
3421 "Unexpected CodecState subelement - ignoring");
3425 g_free (stream->codec_state);
3426 stream->codec_state = data;
3427 stream->codec_state_size = data_len;
3429 /* Decode if necessary */
3430 if (stream->encodings && stream->encodings->len > 0
3431 && stream->codec_state && stream->codec_state_size > 0) {
3432 if (!gst_matroska_decode_data (stream->encodings,
3433 &stream->codec_state, &stream->codec_state_size,
3434 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3435 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3439 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3440 stream->codec_state_size);
3445 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3449 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3450 case GST_MATROSKA_ID_BLOCKADDITIONS:
3451 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3452 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3453 case GST_MATROSKA_ID_SLICES:
3454 GST_DEBUG_OBJECT (demux,
3455 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3456 ret = gst_ebml_read_skip (ebml);
3464 /* reading a number or so could have failed */
3465 if (ret != GST_FLOW_OK)
3468 if (ret == GST_FLOW_OK && readblock) {
3469 gboolean invisible_frame = FALSE;
3470 gboolean delta_unit = FALSE;
3471 guint64 duration = 0;
3472 gint64 lace_time = 0;
3474 stream = g_ptr_array_index (demux->common.src, stream_num);
3476 if (cluster_time != GST_CLOCK_TIME_NONE) {
3477 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3478 * Drop unless the lace contains timestamp 0? */
3479 if (time < 0 && (-time) > cluster_time) {
3482 if (stream->timecodescale == 1.0)
3483 lace_time = (cluster_time + time) * demux->common.time_scale;
3486 gst_util_guint64_to_gdouble ((cluster_time + time) *
3487 demux->common.time_scale) * stream->timecodescale;
3490 lace_time = GST_CLOCK_TIME_NONE;
3493 /* need to refresh segment info ASAP */
3494 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3495 GstSegment *segment = &demux->common.segment;
3497 GstEvent *segment_event;
3499 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3500 demux->stream_start_time = lace_time;
3501 GST_DEBUG_OBJECT (demux,
3502 "Setting stream start time to %" GST_TIME_FORMAT,
3503 GST_TIME_ARGS (lace_time));
3505 clace_time = MAX (lace_time, demux->stream_start_time);
3506 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3507 demux->common.segment.position != 0) {
3508 GST_DEBUG_OBJECT (demux,
3509 "using stored seek position %" GST_TIME_FORMAT,
3510 GST_TIME_ARGS (demux->common.segment.position));
3511 clace_time = demux->common.segment.position + demux->stream_start_time;
3512 segment->position = GST_CLOCK_TIME_NONE;
3514 segment->start = clace_time;
3515 segment->stop = GST_CLOCK_TIME_NONE;
3516 segment->time = segment->start - demux->stream_start_time;
3517 segment->position = segment->start - demux->stream_start_time;
3518 GST_DEBUG_OBJECT (demux,
3519 "generated segment starting at %" GST_TIME_FORMAT ": %"
3520 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3521 /* now convey our segment notion downstream */
3522 segment_event = gst_event_new_segment (segment);
3523 if (demux->segment_seqnum)
3524 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3525 gst_matroska_demux_send_event (demux, segment_event);
3526 demux->need_segment = FALSE;
3527 demux->segment_seqnum = 0;
3530 /* send pending codec data headers for all streams,
3531 * before we perform sync across all streams */
3532 gst_matroska_demux_push_codec_data_all (demux);
3534 if (block_duration != -1) {
3535 if (stream->timecodescale == 1.0)
3536 duration = gst_util_uint64_scale (block_duration,
3537 demux->common.time_scale, 1);
3540 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3541 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3542 1)) * stream->timecodescale);
3543 } else if (stream->default_duration) {
3544 duration = stream->default_duration * laces;
3546 /* else duration is diff between timecode of this and next block */
3548 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3549 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3550 a ReferenceBlock implies that this is not a keyframe. In either
3551 case, it only makes sense for video streams. */
3552 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3554 invisible_frame = ((flags & 0x08)) &&
3555 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3556 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3559 /* If we're doing a keyframe-only trickmode, only push keyframes on video
3563 segment.flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) {
3564 GST_LOG_OBJECT (demux, "Skipping non-keyframe on stream %d",
3571 for (n = 0; n < laces; n++) {
3574 if (G_UNLIKELY (lace_size[n] > size)) {
3575 GST_WARNING_OBJECT (demux, "Invalid lace size");
3579 /* QoS for video track with an index. the assumption is that
3580 index entries point to keyframes, but if that is not true we
3581 will instad skip until the next keyframe. */
3582 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3583 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3584 stream->index_table && demux->common.segment.rate > 0.0) {
3585 GstMatroskaTrackVideoContext *videocontext =
3586 (GstMatroskaTrackVideoContext *) stream;
3587 GstClockTime earliest_time;
3588 GstClockTime earliest_stream_time;
3590 GST_OBJECT_LOCK (demux);
3591 earliest_time = videocontext->earliest_time;
3592 GST_OBJECT_UNLOCK (demux);
3593 earliest_stream_time =
3594 gst_segment_position_from_running_time (&demux->common.segment,
3595 GST_FORMAT_TIME, earliest_time);
3597 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3598 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3599 lace_time <= earliest_stream_time) {
3600 /* find index entry (keyframe) <= earliest_stream_time */
3601 GstMatroskaIndex *entry =
3602 gst_util_array_binary_search (stream->index_table->data,
3603 stream->index_table->len, sizeof (GstMatroskaIndex),
3604 (GCompareDataFunc) gst_matroska_index_seek_find,
3605 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3607 /* if that entry (keyframe) is after the current the current
3608 buffer, we can skip pushing (and thus decoding) all
3609 buffers until that keyframe. */
3610 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3611 entry->time > lace_time) {
3612 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3613 stream->set_discont = TRUE;
3619 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3620 gst_buffer_get_size (buf) - size, lace_size[n]);
3621 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3624 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3626 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3628 if (invisible_frame)
3629 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3631 if (stream->encodings != NULL && stream->encodings->len > 0)
3632 sub = gst_matroska_decode_buffer (stream, sub);
3635 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3639 if (!stream->dts_only) {
3640 GST_BUFFER_PTS (sub) = lace_time;
3642 GST_BUFFER_DTS (sub) = lace_time;
3643 if (stream->intra_only)
3644 GST_BUFFER_PTS (sub) = lace_time;
3647 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
3649 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3650 GstClockTime last_stop_end;
3652 /* Check if this stream is after segment stop */
3653 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3654 lace_time >= demux->common.segment.stop) {
3655 GST_DEBUG_OBJECT (demux,
3656 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3657 GST_TIME_ARGS (demux->common.segment.stop));
3658 gst_buffer_unref (sub);
3661 if (offset >= stream->to_offset
3662 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3663 && lace_time > demux->to_time)) {
3664 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3666 gst_buffer_unref (sub);
3670 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3671 * that landed us with timestamps not quite intended */
3672 GST_OBJECT_LOCK (demux);
3673 if (demux->max_gap_time &&
3674 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3675 demux->common.segment.rate > 0.0) {
3676 GstClockTimeDiff diff;
3678 /* only send segments with increasing start times,
3679 * otherwise if these go back and forth downstream (sinks) increase
3680 * accumulated time and running_time */
3681 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3682 if (diff > 0 && diff > demux->max_gap_time
3683 && lace_time > demux->common.segment.start
3684 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3685 || lace_time < demux->common.segment.stop)) {
3687 GST_DEBUG_OBJECT (demux,
3688 "Gap of %" G_GINT64_FORMAT " ns detected in"
3689 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3690 "Sending updated SEGMENT events", diff,
3691 stream->index, GST_TIME_ARGS (stream->pos),
3692 GST_TIME_ARGS (lace_time));
3694 event = gst_event_new_gap (demux->last_stop_end, diff);
3695 GST_OBJECT_UNLOCK (demux);
3696 gst_pad_push_event (stream->pad, event);
3697 GST_OBJECT_LOCK (demux);
3701 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3702 || demux->common.segment.position < lace_time) {
3703 demux->common.segment.position = lace_time;
3705 GST_OBJECT_UNLOCK (demux);
3707 last_stop_end = lace_time;
3709 GST_BUFFER_DURATION (sub) = duration / laces;
3710 last_stop_end += GST_BUFFER_DURATION (sub);
3713 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3714 demux->last_stop_end < last_stop_end)
3715 demux->last_stop_end = last_stop_end;
3717 GST_OBJECT_LOCK (demux);
3718 if (demux->common.segment.duration == -1 ||
3719 demux->stream_start_time + demux->common.segment.duration <
3721 demux->common.segment.duration =
3722 last_stop_end - demux->stream_start_time;
3723 GST_OBJECT_UNLOCK (demux);
3724 if (!demux->invalid_duration) {
3725 gst_element_post_message (GST_ELEMENT_CAST (demux),
3726 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3727 demux->invalid_duration = TRUE;
3730 GST_OBJECT_UNLOCK (demux);
3734 stream->pos = lace_time;
3736 gst_matroska_demux_sync_streams (demux);
3738 if (stream->set_discont) {
3739 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3740 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3741 stream->set_discont = FALSE;
3743 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3746 /* reverse playback book-keeping */
3747 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3748 stream->from_time = lace_time;
3749 if (stream->from_offset == -1)
3750 stream->from_offset = offset;
3752 GST_DEBUG_OBJECT (demux,
3753 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3754 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3755 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3756 GST_TIME_ARGS (buffer_timestamp),
3757 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3760 if (demux->common.element_index) {
3761 if (stream->index_writer_id == -1)
3762 gst_index_get_writer_id (demux->common.element_index,
3763 GST_OBJECT (stream->pad), &stream->index_writer_id);
3765 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3766 G_GUINT64_FORMAT " for writer id %d",
3767 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
3768 stream->index_writer_id);
3769 gst_index_add_association (demux->common.element_index,
3770 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3771 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3772 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
3777 /* Postprocess the buffers depending on the codec used */
3778 if (stream->postprocess_frame) {
3779 GST_LOG_OBJECT (demux, "running post process");
3780 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3783 /* At this point, we have a sub-buffer pointing at data within a larger
3784 buffer. This data might not be aligned with anything. If the data is
3785 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3786 for 32 bit samples, etc), or bad things will happen downstream as
3787 elements typically assume minimal alignment.
3788 Therefore, create an aligned copy if necessary. */
3789 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3791 if (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
3792 guint64 start_clip = 0, end_clip = 0;
3794 /* Codec delay is part of the timestamps */
3795 if (GST_BUFFER_PTS_IS_VALID (sub) && stream->codec_delay) {
3796 if (GST_BUFFER_PTS (sub) > stream->codec_delay) {
3797 GST_BUFFER_PTS (sub) -= stream->codec_delay;
3799 GST_BUFFER_PTS (sub) = 0;
3801 gst_util_uint64_scale_round (stream->codec_delay, 48000,
3804 if (GST_BUFFER_DURATION_IS_VALID (sub)) {
3805 if (GST_BUFFER_DURATION (sub) > stream->codec_delay)
3806 GST_BUFFER_DURATION (sub) -= stream->codec_delay;
3808 GST_BUFFER_DURATION (sub) = 0;
3813 if (block_discardpadding) {
3815 gst_util_uint64_scale_round (block_discardpadding, 48000,
3819 if (start_clip || end_clip) {
3820 gst_buffer_add_audio_clipping_meta (sub, GST_FORMAT_DEFAULT,
3821 start_clip, end_clip);
3825 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3826 stream->pos = GST_BUFFER_PTS (sub);
3827 if (GST_BUFFER_DURATION_IS_VALID (sub))
3828 stream->pos += GST_BUFFER_DURATION (sub);
3829 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
3830 stream->pos = GST_BUFFER_DTS (sub);
3831 if (GST_BUFFER_DURATION_IS_VALID (sub))
3832 stream->pos += GST_BUFFER_DURATION (sub);
3835 ret = gst_pad_push (stream->pad, sub);
3837 if (demux->common.segment.rate < 0) {
3838 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3839 /* In reverse playback we can get a GST_FLOW_EOS when
3840 * we are at the end of the segment, so we just need to jump
3841 * back to the previous section. */
3842 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3847 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
3851 size -= lace_size[n];
3852 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3853 lace_time += duration / laces;
3855 lace_time = GST_CLOCK_TIME_NONE;
3861 gst_buffer_unmap (buf, &map);
3862 gst_buffer_unref (buf);
3874 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
3880 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3881 /* non-fatal, try next block(group) */
3887 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3888 /* non-fatal, try next block(group) */
3894 /* return FALSE if block(group) should be skipped (due to a seek) */
3895 static inline gboolean
3896 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3898 if (G_UNLIKELY (demux->seek_block)) {
3899 if (!(--demux->seek_block)) {
3902 GST_LOG_OBJECT (demux, "should skip block due to seek");
3910 static GstFlowReturn
3911 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3915 guint64 seek_pos = (guint64) - 1;
3916 guint32 seek_id = 0;
3919 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3921 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3922 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3926 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3927 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3931 case GST_MATROSKA_ID_SEEKID:
3935 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3938 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3943 case GST_MATROSKA_ID_SEEKPOSITION:
3947 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3950 if (t > G_MAXINT64) {
3951 GST_WARNING_OBJECT (demux,
3952 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3956 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3962 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3968 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3971 if (!seek_id || seek_pos == (guint64) - 1) {
3972 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3973 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3978 case GST_MATROSKA_ID_SEEKHEAD:
3981 case GST_MATROSKA_ID_CUES:
3982 case GST_MATROSKA_ID_TAGS:
3983 case GST_MATROSKA_ID_TRACKS:
3984 case GST_MATROSKA_ID_SEGMENTINFO:
3985 case GST_MATROSKA_ID_ATTACHMENTS:
3986 case GST_MATROSKA_ID_CHAPTERS:
3988 guint64 before_pos, length;
3992 length = gst_matroska_read_common_get_length (&demux->common);
3993 before_pos = demux->common.offset;
3995 if (length == (guint64) - 1) {
3996 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
4000 /* check for validity */
4001 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
4002 GST_WARNING_OBJECT (demux,
4003 "SeekHead reference lies outside file!" " (%"
4004 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
4005 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
4010 /* only pick up index location when streaming */
4011 if (demux->streaming) {
4012 if (seek_id == GST_MATROSKA_ID_CUES) {
4013 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
4014 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
4015 demux->index_offset);
4021 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
4024 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4025 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
4029 if (id != seek_id) {
4030 GST_WARNING_OBJECT (demux,
4031 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
4032 seek_id, id, seek_pos + demux->common.ebml_segment_start);
4035 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4040 demux->common.offset = before_pos;
4044 case GST_MATROSKA_ID_CLUSTER:
4046 guint64 pos = seek_pos + demux->common.ebml_segment_start;
4048 GST_LOG_OBJECT (demux, "Cluster position");
4049 if (G_UNLIKELY (!demux->clusters))
4050 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
4051 g_array_append_val (demux->clusters, pos);
4056 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
4059 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4064 static GstFlowReturn
4065 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4067 GstFlowReturn ret = GST_FLOW_OK;
4070 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4072 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4073 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4077 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4078 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4082 case GST_MATROSKA_ID_SEEKENTRY:
4084 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
4085 /* Ignore EOS and errors here */
4086 if (ret != GST_FLOW_OK) {
4087 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4094 ret = gst_matroska_read_common_parse_skip (&demux->common,
4095 ebml, "SeekHead", id);
4100 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4102 /* Sort clusters by position for easier searching */
4103 if (demux->clusters)
4104 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4109 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
4111 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4113 static inline GstFlowReturn
4114 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4116 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4117 /* only a few blocks are expected/allowed to be large,
4118 * and will be recursed into, whereas others will be read and must fit */
4119 if (demux->streaming) {
4120 /* fatal in streaming case, as we can't step over easily */
4121 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4122 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4123 "file might be corrupt.", bytes));
4124 return GST_FLOW_ERROR;
4126 /* indicate higher level to quietly give up */
4127 GST_DEBUG_OBJECT (demux,
4128 "too large block of size %" G_GUINT64_FORMAT, bytes);
4129 return GST_FLOW_ERROR;
4136 /* returns TRUE if we truely are in error state, and should give up */
4137 static inline GstFlowReturn
4138 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4140 if (!demux->streaming && demux->next_cluster_offset > 0) {
4141 /* just repositioning to where next cluster should be and try from there */
4142 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4143 G_GUINT64_FORMAT, demux->next_cluster_offset);
4144 demux->common.offset = demux->next_cluster_offset;
4145 demux->next_cluster_offset = 0;
4151 /* sigh, one last attempt above and beyond call of duty ...;
4152 * search for cluster mark following current pos */
4153 pos = demux->common.offset;
4154 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4155 if ((ret = gst_matroska_demux_search_cluster (demux, &pos)) != GST_FLOW_OK) {
4156 /* did not work, give up */
4159 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4160 /* try that position */
4161 demux->common.offset = pos;
4167 static inline GstFlowReturn
4168 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4170 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4171 demux->common.offset += flush;
4172 if (demux->streaming) {
4175 /* hard to skip large blocks when streaming */
4176 ret = gst_matroska_demux_check_read_size (demux, flush);
4177 if (ret != GST_FLOW_OK)
4179 if (flush <= gst_adapter_available (demux->common.adapter))
4180 gst_adapter_flush (demux->common.adapter, flush);
4182 return GST_FLOW_EOS;
4187 /* initializes @ebml with @bytes from input stream at current offset.
4188 * Returns EOS if insufficient available,
4189 * ERROR if too much was attempted to read. */
4190 static inline GstFlowReturn
4191 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4194 GstBuffer *buffer = NULL;
4195 GstFlowReturn ret = GST_FLOW_OK;
4197 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4199 ret = gst_matroska_demux_check_read_size (demux, bytes);
4200 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4201 if (!demux->streaming) {
4202 /* in pull mode, we can skip */
4203 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4204 ret = GST_FLOW_OVERFLOW;
4206 /* otherwise fatal */
4207 ret = GST_FLOW_ERROR;
4211 if (demux->streaming) {
4212 if (gst_adapter_available (demux->common.adapter) >= bytes)
4213 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4217 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4218 demux->common.offset, bytes, &buffer, NULL);
4219 if (G_LIKELY (buffer)) {
4220 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4221 demux->common.offset);
4222 demux->common.offset += bytes;
4229 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4232 gboolean seekable = FALSE;
4233 gint64 start = -1, stop = -1;
4235 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4236 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4237 GST_DEBUG_OBJECT (demux, "seeking query failed");
4241 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4243 /* try harder to query upstream size if we didn't get it the first time */
4244 if (seekable && stop == -1) {
4245 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4246 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4250 /* if upstream doesn't know the size, it's likely that it's not seekable in
4251 * practice even if it technically may be seekable */
4252 if (seekable && (start != 0 || stop <= start)) {
4253 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4258 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4259 G_GUINT64_FORMAT ")", seekable, start, stop);
4260 demux->seekable = seekable;
4262 gst_query_unref (query);
4265 static GstFlowReturn
4266 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4272 GstFlowReturn ret = GST_FLOW_OK;
4274 GST_WARNING_OBJECT (demux,
4275 "Found Cluster element before Tracks, searching Tracks");
4278 before_pos = demux->common.offset;
4280 /* Search Tracks element */
4282 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4283 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4284 if (ret != GST_FLOW_OK)
4287 if (id != GST_MATROSKA_ID_TRACKS) {
4288 /* we may be skipping large cluster here, so forego size check etc */
4289 /* ... but we can't skip undefined size; force error */
4290 if (length == G_MAXUINT64) {
4291 ret = gst_matroska_demux_check_read_size (demux, length);
4294 demux->common.offset += needed;
4295 demux->common.offset += length;
4300 /* will lead to track parsing ... */
4301 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4306 demux->common.offset = before_pos;
4311 #define GST_READ_CHECK(stmt) \
4313 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4314 if (ret == GST_FLOW_OVERFLOW) { \
4315 ret = GST_FLOW_OK; \
4321 static GstFlowReturn
4322 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4323 guint64 length, guint needed)
4325 GstEbmlRead ebml = { 0, };
4326 GstFlowReturn ret = GST_FLOW_OK;
4329 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4330 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4332 /* if we plan to read and parse this element, we need prefix (id + length)
4333 * and the contents */
4334 /* mind about overflow wrap-around when dealing with undefined size */
4336 if (G_LIKELY (length != G_MAXUINT64))
4339 switch (demux->common.state) {
4340 case GST_MATROSKA_READ_STATE_START:
4342 case GST_EBML_ID_HEADER:
4343 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4344 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4345 if (ret != GST_FLOW_OK)
4347 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4348 gst_matroska_demux_check_seekability (demux);
4351 goto invalid_header;
4355 case GST_MATROSKA_READ_STATE_SEGMENT:
4357 case GST_MATROSKA_ID_SEGMENT:
4358 /* eat segment prefix */
4359 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4360 GST_DEBUG_OBJECT (demux,
4361 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4362 G_GUINT64_FORMAT, demux->common.offset, length);
4363 /* seeks are from the beginning of the segment,
4364 * after the segment ID/length */
4365 demux->common.ebml_segment_start = demux->common.offset;
4367 length = G_MAXUINT64;
4368 demux->common.ebml_segment_length = length;
4369 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4372 GST_WARNING_OBJECT (demux,
4373 "Expected a Segment ID (0x%x), but received 0x%x!",
4374 GST_MATROSKA_ID_SEGMENT, id);
4375 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4379 case GST_MATROSKA_READ_STATE_SCANNING:
4380 if (id != GST_MATROSKA_ID_CLUSTER &&
4381 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4384 case GST_MATROSKA_READ_STATE_HEADER:
4385 case GST_MATROSKA_READ_STATE_DATA:
4386 case GST_MATROSKA_READ_STATE_SEEK:
4388 case GST_MATROSKA_ID_SEGMENTINFO:
4389 if (!demux->common.segmentinfo_parsed) {
4390 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4391 ret = gst_matroska_read_common_parse_info (&demux->common,
4392 GST_ELEMENT_CAST (demux), &ebml);
4393 if (ret == GST_FLOW_OK)
4394 gst_matroska_demux_send_tags (demux);
4396 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4399 case GST_MATROSKA_ID_TRACKS:
4400 if (!demux->tracks_parsed) {
4401 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4402 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4404 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4407 case GST_MATROSKA_ID_CLUSTER:
4408 if (G_UNLIKELY (!demux->tracks_parsed)) {
4409 if (demux->streaming) {
4410 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4411 goto not_streamable;
4413 ret = gst_matroska_demux_find_tracks (demux);
4414 if (!demux->tracks_parsed)
4418 if (G_UNLIKELY (demux->common.state
4419 == GST_MATROSKA_READ_STATE_HEADER)) {
4420 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4421 demux->first_cluster_offset = demux->common.offset;
4422 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4423 gst_element_no_more_pads (GST_ELEMENT (demux));
4424 /* send initial segment - we wait till we know the first
4425 incoming timestamp, so we can properly set the start of
4427 demux->need_segment = TRUE;
4429 demux->cluster_time = GST_CLOCK_TIME_NONE;
4430 demux->cluster_offset = demux->common.offset;
4431 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4432 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4433 " not found in Cluster, trying next Cluster's first block instead",
4435 demux->seek_block = 0;
4437 demux->seek_first = FALSE;
4438 /* record next cluster for recovery */
4439 if (read != G_MAXUINT64)
4440 demux->next_cluster_offset = demux->cluster_offset + read;
4441 /* eat cluster prefix */
4442 gst_matroska_demux_flush (demux, needed);
4444 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4448 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4449 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4451 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4452 demux->cluster_time = num;
4454 if (demux->common.element_index) {
4455 if (demux->common.element_index_writer_id == -1)
4456 gst_index_get_writer_id (demux->common.element_index,
4457 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4458 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4459 G_GUINT64_FORMAT " for writer id %d",
4460 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4461 demux->common.element_index_writer_id);
4462 gst_index_add_association (demux->common.element_index,
4463 demux->common.element_index_writer_id,
4464 GST_ASSOCIATION_FLAG_KEY_UNIT,
4465 GST_FORMAT_TIME, demux->cluster_time,
4466 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4471 case GST_MATROSKA_ID_BLOCKGROUP:
4472 if (!gst_matroska_demux_seek_block (demux))
4474 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4475 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4476 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4477 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4478 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4480 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4482 case GST_MATROSKA_ID_SIMPLEBLOCK:
4483 if (!gst_matroska_demux_seek_block (demux))
4485 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4486 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4487 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4488 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4489 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4491 case GST_MATROSKA_ID_ATTACHMENTS:
4492 if (!demux->common.attachments_parsed) {
4493 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4494 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4495 GST_ELEMENT_CAST (demux), &ebml);
4496 if (ret == GST_FLOW_OK)
4497 gst_matroska_demux_send_tags (demux);
4499 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4502 case GST_MATROSKA_ID_TAGS:
4503 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4504 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4505 GST_ELEMENT_CAST (demux), &ebml);
4506 if (ret == GST_FLOW_OK)
4507 gst_matroska_demux_send_tags (demux);
4509 case GST_MATROSKA_ID_CHAPTERS:
4510 if (!demux->common.chapters_parsed) {
4511 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4513 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4515 if (demux->common.toc) {
4516 gst_matroska_demux_send_event (demux,
4517 gst_event_new_toc (demux->common.toc, FALSE));
4520 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4522 case GST_MATROSKA_ID_SEEKHEAD:
4523 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4524 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4526 case GST_MATROSKA_ID_CUES:
4527 if (demux->common.index_parsed) {
4528 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4531 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4532 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4533 /* only push based; delayed index building */
4534 if (ret == GST_FLOW_OK
4535 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4538 GST_OBJECT_LOCK (demux);
4539 event = demux->seek_event;
4540 demux->seek_event = NULL;
4541 GST_OBJECT_UNLOCK (demux);
4544 /* unlikely to fail, since we managed to seek to this point */
4545 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
4546 gst_event_unref (event);
4549 gst_event_unref (event);
4550 /* resume data handling, main thread clear to seek again */
4551 GST_OBJECT_LOCK (demux);
4552 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4553 GST_OBJECT_UNLOCK (demux);
4556 case GST_MATROSKA_ID_POSITION:
4557 case GST_MATROSKA_ID_PREVSIZE:
4558 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4559 case GST_MATROSKA_ID_SILENTTRACKS:
4560 GST_DEBUG_OBJECT (demux,
4561 "Skipping Cluster subelement 0x%x - ignoring", id);
4565 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4566 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4572 if (ret == GST_FLOW_PARSE)
4576 gst_ebml_read_clear (&ebml);
4582 /* simply exit, maybe not enough data yet */
4583 /* no ebml to clear if read error */
4588 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4589 ("Failed to parse Element 0x%x", id));
4590 ret = GST_FLOW_ERROR;
4595 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4596 ("File layout does not permit streaming"));
4597 ret = GST_FLOW_ERROR;
4602 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4603 ("No Tracks element found"));
4604 ret = GST_FLOW_ERROR;
4609 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4610 ret = GST_FLOW_ERROR;
4615 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4616 ret = GST_FLOW_ERROR;
4622 gst_matroska_demux_loop (GstPad * pad)
4624 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4630 /* If we have to close a segment, send a new segment to do this now */
4631 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4632 if (G_UNLIKELY (demux->new_segment)) {
4633 gst_matroska_demux_send_event (demux, demux->new_segment);
4634 demux->new_segment = NULL;
4638 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4639 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4640 if (ret == GST_FLOW_EOS) {
4642 } else if (ret == GST_FLOW_FLUSHING) {
4644 } else if (ret != GST_FLOW_OK) {
4645 ret = gst_matroska_demux_check_parse_error (demux);
4647 /* Only handle EOS as no error if we're outside the segment already */
4648 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4649 && demux->common.offset >=
4650 demux->common.ebml_segment_start +
4651 demux->common.ebml_segment_length))
4653 else if (ret != GST_FLOW_OK)
4659 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4660 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4663 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4664 if (ret == GST_FLOW_EOS)
4666 if (ret != GST_FLOW_OK)
4669 /* check if we're at the end of a configured segment */
4670 if (G_LIKELY (demux->common.src->len)) {
4673 g_assert (demux->common.num_streams == demux->common.src->len);
4674 for (i = 0; i < demux->common.src->len; i++) {
4675 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4677 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4678 GST_TIME_ARGS (context->pos));
4679 if (context->eos == FALSE)
4683 GST_INFO_OBJECT (demux, "All streams are EOS");
4689 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4690 demux->common.offset >= demux->cached_length)) {
4691 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4692 if (demux->common.offset == demux->cached_length) {
4693 GST_LOG_OBJECT (demux, "Reached end of stream");
4704 if (demux->common.segment.rate < 0.0) {
4705 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4706 if (ret == GST_FLOW_OK)
4713 const gchar *reason = gst_flow_get_name (ret);
4714 gboolean push_eos = FALSE;
4716 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4717 gst_pad_pause_task (demux->common.sinkpad);
4719 if (ret == GST_FLOW_EOS) {
4720 /* perform EOS logic */
4722 /* If we were in the headers, make sure we send no-more-pads.
4723 This will ensure decodebin does not get stuck thinking
4724 the chain is not complete yet, and waiting indefinitely. */
4725 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4726 if (demux->common.src->len == 0) {
4727 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4728 ("No pads created"));
4730 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4731 ("Failed to finish reading headers"));
4733 gst_element_no_more_pads (GST_ELEMENT (demux));
4736 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4739 /* for segment playback we need to post when (in stream time)
4740 * we stopped, this is either stop (when set) or the duration. */
4741 if ((stop = demux->common.segment.stop) == -1)
4742 stop = demux->last_stop_end;
4744 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4745 gst_element_post_message (GST_ELEMENT (demux),
4746 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4748 gst_matroska_demux_send_event (demux,
4749 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4753 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4754 /* for fatal errors we post an error message */
4755 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4756 ("stream stopped, reason %s", reason));
4760 /* send EOS, and prevent hanging if no streams yet */
4761 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4762 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4763 (ret == GST_FLOW_EOS)) {
4764 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4765 (NULL), ("got eos but no streams (yet)"));
4773 * Create and push a flushing seek event upstream
4776 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4782 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4785 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4786 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4787 GST_SEEK_TYPE_NONE, -1);
4788 gst_event_set_seqnum (event, seqnum);
4790 res = gst_pad_push_event (demux->common.sinkpad, event);
4792 /* segment event will update offset */
4796 static GstFlowReturn
4797 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4799 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4801 GstFlowReturn ret = GST_FLOW_OK;
4806 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4807 GST_DEBUG_OBJECT (demux, "got DISCONT");
4808 gst_adapter_clear (demux->common.adapter);
4809 GST_OBJECT_LOCK (demux);
4810 gst_matroska_read_common_reset_streams (&demux->common,
4811 GST_CLOCK_TIME_NONE, FALSE);
4812 GST_OBJECT_UNLOCK (demux);
4815 gst_adapter_push (demux->common.adapter, buffer);
4819 available = gst_adapter_available (demux->common.adapter);
4821 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4822 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4823 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4824 if (demux->common.ebml_segment_length != G_MAXUINT64
4825 && demux->common.offset >=
4826 demux->common.ebml_segment_start + demux->common.ebml_segment_length)
4831 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4832 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4833 demux->common.offset, id, length, needed, available);
4835 if (needed > available)
4838 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4839 if (ret == GST_FLOW_EOS) {
4840 /* need more data */
4842 } else if (ret != GST_FLOW_OK) {
4849 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4852 gboolean res = TRUE;
4853 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4855 GST_DEBUG_OBJECT (demux,
4856 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4858 switch (GST_EVENT_TYPE (event)) {
4859 case GST_EVENT_SEGMENT:
4861 const GstSegment *segment;
4863 /* some debug output */
4864 gst_event_parse_segment (event, &segment);
4865 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4866 GST_DEBUG_OBJECT (demux,
4867 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4870 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4871 GST_DEBUG_OBJECT (demux, "still starting");
4875 /* we only expect a BYTE segment, e.g. following a seek */
4876 if (segment->format != GST_FORMAT_BYTES) {
4877 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4881 GST_DEBUG_OBJECT (demux, "clearing segment state");
4882 GST_OBJECT_LOCK (demux);
4883 /* clear current segment leftover */
4884 gst_adapter_clear (demux->common.adapter);
4885 /* and some streaming setup */
4886 demux->common.offset = segment->start;
4887 /* accumulate base based on current position */
4888 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4889 demux->common.segment.base +=
4890 (MAX (demux->common.segment.position, demux->stream_start_time)
4891 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4892 /* do not know where we are;
4893 * need to come across a cluster and generate segment */
4894 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4895 demux->cluster_time = GST_CLOCK_TIME_NONE;
4896 demux->cluster_offset = 0;
4897 demux->need_segment = TRUE;
4898 demux->segment_seqnum = gst_event_get_seqnum (event);
4899 /* but keep some of the upstream segment */
4900 demux->common.segment.rate = segment->rate;
4901 /* also check if need to keep some of the requested seek position */
4902 if (demux->seek_offset == segment->start) {
4903 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4904 demux->common.segment.position = demux->requested_seek_time;
4906 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4908 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4909 demux->seek_offset = -1;
4910 GST_OBJECT_UNLOCK (demux);
4912 /* chain will send initial segment after pads have been added,
4913 * or otherwise come up with one */
4914 GST_DEBUG_OBJECT (demux, "eating event");
4915 gst_event_unref (event);
4921 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4922 gst_event_unref (event);
4923 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4924 (NULL), ("got eos and didn't receive a complete header object"));
4925 } else if (demux->common.num_streams == 0) {
4926 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4927 (NULL), ("got eos but no streams (yet)"));
4929 gst_matroska_demux_send_event (demux, event);
4933 case GST_EVENT_FLUSH_STOP:
4937 gst_adapter_clear (demux->common.adapter);
4938 GST_OBJECT_LOCK (demux);
4939 gst_matroska_read_common_reset_streams (&demux->common,
4940 GST_CLOCK_TIME_NONE, TRUE);
4941 gst_flow_combiner_reset (demux->flowcombiner);
4942 dur = demux->common.segment.duration;
4943 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4944 demux->common.segment.duration = dur;
4945 demux->cluster_time = GST_CLOCK_TIME_NONE;
4946 demux->cluster_offset = 0;
4947 GST_OBJECT_UNLOCK (demux);
4951 res = gst_pad_event_default (pad, parent, event);
4959 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4961 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4963 gboolean pull_mode = FALSE;
4965 query = gst_query_new_scheduling ();
4967 if (gst_pad_peer_query (sinkpad, query))
4968 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4969 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4971 gst_query_unref (query);
4974 GST_DEBUG ("going to pull mode");
4975 demux->streaming = FALSE;
4976 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4978 GST_DEBUG ("going to push (streaming) mode");
4979 demux->streaming = TRUE;
4980 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4985 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4986 GstPadMode mode, gboolean active)
4989 case GST_PAD_MODE_PULL:
4991 /* if we have a scheduler we can start the task */
4992 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4995 gst_pad_stop_task (sinkpad);
4998 case GST_PAD_MODE_PUSH:
5006 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
5007 videocontext, const gchar * codec_id, guint8 * data, guint size,
5008 gchar ** codec_name, guint32 * riff_fourcc)
5010 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
5011 GstCaps *caps = NULL;
5013 g_assert (videocontext != NULL);
5014 g_assert (codec_name != NULL);
5019 /* TODO: check if we have all codec types from matroska-ids.h
5020 * check if we have to do more special things with codec_private
5023 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
5024 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
5027 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
5028 gst_riff_strf_vids *vids = NULL;
5031 GstBuffer *buf = NULL;
5033 vids = (gst_riff_strf_vids *) data;
5035 /* assure size is big enough */
5037 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
5040 if (size < sizeof (gst_riff_strf_vids)) {
5041 vids = g_new (gst_riff_strf_vids, 1);
5042 memcpy (vids, data, size);
5045 context->dts_only = TRUE; /* VFW files only store DTS */
5047 /* little-endian -> byte-order */
5048 vids->size = GUINT32_FROM_LE (vids->size);
5049 vids->width = GUINT32_FROM_LE (vids->width);
5050 vids->height = GUINT32_FROM_LE (vids->height);
5051 vids->planes = GUINT16_FROM_LE (vids->planes);
5052 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
5053 vids->compression = GUINT32_FROM_LE (vids->compression);
5054 vids->image_size = GUINT32_FROM_LE (vids->image_size);
5055 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
5056 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
5057 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
5058 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
5060 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
5061 gsize offset = sizeof (gst_riff_strf_vids);
5064 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
5065 size - offset), size - offset);
5069 *riff_fourcc = vids->compression;
5071 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
5072 buf, NULL, codec_name);
5075 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
5076 GST_FOURCC_ARGS (vids->compression));
5078 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
5079 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
5080 "video/x-compressed-yuv");
5081 context->intra_only =
5082 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
5086 gst_buffer_unref (buf);
5088 if (vids != (gst_riff_strf_vids *) data)
5091 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
5093 GstVideoFormat format;
5095 gst_video_info_init (&info);
5096 switch (videocontext->fourcc) {
5097 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5098 format = GST_VIDEO_FORMAT_I420;
5100 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5101 format = GST_VIDEO_FORMAT_YUY2;
5103 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5104 format = GST_VIDEO_FORMAT_YV12;
5106 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5107 format = GST_VIDEO_FORMAT_UYVY;
5109 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5110 format = GST_VIDEO_FORMAT_AYUV;
5112 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
5113 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
5114 format = GST_VIDEO_FORMAT_GRAY8;
5116 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
5117 format = GST_VIDEO_FORMAT_RGB;
5119 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
5120 format = GST_VIDEO_FORMAT_BGR;
5123 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5124 GST_FOURCC_ARGS (videocontext->fourcc));
5128 context->intra_only = TRUE;
5130 gst_video_info_set_format (&info, format, videocontext->pixel_width,
5131 videocontext->pixel_height);
5132 caps = gst_video_info_to_caps (&info);
5133 *codec_name = gst_pb_utils_get_codec_description (caps);
5134 context->alignment = 32;
5135 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5136 caps = gst_caps_new_simple ("video/x-divx",
5137 "divxversion", G_TYPE_INT, 4, NULL);
5138 *codec_name = g_strdup ("MPEG-4 simple profile");
5139 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5140 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5141 caps = gst_caps_new_simple ("video/mpeg",
5142 "mpegversion", G_TYPE_INT, 4,
5143 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5147 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5148 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5149 gst_buffer_unref (priv);
5151 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
5153 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5154 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5156 *codec_name = g_strdup ("MPEG-4 advanced profile");
5157 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5159 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5160 "divxversion", G_TYPE_INT, 3, NULL),
5161 gst_structure_new ("video/x-msmpeg",
5162 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5164 caps = gst_caps_new_simple ("video/x-msmpeg",
5165 "msmpegversion", G_TYPE_INT, 43, NULL);
5166 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5167 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5168 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5171 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5176 caps = gst_caps_new_simple ("video/mpeg",
5177 "systemstream", G_TYPE_BOOLEAN, FALSE,
5178 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5179 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5180 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5181 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5182 caps = gst_caps_new_empty_simple ("image/jpeg");
5183 *codec_name = g_strdup ("Motion-JPEG");
5184 context->intra_only = TRUE;
5185 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5186 caps = gst_caps_new_empty_simple ("video/x-h264");
5190 /* First byte is the version, second is the profile indication, and third
5191 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5192 * level indication. */
5193 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5196 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5197 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5198 gst_buffer_unref (priv);
5200 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5201 "alignment", G_TYPE_STRING, "au", NULL);
5203 GST_WARNING ("No codec data found, assuming output is byte-stream");
5204 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5207 *codec_name = g_strdup ("H264");
5208 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
5209 caps = gst_caps_new_empty_simple ("video/x-h265");
5213 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
5216 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5217 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5218 gst_buffer_unref (priv);
5220 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
5221 "alignment", G_TYPE_STRING, "au", NULL);
5223 GST_WARNING ("No codec data found, assuming output is byte-stream");
5224 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5227 *codec_name = g_strdup ("HEVC");
5228 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5229 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5230 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5231 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5232 gint rmversion = -1;
5234 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5236 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5238 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5240 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5243 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5244 "rmversion", G_TYPE_INT, rmversion, NULL);
5245 GST_DEBUG ("data:%p, size:0x%x", data, size);
5246 /* We need to extract the extradata ! */
5247 if (data && (size >= 0x22)) {
5252 subformat = GST_READ_UINT32_BE (data + 0x1a);
5253 rformat = GST_READ_UINT32_BE (data + 0x1e);
5256 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5258 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5259 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5260 gst_buffer_unref (priv);
5263 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5264 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5265 caps = gst_caps_new_empty_simple ("video/x-theora");
5266 context->stream_headers =
5267 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5268 context->codec_priv_size);
5269 /* FIXME: mark stream as broken and skip if there are no stream headers */
5270 context->send_stream_headers = TRUE;
5271 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5272 caps = gst_caps_new_empty_simple ("video/x-dirac");
5273 *codec_name = g_strdup_printf ("Dirac");
5274 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5275 caps = gst_caps_new_empty_simple ("video/x-vp8");
5276 *codec_name = g_strdup_printf ("On2 VP8");
5277 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5278 caps = gst_caps_new_empty_simple ("video/x-vp9");
5279 *codec_name = g_strdup_printf ("On2 VP9");
5280 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
5282 const gchar *variant, *variant_descr = "";
5284 /* Expect a fourcc in the codec private data */
5285 if (!data || size < 4) {
5286 GST_WARNING ("No or too small PRORESS fourcc (%d bytes)", size);
5290 fourcc = GST_STR_FOURCC (data);
5292 case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
5293 variant_descr = " 4:2:2 LT";
5296 case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
5298 variant_descr = " 4:2:2 HQ";
5300 case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
5302 variant_descr = " 4:4:4:4";
5304 case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
5306 variant_descr = " 4:2:2 Proxy";
5308 case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
5310 variant = "standard";
5311 variant_descr = " 4:2:2 SD";
5315 GST_LOG ("Prores video, codec fourcc %" GST_FOURCC_FORMAT,
5316 GST_FOURCC_ARGS (fourcc));
5318 caps = gst_caps_new_simple ("video/x-prores",
5319 "format", G_TYPE_STRING, variant, NULL);
5320 *codec_name = g_strdup_printf ("Apple ProRes%s", variant_descr);
5321 context->postprocess_frame = gst_matroska_demux_add_prores_header;
5323 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5329 GstStructure *structure;
5331 for (i = 0; i < gst_caps_get_size (caps); i++) {
5332 structure = gst_caps_get_structure (caps, i);
5334 /* FIXME: use the real unit here! */
5335 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5336 videocontext->pixel_width,
5337 videocontext->pixel_height,
5338 videocontext->display_width, videocontext->display_height);
5340 /* pixel width and height are the w and h of the video in pixels */
5341 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5342 gint w = videocontext->pixel_width;
5343 gint h = videocontext->pixel_height;
5345 gst_structure_set (structure,
5346 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5349 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5352 if (videocontext->display_width <= 0)
5353 videocontext->display_width = videocontext->pixel_width;
5354 if (videocontext->display_height <= 0)
5355 videocontext->display_height = videocontext->pixel_height;
5357 /* calculate the pixel aspect ratio using the display and pixel w/h */
5358 n = videocontext->display_width * videocontext->pixel_height;
5359 d = videocontext->display_height * videocontext->pixel_width;
5360 GST_DEBUG ("setting PAR to %d/%d", n, d);
5361 gst_structure_set (structure, "pixel-aspect-ratio",
5363 videocontext->display_width * videocontext->pixel_height,
5364 videocontext->display_height * videocontext->pixel_width, NULL);
5367 if (videocontext->default_fps > 0.0) {
5370 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5372 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5374 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5376 } else if (context->default_duration > 0) {
5379 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5381 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5382 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5384 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5385 fps_n, fps_d, NULL);
5387 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5391 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5392 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5395 if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
5396 if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
5397 videocontext->pixel_width, videocontext->pixel_height,
5398 videocontext->display_width * videocontext->pixel_height,
5399 videocontext->display_height * videocontext->pixel_width)) {
5400 videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
5402 gst_caps_set_simple (caps,
5403 "multiview-mode", G_TYPE_STRING,
5404 gst_video_multiview_mode_to_caps_string
5405 (videocontext->multiview_mode), "multiview-flags",
5406 GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
5407 GST_FLAG_SET_MASK_EXACT, NULL);
5410 caps = gst_caps_simplify (caps);
5417 * Some AAC specific code... *sigh*
5418 * FIXME: maybe we should use '15' and code the sample rate explicitly
5419 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5423 aac_rate_idx (gint rate)
5427 else if (75132 <= rate)
5429 else if (55426 <= rate)
5431 else if (46009 <= rate)
5433 else if (37566 <= rate)
5435 else if (27713 <= rate)
5437 else if (23004 <= rate)
5439 else if (18783 <= rate)
5441 else if (13856 <= rate)
5443 else if (11502 <= rate)
5445 else if (9391 <= rate)
5452 aac_profile_idx (const gchar * codec_id)
5456 if (strlen (codec_id) <= 12)
5458 else if (!strncmp (&codec_id[12], "MAIN", 4))
5460 else if (!strncmp (&codec_id[12], "LC", 2))
5462 else if (!strncmp (&codec_id[12], "SSR", 3))
5471 round_up_pow2 (guint n)
5482 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5485 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5486 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5487 gchar ** codec_name, guint16 * riff_audio_fmt)
5489 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5490 GstCaps *caps = NULL;
5492 g_assert (audiocontext != NULL);
5493 g_assert (codec_name != NULL);
5496 *riff_audio_fmt = 0;
5498 /* TODO: check if we have all codec types from matroska-ids.h
5499 * check if we have to do more special things with codec_private
5500 * check if we need bitdepth in different places too
5501 * implement channel position magic
5503 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5504 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5505 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5506 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5509 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5510 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5511 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5514 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5516 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5521 caps = gst_caps_new_simple ("audio/mpeg",
5522 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5523 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5524 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5525 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5528 GstAudioFormat format;
5530 sign = (audiocontext->bitdepth != 8);
5531 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5532 endianness = G_BIG_ENDIAN;
5534 endianness = G_LITTLE_ENDIAN;
5536 format = gst_audio_format_build_integer (sign, endianness,
5537 audiocontext->bitdepth, audiocontext->bitdepth);
5539 /* FIXME: Channel mask and reordering */
5540 caps = gst_caps_new_simple ("audio/x-raw",
5541 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5542 "layout", G_TYPE_STRING, "interleaved",
5543 "channel-mask", GST_TYPE_BITMASK,
5544 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5546 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5547 audiocontext->bitdepth);
5548 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5549 context->alignment = round_up_pow2 (context->alignment);
5550 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5551 const gchar *format;
5552 if (audiocontext->bitdepth == 32)
5556 /* FIXME: Channel mask and reordering */
5557 caps = gst_caps_new_simple ("audio/x-raw",
5558 "format", G_TYPE_STRING, format,
5559 "layout", G_TYPE_STRING, "interleaved",
5560 "channel-mask", GST_TYPE_BITMASK,
5561 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5562 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5563 audiocontext->bitdepth);
5564 context->alignment = audiocontext->bitdepth / 8;
5565 context->alignment = round_up_pow2 (context->alignment);
5566 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5567 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5568 caps = gst_caps_new_simple ("audio/x-ac3",
5569 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5570 *codec_name = g_strdup ("AC-3 audio");
5571 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5572 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5573 caps = gst_caps_new_simple ("audio/x-eac3",
5574 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5575 *codec_name = g_strdup ("E-AC-3 audio");
5576 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5577 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5578 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5579 *codec_name = g_strdup ("Dolby TrueHD");
5580 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5581 caps = gst_caps_new_empty_simple ("audio/x-dts");
5582 *codec_name = g_strdup ("DTS audio");
5583 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5584 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5585 context->stream_headers =
5586 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5587 context->codec_priv_size);
5588 /* FIXME: mark stream as broken and skip if there are no stream headers */
5589 context->send_stream_headers = TRUE;
5590 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5591 caps = gst_caps_new_empty_simple ("audio/x-flac");
5592 context->stream_headers =
5593 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5594 context->codec_priv_size);
5595 /* FIXME: mark stream as broken and skip if there are no stream headers */
5596 context->send_stream_headers = TRUE;
5597 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5598 caps = gst_caps_new_empty_simple ("audio/x-speex");
5599 context->stream_headers =
5600 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5601 context->codec_priv_size);
5602 /* FIXME: mark stream as broken and skip if there are no stream headers */
5603 context->send_stream_headers = TRUE;
5604 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5607 if (context->codec_priv_size >= 19) {
5608 if (audiocontext->samplerate)
5609 GST_WRITE_UINT32_LE ((guint8 *) context->codec_priv + 12,
5610 audiocontext->samplerate);
5611 if (context->codec_delay) {
5613 gst_util_uint64_scale_round (context->codec_delay, 48000,
5615 GST_WRITE_UINT16_LE ((guint8 *) context->codec_priv + 10, delay);
5619 gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5620 context->codec_priv_size), context->codec_priv_size);
5621 caps = gst_codec_utils_opus_create_caps_from_header (tmp, NULL);
5622 gst_buffer_unref (tmp);
5623 *codec_name = g_strdup ("Opus");
5624 } else if (context->codec_priv_size == 0) {
5625 GST_WARNING ("No Opus codec data found, trying to create one");
5626 if (audiocontext->channels <= 2) {
5627 guint8 streams, coupled, channels;
5631 audiocontext->samplerate == 0 ? 48000 : audiocontext->samplerate;
5632 channels = audiocontext->channels == 0 ? 2 : audiocontext->channels;
5633 if (channels == 1) {
5642 gst_codec_utils_opus_create_caps (samplerate, channels, 0, streams,
5645 *codec_name = g_strdup ("Opus");
5647 GST_WARNING ("Failed to create Opus caps from audio context");
5650 GST_WARNING ("No Opus codec data, and not enough info to create one");
5653 GST_WARNING ("Invalid Opus codec data size (got %" G_GSIZE_FORMAT
5654 ", expected 19)", context->codec_priv_size);
5656 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5657 gst_riff_strf_auds auds;
5659 if (data && size >= 18) {
5660 GstBuffer *codec_data = NULL;
5662 /* little-endian -> byte-order */
5663 auds.format = GST_READ_UINT16_LE (data);
5664 auds.channels = GST_READ_UINT16_LE (data + 2);
5665 auds.rate = GST_READ_UINT32_LE (data + 4);
5666 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5667 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5668 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5670 /* 18 is the waveformatex size */
5672 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5673 data + 18, size - 18, 0, size - 18, NULL, NULL);
5677 *riff_audio_fmt = auds.format;
5679 /* FIXME: Handle reorder map */
5680 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5681 codec_data, codec_name, NULL);
5683 gst_buffer_unref (codec_data);
5686 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5689 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5691 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5692 GstBuffer *priv = NULL;
5694 gint rate_idx, profile;
5695 guint8 *data = NULL;
5697 /* unspecified AAC profile with opaque private codec data */
5698 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5699 if (context->codec_priv_size >= 2) {
5700 guint obj_type, freq_index, explicit_freq_bytes = 0;
5702 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5704 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5705 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5706 if (freq_index == 15)
5707 explicit_freq_bytes = 3;
5708 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5709 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5710 context->codec_priv_size), context->codec_priv_size);
5711 /* assume SBR if samplerate <= 24kHz */
5712 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5713 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5714 audiocontext->samplerate *= 2;
5717 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5718 /* this is pretty broken;
5719 * maybe we need to make up some default private,
5720 * or maybe ADTS data got dumped in.
5721 * Let's set up some private data now, and check actual data later */
5722 /* just try this and see what happens ... */
5723 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5724 context->postprocess_frame = gst_matroska_demux_check_aac;
5728 /* make up decoder-specific data if it is not supplied */
5732 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5733 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5735 rate_idx = aac_rate_idx (audiocontext->samplerate);
5736 profile = aac_profile_idx (codec_id);
5738 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5739 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5741 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5742 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5744 gst_buffer_unmap (priv, &map);
5745 gst_buffer_set_size (priv, 2);
5746 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5747 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5750 if (g_strrstr (codec_id, "SBR")) {
5751 /* HE-AAC (aka SBR AAC) */
5752 audiocontext->samplerate *= 2;
5753 rate_idx = aac_rate_idx (audiocontext->samplerate);
5754 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5755 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5756 data[4] = (1 << 7) | (rate_idx << 3);
5757 gst_buffer_unmap (priv, &map);
5759 gst_buffer_unmap (priv, &map);
5760 gst_buffer_set_size (priv, 2);
5763 gst_buffer_unmap (priv, &map);
5764 gst_buffer_unref (priv);
5766 GST_ERROR ("Unknown AAC profile and no codec private data");
5771 caps = gst_caps_new_simple ("audio/mpeg",
5772 "mpegversion", G_TYPE_INT, mpegversion,
5773 "framed", G_TYPE_BOOLEAN, TRUE,
5774 "stream-format", G_TYPE_STRING, "raw", NULL);
5775 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5776 if (context->codec_priv && context->codec_priv_size > 0)
5777 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5778 context->codec_priv, context->codec_priv_size);
5779 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5780 gst_buffer_unref (priv);
5782 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5783 caps = gst_caps_new_simple ("audio/x-tta",
5784 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5785 *codec_name = g_strdup ("TTA audio");
5786 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5787 caps = gst_caps_new_simple ("audio/x-wavpack",
5788 "width", G_TYPE_INT, audiocontext->bitdepth,
5789 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5790 *codec_name = g_strdup ("Wavpack audio");
5791 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5792 audiocontext->wvpk_block_index = 0;
5793 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5794 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5795 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5796 gint raversion = -1;
5798 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5800 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5805 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5806 "raversion", G_TYPE_INT, raversion, NULL);
5807 /* Extract extra information from caps, mapping varies based on codec */
5808 if (data && (size >= 0x50)) {
5815 guint extra_data_size;
5817 GST_ERROR ("real audio raversion:%d", raversion);
5818 if (raversion == 8) {
5820 flavor = GST_READ_UINT16_BE (data + 22);
5821 packet_size = GST_READ_UINT32_BE (data + 24);
5822 height = GST_READ_UINT16_BE (data + 40);
5823 leaf_size = GST_READ_UINT16_BE (data + 44);
5824 sample_width = GST_READ_UINT16_BE (data + 58);
5825 extra_data_size = GST_READ_UINT32_BE (data + 74);
5828 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5829 flavor, packet_size, height, leaf_size, sample_width,
5831 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5832 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5833 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5835 if ((size - 78) >= extra_data_size) {
5836 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5838 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5839 gst_buffer_unref (priv);
5844 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5845 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5846 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5847 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5848 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5849 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5850 *codec_name = g_strdup ("Real Audio Lossless");
5851 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5852 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5853 *codec_name = g_strdup ("Sony ATRAC3");
5855 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5860 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5863 for (i = 0; i < gst_caps_get_size (caps); i++) {
5864 gst_structure_set (gst_caps_get_structure (caps, i),
5865 "channels", G_TYPE_INT, audiocontext->channels,
5866 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5870 caps = gst_caps_simplify (caps);
5877 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5878 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5880 GstCaps *caps = NULL;
5881 GstMatroskaTrackContext *context =
5882 (GstMatroskaTrackContext *) subtitlecontext;
5884 /* for backwards compatibility */
5885 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5886 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5887 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5888 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5889 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5890 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5891 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5892 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5894 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5895 * Check if we have to do something with codec_private */
5896 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5897 /* well, plain text simply does not have a lot of markup ... */
5898 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5899 "pango-markup", NULL);
5900 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5901 subtitlecontext->check_markup = TRUE;
5902 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5903 caps = gst_caps_new_empty_simple ("application/x-ssa");
5904 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5905 subtitlecontext->check_markup = FALSE;
5906 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5907 caps = gst_caps_new_empty_simple ("application/x-ass");
5908 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5909 subtitlecontext->check_markup = FALSE;
5910 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5911 caps = gst_caps_new_empty_simple ("application/x-usf");
5912 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5913 subtitlecontext->check_markup = FALSE;
5914 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5915 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5916 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5917 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5918 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5919 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5920 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5921 context->stream_headers =
5922 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5923 context->codec_priv_size);
5924 /* FIXME: mark stream as broken and skip if there are no stream headers */
5925 context->send_stream_headers = TRUE;
5927 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5928 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5931 if (data != NULL && size > 0) {
5934 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5935 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5936 gst_buffer_unref (buf);
5944 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5946 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5948 GST_OBJECT_LOCK (demux);
5949 if (demux->common.element_index)
5950 gst_object_unref (demux->common.element_index);
5951 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5952 GST_OBJECT_UNLOCK (demux);
5953 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5954 demux->common.element_index);
5958 gst_matroska_demux_get_index (GstElement * element)
5960 GstIndex *result = NULL;
5961 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5963 GST_OBJECT_LOCK (demux);
5964 if (demux->common.element_index)
5965 result = gst_object_ref (demux->common.element_index);
5966 GST_OBJECT_UNLOCK (demux);
5968 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5974 static GstStateChangeReturn
5975 gst_matroska_demux_change_state (GstElement * element,
5976 GstStateChange transition)
5978 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5979 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5981 /* handle upwards state changes here */
5982 switch (transition) {
5987 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5989 /* handle downwards state changes */
5990 switch (transition) {
5991 case GST_STATE_CHANGE_PAUSED_TO_READY:
5992 gst_matroska_demux_reset (GST_ELEMENT (demux));
6002 gst_matroska_demux_set_property (GObject * object,
6003 guint prop_id, const GValue * value, GParamSpec * pspec)
6005 GstMatroskaDemux *demux;
6007 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6008 demux = GST_MATROSKA_DEMUX (object);
6011 case PROP_MAX_GAP_TIME:
6012 GST_OBJECT_LOCK (demux);
6013 demux->max_gap_time = g_value_get_uint64 (value);
6014 GST_OBJECT_UNLOCK (demux);
6017 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6023 gst_matroska_demux_get_property (GObject * object,
6024 guint prop_id, GValue * value, GParamSpec * pspec)
6026 GstMatroskaDemux *demux;
6028 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6029 demux = GST_MATROSKA_DEMUX (object);
6032 case PROP_MAX_GAP_TIME:
6033 GST_OBJECT_LOCK (demux);
6034 g_value_set_uint64 (value, demux->max_gap_time);
6035 GST_OBJECT_UNLOCK (demux);
6038 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6044 gst_matroska_demux_plugin_init (GstPlugin * plugin)
6048 /* parser helper separate debug */
6049 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
6050 0, "EBML stream helper class");
6052 /* create an elementfactory for the matroska_demux element */
6053 if (!gst_element_register (plugin, "matroskademux",
6054 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))