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, context->uid);
1300 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1303 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1304 demux->have_group_id = TRUE;
1306 demux->have_group_id = FALSE;
1307 gst_event_unref (stream_start);
1308 } else if (!demux->have_group_id) {
1309 demux->have_group_id = TRUE;
1310 demux->group_id = gst_util_group_id_next ();
1313 stream_start = gst_event_new_stream_start (stream_id);
1315 if (demux->have_group_id)
1316 gst_event_set_group_id (stream_start, demux->group_id);
1317 stream_flags = GST_STREAM_FLAG_NONE;
1318 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1319 stream_flags |= GST_STREAM_FLAG_SPARSE;
1320 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1321 stream_flags |= GST_STREAM_FLAG_SELECT;
1322 gst_event_set_stream_flags (stream_start, stream_flags);
1323 gst_pad_push_event (context->pad, stream_start);
1324 gst_pad_set_caps (context->pad, context->caps);
1327 if (demux->common.global_tags) {
1328 GstEvent *tag_event;
1330 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1331 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1332 GST_DEBUG_OBJECT (context->pad, "Sending global_tags %p: %" GST_PTR_FORMAT,
1333 demux->common.global_tags, demux->common.global_tags);
1336 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1338 gst_pad_push_event (context->pad, tag_event);
1341 if (G_UNLIKELY (context->tags_changed)) {
1342 GST_DEBUG_OBJECT (context->pad, "Sending tags %p: %"
1343 GST_PTR_FORMAT, context->tags, context->tags);
1344 gst_pad_push_event (context->pad,
1345 gst_event_new_tag (gst_tag_list_copy (context->tags)));
1346 context->tags_changed = FALSE;
1349 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1350 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1359 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1362 gboolean res = FALSE;
1363 GstMatroskaTrackContext *context = NULL;
1366 context = gst_pad_get_element_private (pad);
1369 switch (GST_QUERY_TYPE (query)) {
1370 case GST_QUERY_POSITION:
1374 gst_query_parse_position (query, &format, NULL);
1377 if (format == GST_FORMAT_TIME) {
1378 GST_OBJECT_LOCK (demux);
1380 gst_query_set_position (query, GST_FORMAT_TIME,
1381 MAX (context->pos, demux->stream_start_time) -
1382 demux->stream_start_time);
1384 gst_query_set_position (query, GST_FORMAT_TIME,
1385 MAX (demux->common.segment.position, demux->stream_start_time) -
1386 demux->stream_start_time);
1387 GST_OBJECT_UNLOCK (demux);
1388 } else if (format == GST_FORMAT_DEFAULT && context
1389 && context->default_duration) {
1390 GST_OBJECT_LOCK (demux);
1391 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1392 context->pos / context->default_duration);
1393 GST_OBJECT_UNLOCK (demux);
1395 GST_DEBUG_OBJECT (demux,
1396 "only position query in TIME and DEFAULT format is supported");
1402 case GST_QUERY_DURATION:
1406 gst_query_parse_duration (query, &format, NULL);
1409 if (format == GST_FORMAT_TIME) {
1410 GST_OBJECT_LOCK (demux);
1411 gst_query_set_duration (query, GST_FORMAT_TIME,
1412 demux->common.segment.duration);
1413 GST_OBJECT_UNLOCK (demux);
1414 } else if (format == GST_FORMAT_DEFAULT && context
1415 && context->default_duration) {
1416 GST_OBJECT_LOCK (demux);
1417 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1418 demux->common.segment.duration / context->default_duration);
1419 GST_OBJECT_UNLOCK (demux);
1421 GST_DEBUG_OBJECT (demux,
1422 "only duration query in TIME and DEFAULT format is supported");
1428 case GST_QUERY_SEEKING:
1432 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1433 GST_OBJECT_LOCK (demux);
1434 if (fmt == GST_FORMAT_TIME) {
1437 if (demux->streaming) {
1438 /* assuming we'll be able to get an index ... */
1439 seekable = demux->seekable;
1444 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1445 0, demux->common.segment.duration);
1448 GST_OBJECT_UNLOCK (demux);
1451 case GST_QUERY_SEGMENT:
1456 format = demux->common.segment.format;
1459 gst_segment_to_stream_time (&demux->common.segment, format,
1460 demux->common.segment.start);
1461 if ((stop = demux->common.segment.stop) == -1)
1462 stop = demux->common.segment.duration;
1465 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1467 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1474 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1477 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1486 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1488 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1492 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1495 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1497 return gst_matroska_demux_query (demux, pad, query);
1500 /* returns FALSE if there are no pads to deliver event to,
1501 * otherwise TRUE (whatever the outcome of event sending),
1502 * takes ownership of the passed event! */
1504 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1506 gboolean ret = FALSE;
1509 g_return_val_if_fail (event != NULL, FALSE);
1511 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1512 GST_EVENT_TYPE_NAME (event));
1514 g_assert (demux->common.src->len == demux->common.num_streams);
1515 for (i = 0; i < demux->common.src->len; i++) {
1516 GstMatroskaTrackContext *stream;
1518 stream = g_ptr_array_index (demux->common.src, i);
1519 gst_event_ref (event);
1520 gst_pad_push_event (stream->pad, event);
1524 gst_event_unref (event);
1529 gst_matroska_demux_send_tags (GstMatroskaDemux * demux)
1533 if (G_UNLIKELY (demux->common.global_tags_changed)) {
1534 GstEvent *tag_event;
1535 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1536 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1537 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1538 demux->common.global_tags, demux->common.global_tags);
1541 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1543 for (i = 0; i < demux->common.src->len; i++) {
1544 GstMatroskaTrackContext *stream;
1546 stream = g_ptr_array_index (demux->common.src, i);
1547 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1550 gst_event_unref (tag_event);
1551 demux->common.global_tags_changed = FALSE;
1554 g_assert (demux->common.src->len == demux->common.num_streams);
1555 for (i = 0; i < demux->common.src->len; i++) {
1556 GstMatroskaTrackContext *stream;
1558 stream = g_ptr_array_index (demux->common.src, i);
1560 if (G_UNLIKELY (stream->tags_changed)) {
1561 GST_DEBUG_OBJECT (demux, "Sending tags %p for pad %s:%s : %"
1562 GST_PTR_FORMAT, stream->tags,
1563 GST_DEBUG_PAD_NAME (stream->pad), stream->tags);
1564 gst_pad_push_event (stream->pad,
1565 gst_event_new_tag (gst_tag_list_copy (stream->tags)));
1566 stream->tags_changed = FALSE;
1572 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1574 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1577 g_return_val_if_fail (event != NULL, FALSE);
1579 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1580 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1582 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1583 GST_EVENT_TYPE_NAME (event));
1586 gst_event_unref (event);
1591 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1592 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1596 GST_OBJECT_LOCK (demux);
1599 /* seek (relative to matroska segment) */
1600 /* position might be invalid; will error when streaming resumes ... */
1601 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1602 demux->next_cluster_offset = 0;
1604 GST_DEBUG_OBJECT (demux,
1605 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1606 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1607 entry->block, GST_TIME_ARGS (entry->time));
1609 /* update the time */
1610 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1611 gst_flow_combiner_reset (demux->flowcombiner);
1612 demux->common.segment.position = entry->time;
1613 demux->seek_block = entry->block;
1614 demux->seek_first = TRUE;
1615 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1618 for (i = 0; i < demux->common.src->len; i++) {
1619 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1622 stream->to_offset = G_MAXINT64;
1624 if (stream->from_offset != -1)
1625 stream->to_offset = stream->from_offset;
1627 stream->from_offset = -1;
1628 stream->from_time = GST_CLOCK_TIME_NONE;
1631 GST_OBJECT_UNLOCK (demux);
1637 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1647 /* searches for a cluster start from @pos,
1648 * return GST_FLOW_OK and cluster position in @pos if found */
1649 static GstFlowReturn
1650 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1652 gint64 newpos = *pos;
1654 GstFlowReturn ret = GST_FLOW_OK;
1655 const guint chunk = 64 * 1024;
1656 GstBuffer *buf = NULL;
1658 gpointer data = NULL;
1663 gint64 oldpos, oldlength;
1665 orig_offset = demux->common.offset;
1667 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1670 if (demux->clusters) {
1673 cpos = gst_util_array_binary_search (demux->clusters->data,
1674 demux->clusters->len, sizeof (gint64),
1675 (GCompareDataFunc) gst_matroska_cluster_compare,
1676 GST_SEARCH_MODE_AFTER, pos, NULL);
1679 GST_DEBUG_OBJECT (demux,
1680 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1681 demux->common.offset = *cpos;
1682 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1683 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1684 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1691 /* read in at newpos and scan for ebml cluster id */
1692 oldpos = oldlength = -1;
1694 GstByteReader reader;
1698 gst_buffer_unmap (buf, &map);
1699 gst_buffer_unref (buf);
1702 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1703 if (ret != GST_FLOW_OK)
1705 GST_DEBUG_OBJECT (demux,
1706 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1707 gst_buffer_get_size (buf), newpos);
1708 gst_buffer_map (buf, &map, GST_MAP_READ);
1711 if (oldpos == newpos && oldlength == map.size) {
1712 GST_ERROR_OBJECT (demux, "Stuck at same position");
1713 ret = GST_FLOW_ERROR;
1717 oldlength = map.size;
1720 gst_byte_reader_init (&reader, data, size);
1722 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1723 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1724 if (cluster_pos >= 0) {
1725 newpos += cluster_pos;
1726 /* prepare resuming at next byte */
1727 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1728 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1731 GST_DEBUG_OBJECT (demux,
1732 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1733 /* extra checks whether we really sync'ed to a cluster:
1734 * - either it is the first and only cluster
1735 * - either there is a cluster after this one
1736 * - either cluster length is undefined
1738 /* ok if first cluster (there may not a subsequent one) */
1739 if (newpos == demux->first_cluster_offset) {
1740 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1743 demux->common.offset = newpos;
1744 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1745 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1746 if (ret != GST_FLOW_OK) {
1747 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1750 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1751 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1753 /* ok if undefined length or first cluster */
1754 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1755 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1759 demux->common.offset += length + needed;
1760 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1761 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1762 if (ret != GST_FLOW_OK)
1764 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1765 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1766 if (id == GST_MATROSKA_ID_CLUSTER)
1768 /* not ok, resume */
1771 /* partial cluster id may have been in tail of buffer */
1772 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1777 gst_buffer_unmap (buf, &map);
1778 gst_buffer_unref (buf);
1783 demux->common.offset = orig_offset;
1788 /* bisect and scan through file for cluster starting before @time,
1789 * returns fake index entry with corresponding info on cluster */
1790 static GstMatroskaIndex *
1791 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1793 GstMatroskaIndex *entry = NULL;
1794 GstMatroskaReadState current_state;
1795 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1796 gint64 opos, newpos, startpos = 0, current_offset;
1797 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1798 const guint chunk = 64 * 1024;
1804 /* (under)estimate new position, resync using cluster ebml id,
1805 * and scan forward to appropriate cluster
1806 * (and re-estimate if need to go backward) */
1808 prev_cluster_time = GST_CLOCK_TIME_NONE;
1810 /* store some current state */
1811 current_state = demux->common.state;
1812 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1814 current_cluster_offset = demux->cluster_offset;
1815 current_cluster_time = demux->cluster_time;
1816 current_offset = demux->common.offset;
1818 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1820 /* estimate using start and current position */
1821 GST_OBJECT_LOCK (demux);
1822 opos = demux->common.offset - demux->common.ebml_segment_start;
1823 otime = demux->common.segment.position;
1824 GST_OBJECT_UNLOCK (demux);
1827 time = MAX (time, demux->stream_start_time);
1829 /* avoid division by zero in first estimation below */
1830 if (otime <= demux->stream_start_time)
1834 GST_LOG_OBJECT (demux,
1835 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1836 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1837 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1838 GST_TIME_ARGS (otime - demux->stream_start_time),
1839 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1841 if (otime <= demux->stream_start_time) {
1845 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1846 time - demux->stream_start_time,
1847 otime - demux->stream_start_time) - chunk;
1851 /* favour undershoot */
1852 newpos = newpos * 90 / 100;
1853 newpos += demux->common.ebml_segment_start;
1855 GST_DEBUG_OBJECT (demux,
1856 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1857 GST_TIME_ARGS (time), newpos);
1859 /* and at least start scanning before previous scan start to avoid looping */
1860 startpos = startpos * 90 / 100;
1861 if (startpos && startpos < newpos)
1864 /* read in at newpos and scan for ebml cluster id */
1868 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1869 if (ret == GST_FLOW_EOS) {
1870 /* heuristic HACK */
1871 newpos = startpos * 80 / 100;
1872 GST_DEBUG_OBJECT (demux, "EOS; "
1873 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1874 GST_TIME_ARGS (time), newpos);
1877 } else if (ret != GST_FLOW_OK) {
1884 /* then start scanning and parsing for cluster time,
1885 * re-estimate if overshoot, otherwise next cluster and so on */
1886 demux->common.offset = newpos;
1887 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1889 guint64 cluster_size = 0;
1891 /* peek and parse some elements */
1892 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1893 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1894 if (ret != GST_FLOW_OK)
1896 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1897 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1899 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1900 if (ret != GST_FLOW_OK)
1903 if (id == GST_MATROSKA_ID_CLUSTER) {
1904 cluster_time = GST_CLOCK_TIME_NONE;
1905 if (length == G_MAXUINT64)
1908 cluster_size = length + needed;
1910 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1911 cluster_time == GST_CLOCK_TIME_NONE) {
1912 cluster_time = demux->cluster_time * demux->common.time_scale;
1913 cluster_offset = demux->cluster_offset;
1914 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1915 " with time %" GST_TIME_FORMAT, cluster_offset,
1916 GST_TIME_ARGS (cluster_time));
1917 if (cluster_time > time) {
1918 GST_DEBUG_OBJECT (demux, "overshot target");
1919 /* cluster overshoots */
1920 if (cluster_offset == demux->first_cluster_offset) {
1921 /* but no prev one */
1922 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1923 prev_cluster_time = cluster_time;
1924 prev_cluster_offset = cluster_offset;
1927 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1928 /* prev cluster did not overshoot, so prev cluster is target */
1931 /* re-estimate using this new position info */
1932 opos = cluster_offset;
1933 otime = cluster_time;
1937 /* cluster undershoots, goto next one */
1938 prev_cluster_time = cluster_time;
1939 prev_cluster_offset = cluster_offset;
1940 /* skip cluster if length is defined,
1941 * otherwise will be skippingly parsed into */
1943 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1944 demux->common.offset = cluster_offset + cluster_size;
1945 demux->cluster_time = GST_CLOCK_TIME_NONE;
1947 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1954 if (ret == GST_FLOW_EOS) {
1955 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1961 entry = g_new0 (GstMatroskaIndex, 1);
1962 entry->time = prev_cluster_time;
1963 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1964 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1965 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1969 /* restore some state */
1970 demux->cluster_offset = current_cluster_offset;
1971 demux->cluster_time = current_cluster_time;
1972 demux->common.offset = current_offset;
1973 demux->common.state = current_state;
1979 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1980 GstPad * pad, GstEvent * event)
1982 GstMatroskaIndex *entry = NULL;
1983 GstMatroskaIndex scan_entry;
1985 GstSeekType cur_type, stop_type;
1987 gboolean flush, keyunit, before, after, snap_next;
1990 GstMatroskaTrackContext *track = NULL;
1991 GstSegment seeksegment = { 0, };
1992 gboolean update = TRUE;
1993 gboolean pad_locked = FALSE;
1995 GstSearchMode snap_dir;
1997 g_return_val_if_fail (event != NULL, FALSE);
2000 track = gst_pad_get_element_private (pad);
2002 GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
2004 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2006 seqnum = gst_event_get_seqnum (event);
2008 /* we can only seek on time */
2009 if (format != GST_FORMAT_TIME) {
2010 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2014 /* copy segment, we need this because we still need the old
2015 * segment when we close the current segment. */
2016 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
2018 /* pull mode without index means that the actual duration is not known,
2019 * we might be playing a file that's still being recorded
2020 * so, invalidate our current duration, which is only a moving target,
2021 * and should not be used to clamp anything */
2022 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
2023 seeksegment.duration = GST_CLOCK_TIME_NONE;
2026 GST_DEBUG_OBJECT (demux, "configuring seek");
2027 /* Subtract stream_start_time so we always seek on a segment
2029 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2030 seeksegment.start -= demux->stream_start_time;
2031 seeksegment.position -= demux->stream_start_time;
2032 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2033 seeksegment.stop -= demux->stream_start_time;
2035 seeksegment.stop = seeksegment.duration;
2038 gst_segment_do_seek (&seeksegment, rate, format, flags,
2039 cur_type, cur, stop_type, stop, &update);
2041 /* Restore the clip timestamp offset */
2042 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2043 seeksegment.position += demux->stream_start_time;
2044 seeksegment.start += demux->stream_start_time;
2045 if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2046 seeksegment.stop = seeksegment.duration;
2047 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2048 seeksegment.stop += demux->stream_start_time;
2051 /* restore segment duration (if any effect),
2052 * would be determined again when parsing, but anyway ... */
2053 seeksegment.duration = demux->common.segment.duration;
2055 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2056 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2057 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
2058 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
2060 /* always do full update if flushing,
2061 * otherwise problems might arise downstream with missing keyframes etc */
2062 update = update || flush;
2064 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2066 /* check sanity before we start flushing and all that */
2067 snap_next = after && !before;
2068 if (seeksegment.rate < 0)
2069 snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
2071 snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
2073 GST_OBJECT_LOCK (demux);
2074 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2075 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2076 seeksegment.position, &demux->seek_index, &demux->seek_entry,
2077 snap_dir)) == NULL) {
2078 /* pull mode without index can scan later on */
2079 if (demux->streaming) {
2080 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2081 GST_OBJECT_UNLOCK (demux);
2083 } else if (rate < 0.0) {
2084 /* FIXME: We should build an index during playback or when scanning
2085 * that can be used here. The reverse playback code requires seek_index
2086 * and seek_entry to be set!
2088 GST_DEBUG_OBJECT (demux,
2089 "No matching seek entry in index, needed for reverse playback");
2090 GST_OBJECT_UNLOCK (demux);
2094 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2095 GST_OBJECT_UNLOCK (demux);
2098 /* only have to update some segment,
2099 * but also still have to honour flush and so on */
2100 GST_DEBUG_OBJECT (demux, "... no update");
2101 /* bad goto, bad ... */
2105 if (demux->streaming)
2110 GstEvent *flush_event = gst_event_new_flush_start ();
2111 gst_event_set_seqnum (flush_event, seqnum);
2112 GST_DEBUG_OBJECT (demux, "Starting flush");
2113 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2114 gst_matroska_demux_send_event (demux, flush_event);
2116 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2117 gst_pad_pause_task (demux->common.sinkpad);
2121 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2126 /* now grab the stream lock so that streaming cannot continue, for
2127 * non flushing seeks when the element is in PAUSED this could block
2129 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2130 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2133 /* pull mode without index can do some scanning */
2134 if (!demux->streaming && !entry) {
2135 GstEvent *flush_event;
2137 /* need to stop flushing upstream as we need it next */
2139 flush_event = gst_event_new_flush_stop (TRUE);
2140 gst_event_set_seqnum (flush_event, seqnum);
2141 gst_pad_push_event (demux->common.sinkpad, flush_event);
2143 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2144 /* keep local copy */
2146 scan_entry = *entry;
2148 entry = &scan_entry;
2150 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2152 flush_event = gst_event_new_flush_stop (TRUE);
2153 gst_event_set_seqnum (flush_event, seqnum);
2154 gst_matroska_demux_send_event (demux, flush_event);
2162 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2163 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2164 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2165 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2166 seeksegment.position = seeksegment.start;
2167 seeksegment.time = seeksegment.start - demux->stream_start_time;
2170 if (demux->streaming) {
2171 GST_OBJECT_LOCK (demux);
2172 /* track real position we should start at */
2173 GST_DEBUG_OBJECT (demux, "storing segment start");
2174 demux->requested_seek_time = seeksegment.position;
2175 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2176 GST_OBJECT_UNLOCK (demux);
2177 /* need to seek to cluster start to pick up cluster time */
2178 /* upstream takes care of flushing and all that
2179 * ... and newsegment event handling takes care of the rest */
2180 return perform_seek_to_offset (demux, rate,
2181 entry->pos + demux->common.ebml_segment_start, seqnum);
2186 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2187 gst_event_set_seqnum (flush_event, seqnum);
2188 GST_DEBUG_OBJECT (demux, "Stopping flush");
2189 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2190 gst_matroska_demux_send_event (demux, flush_event);
2193 GST_OBJECT_LOCK (demux);
2194 /* now update the real segment info */
2195 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2196 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2197 GST_OBJECT_UNLOCK (demux);
2199 /* update some (segment) state */
2200 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2203 /* notify start of new segment */
2204 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2207 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2208 GST_FORMAT_TIME, demux->common.segment.start);
2209 gst_message_set_seqnum (msg, seqnum);
2210 gst_element_post_message (GST_ELEMENT (demux), msg);
2213 GST_OBJECT_LOCK (demux);
2214 if (demux->new_segment)
2215 gst_event_unref (demux->new_segment);
2217 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2218 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2219 gst_event_set_seqnum (demux->new_segment, seqnum);
2220 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2221 demux->to_time = demux->common.segment.position;
2223 demux->to_time = GST_CLOCK_TIME_NONE;
2224 GST_OBJECT_UNLOCK (demux);
2226 /* restart our task since it might have been stopped when we did the
2228 gst_pad_start_task (demux->common.sinkpad,
2229 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2231 /* streaming can continue now */
2233 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2241 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2243 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2249 * Handle whether we can perform the seek event or if we have to let the chain
2250 * function handle seeks to build the seek indexes first.
2253 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2257 GstSeekType cur_type, stop_type;
2262 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2267 /* we can only seek on time */
2268 if (format != GST_FORMAT_TIME) {
2269 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2273 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2274 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2278 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2279 GST_DEBUG_OBJECT (demux,
2280 "Non-flushing seek not supported in streaming mode");
2284 if (flags & GST_SEEK_FLAG_SEGMENT) {
2285 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2289 /* check for having parsed index already */
2290 if (!demux->common.index_parsed) {
2291 gboolean building_index;
2294 if (!demux->index_offset) {
2295 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2299 GST_OBJECT_LOCK (demux);
2300 /* handle the seek event in the chain function */
2301 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2302 /* no more seek can be issued until state reset to _DATA */
2304 /* copy the event */
2305 if (demux->seek_event)
2306 gst_event_unref (demux->seek_event);
2307 demux->seek_event = gst_event_ref (event);
2309 /* set the building_index flag so that only one thread can setup the
2310 * structures for index seeking. */
2311 building_index = demux->building_index;
2312 if (!building_index) {
2313 demux->building_index = TRUE;
2314 offset = demux->index_offset;
2316 GST_OBJECT_UNLOCK (demux);
2318 if (!building_index) {
2319 /* seek to the first subindex or legacy index */
2320 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2321 return perform_seek_to_offset (demux, rate, offset,
2322 gst_event_get_seqnum (event));
2325 /* well, we are handling it already */
2329 /* delegate to tweaked regular seek */
2330 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2334 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2337 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2338 gboolean res = TRUE;
2340 switch (GST_EVENT_TYPE (event)) {
2341 case GST_EVENT_SEEK:
2342 /* no seeking until we are (safely) ready */
2343 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2344 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2347 if (!demux->streaming)
2348 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2350 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2351 gst_event_unref (event);
2356 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2357 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2358 GstMatroskaTrackVideoContext *videocontext =
2359 (GstMatroskaTrackVideoContext *) context;
2361 GstClockTimeDiff diff;
2362 GstClockTime timestamp;
2364 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2366 GST_OBJECT_LOCK (demux);
2367 videocontext->earliest_time = timestamp + diff;
2368 GST_OBJECT_UNLOCK (demux);
2371 gst_event_unref (event);
2375 case GST_EVENT_TOC_SELECT:
2378 GstTocEntry *entry = NULL;
2379 GstEvent *seek_event;
2382 if (!demux->common.toc) {
2383 GST_DEBUG_OBJECT (demux, "no TOC to select");
2386 gst_event_parse_toc_select (event, &uid);
2388 GST_OBJECT_LOCK (demux);
2389 entry = gst_toc_find_entry (demux->common.toc, uid);
2390 if (entry == NULL) {
2391 GST_OBJECT_UNLOCK (demux);
2392 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2395 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2396 GST_OBJECT_UNLOCK (demux);
2397 seek_event = gst_event_new_seek (1.0,
2399 GST_SEEK_FLAG_FLUSH,
2400 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2401 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2402 gst_event_unref (seek_event);
2406 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2410 gst_event_unref (event);
2414 /* events we don't need to handle */
2415 case GST_EVENT_NAVIGATION:
2416 gst_event_unref (event);
2420 case GST_EVENT_LATENCY:
2422 res = gst_pad_push_event (demux->common.sinkpad, event);
2429 static GstFlowReturn
2430 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2432 GstFlowReturn ret = GST_FLOW_EOS;
2433 gboolean done = TRUE;
2436 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2437 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2440 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2442 if (!demux->seek_entry) {
2443 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2447 for (i = 0; i < demux->common.src->len; i++) {
2448 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2450 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2451 ", stream %d at %" GST_TIME_FORMAT,
2452 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2453 GST_TIME_ARGS (stream->from_time));
2454 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2455 if (stream->from_time > demux->common.segment.start) {
2456 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2460 /* nothing pushed for this stream;
2461 * likely seek entry did not start at keyframe, so all was skipped.
2462 * So we need an earlier entry */
2468 GstMatroskaIndex *entry;
2470 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2471 --demux->seek_entry);
2472 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2482 static GstFlowReturn
2483 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2485 GstFlowReturn ret = GST_FLOW_OK;
2488 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2490 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2491 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2495 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2496 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2500 /* one track within the "all-tracks" header */
2501 case GST_MATROSKA_ID_TRACKENTRY:
2502 ret = gst_matroska_demux_add_stream (demux, ebml);
2506 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2511 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2513 demux->tracks_parsed = TRUE;
2519 * Read signed/unsigned "EBML" numbers.
2520 * Return: number of bytes processed.
2524 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2526 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2534 while (read <= 8 && !(total & len_mask)) {
2541 if ((total &= (len_mask - 1)) == len_mask - 1)
2546 if (data[n] == 0xff)
2548 total = (total << 8) | data[n];
2552 if (read == num_ffs && total != 0)
2561 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2566 /* read as unsigned number first */
2567 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2571 if (unum == G_MAXUINT64)
2574 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2580 * Mostly used for subtitles. We add void filler data for each
2581 * lagging stream to make sure we don't deadlock.
2585 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2589 GST_OBJECT_LOCK (demux);
2591 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2592 GST_TIME_ARGS (demux->common.segment.position));
2594 g_assert (demux->common.num_streams == demux->common.src->len);
2595 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2596 GstMatroskaTrackContext *context;
2598 context = g_ptr_array_index (demux->common.src, stream_nr);
2600 GST_LOG_OBJECT (demux,
2601 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2602 GST_TIME_ARGS (context->pos));
2604 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2605 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2609 /* does it lag? 0.5 seconds is a random threshold...
2610 * lag need only be considered if we have advanced into requested segment */
2611 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2612 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2613 demux->common.segment.position > demux->common.segment.start &&
2614 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2617 guint64 start = context->pos;
2618 guint64 stop = demux->common.segment.position - (GST_SECOND / 2);
2620 GST_DEBUG_OBJECT (demux,
2621 "Synchronizing stream %d with other by advancing time from %"
2622 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2623 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2625 context->pos = stop;
2627 event = gst_event_new_gap (start, stop - start);
2628 GST_OBJECT_UNLOCK (demux);
2629 gst_pad_push_event (context->pad, event);
2630 GST_OBJECT_LOCK (demux);
2634 GST_OBJECT_UNLOCK (demux);
2637 static GstFlowReturn
2638 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2639 GstMatroskaTrackContext * stream)
2641 GstFlowReturn ret = GST_FLOW_OK;
2644 num = gst_buffer_list_length (stream->stream_headers);
2645 for (i = 0; i < num; ++i) {
2648 buf = gst_buffer_list_get (stream->stream_headers, i);
2649 buf = gst_buffer_copy (buf);
2651 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2653 if (stream->set_discont) {
2654 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2655 stream->set_discont = FALSE;
2657 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2660 /* push out all headers in one go and use last flow return */
2661 ret = gst_pad_push (stream->pad, buf);
2664 /* don't need these any longer */
2665 gst_buffer_list_unref (stream->stream_headers);
2666 stream->stream_headers = NULL;
2669 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2675 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2676 GstMatroskaTrackContext * stream)
2680 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2682 if (!stream->codec_priv)
2685 /* ideally, VobSub private data should be parsed and stored more convenient
2686 * elsewhere, but for now, only interested in a small part */
2688 /* make sure we have terminating 0 */
2689 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2691 /* just locate and parse palette part */
2692 start = strstr (buf, "palette:");
2697 guint8 r, g, b, y, u, v;
2700 while (g_ascii_isspace (*start))
2702 for (i = 0; i < 16; i++) {
2703 if (sscanf (start, "%06x", &col) != 1)
2706 while ((*start == ',') || g_ascii_isspace (*start))
2708 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2709 r = (col >> 16) & 0xff;
2710 g = (col >> 8) & 0xff;
2712 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2714 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2715 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2716 clut[i] = (y << 16) | (u << 8) | v;
2719 /* got them all without problems; build and send event */
2723 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2724 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2725 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2726 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2727 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2728 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2729 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2730 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2731 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2732 G_TYPE_INT, clut[15], NULL);
2734 gst_pad_push_event (stream->pad,
2735 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2742 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2746 GST_OBJECT_LOCK (demux);
2748 g_assert (demux->common.num_streams == demux->common.src->len);
2749 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2750 GstMatroskaTrackContext *stream;
2752 stream = g_ptr_array_index (demux->common.src, stream_nr);
2754 if (stream->send_stream_headers) {
2755 if (stream->stream_headers != NULL) {
2756 gst_matroska_demux_push_stream_headers (demux, stream);
2758 /* FIXME: perhaps we can just disable and skip this stream then */
2759 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2760 ("Failed to extract stream headers from codec private data"));
2762 stream->send_stream_headers = FALSE;
2765 if (stream->send_dvd_event) {
2766 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2767 /* FIXME: should we send this event again after (flushing) seek ? */
2768 stream->send_dvd_event = FALSE;
2772 GST_OBJECT_UNLOCK (demux);
2775 static GstFlowReturn
2776 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2777 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2780 guint seq_header_len;
2781 guint32 header, tmp;
2783 if (stream->codec_state) {
2784 seq_header = stream->codec_state;
2785 seq_header_len = stream->codec_state_size;
2786 } else if (stream->codec_priv) {
2787 seq_header = stream->codec_priv;
2788 seq_header_len = stream->codec_priv_size;
2793 /* Sequence header only needed for keyframes */
2794 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2797 if (gst_buffer_get_size (*buf) < 4)
2800 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2801 header = GUINT32_FROM_BE (tmp);
2803 /* Sequence start code, if not found prepend */
2804 if (header != 0x000001b3) {
2807 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2809 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2812 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2813 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2814 gst_buffer_get_size (*buf));
2816 gst_buffer_unref (*buf);
2823 static GstFlowReturn
2824 gst_matroska_demux_add_wvpk_header (GstElement * element,
2825 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2827 GstMatroskaTrackAudioContext *audiocontext =
2828 (GstMatroskaTrackAudioContext *) stream;
2829 GstBuffer *newbuf = NULL;
2830 GstMapInfo map, outmap;
2831 guint8 *buf_data, *data;
2839 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2842 wvh.total_samples = -1;
2843 wvh.block_index = audiocontext->wvpk_block_index;
2845 if (audiocontext->channels <= 2) {
2846 guint32 block_samples, tmp;
2847 gsize size = gst_buffer_get_size (*buf);
2849 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2850 block_samples = GUINT32_FROM_LE (tmp);
2851 /* we need to reconstruct the header of the wavpack block */
2853 /* -20 because ck_size is the size of the wavpack block -8
2854 * and lace_size is the size of the wavpack block + 12
2855 * (the three guint32 of the header that already are in the buffer) */
2856 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2858 /* block_samples, flags and crc are already in the buffer */
2859 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2861 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2867 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2868 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2869 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2870 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2871 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2872 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2874 /* Append data from buf: */
2875 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2876 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2878 gst_buffer_unref (*buf);
2880 audiocontext->wvpk_block_index += block_samples;
2882 guint8 *outdata = NULL;
2884 gsize buf_size, size, out_size = 0;
2885 guint32 block_samples, flags, crc, blocksize;
2887 gst_buffer_map (*buf, &map, GST_MAP_READ);
2888 buf_data = map.data;
2889 buf_size = map.size;
2892 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2893 gst_buffer_unmap (*buf, &map);
2894 return GST_FLOW_ERROR;
2900 block_samples = GST_READ_UINT32_LE (data);
2905 flags = GST_READ_UINT32_LE (data);
2908 crc = GST_READ_UINT32_LE (data);
2911 blocksize = GST_READ_UINT32_LE (data);
2915 if (blocksize == 0 || size < blocksize)
2918 g_assert ((newbuf == NULL) == (outdata == NULL));
2920 if (newbuf == NULL) {
2921 out_size = sizeof (Wavpack4Header) + blocksize;
2922 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2924 gst_buffer_copy_into (newbuf, *buf,
2925 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2928 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2929 outdata = outmap.data;
2931 gst_buffer_unmap (newbuf, &outmap);
2932 out_size += sizeof (Wavpack4Header) + blocksize;
2933 gst_buffer_set_size (newbuf, out_size);
2934 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2935 outdata = outmap.data;
2938 outdata[outpos] = 'w';
2939 outdata[outpos + 1] = 'v';
2940 outdata[outpos + 2] = 'p';
2941 outdata[outpos + 3] = 'k';
2944 GST_WRITE_UINT32_LE (outdata + outpos,
2945 blocksize + sizeof (Wavpack4Header) - 8);
2946 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2947 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2948 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2949 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2950 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2951 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2952 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2953 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2956 memmove (outdata + outpos, data, blocksize);
2957 outpos += blocksize;
2961 gst_buffer_unmap (*buf, &map);
2962 gst_buffer_unref (*buf);
2965 gst_buffer_unmap (newbuf, &outmap);
2968 audiocontext->wvpk_block_index += block_samples;
2974 static GstFlowReturn
2975 gst_matroska_demux_add_prores_header (GstElement * element,
2976 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2978 GstBuffer *newbuf = gst_buffer_new_allocate (NULL, 8, NULL);
2982 if (!gst_buffer_map (newbuf, &map, GST_MAP_WRITE)) {
2983 GST_ERROR ("Failed to map newly allocated buffer");
2984 return GST_FLOW_ERROR;
2987 frame_size = gst_buffer_get_size (*buf);
2989 GST_WRITE_UINT32_BE (map.data, frame_size);
2995 gst_buffer_unmap (newbuf, &map);
2996 *buf = gst_buffer_append (newbuf, *buf);
3001 /* @text must be null-terminated */
3003 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
3008 g_return_val_if_fail (text != NULL, FALSE);
3010 /* yes, this might all lead to false positives ... */
3011 tag = (gchar *) text;
3012 while ((tag = strchr (tag, '<'))) {
3014 if (*tag != '\0' && *(tag + 1) == '>') {
3015 /* some common convenience ones */
3016 /* maybe any character will do here ? */
3029 if (strstr (text, "<span"))
3035 static GstFlowReturn
3036 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
3037 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3039 GstMatroskaTrackSubtitleContext *sub_stream;
3040 const gchar *encoding;
3045 gboolean needs_unmap = TRUE;
3047 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3049 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
3052 /* The subtitle buffer we push out should not include a NUL terminator as
3053 * part of the data. */
3054 if (map.data[map.size - 1] == '\0') {
3055 gst_buffer_set_size (*buf, map.size - 1);
3056 gst_buffer_unmap (*buf, &map);
3057 gst_buffer_map (*buf, &map, GST_MAP_READ);
3060 if (!sub_stream->invalid_utf8) {
3061 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
3064 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
3065 " is not valid UTF-8, this is broken according to the matroska"
3066 " specification", stream->num);
3067 sub_stream->invalid_utf8 = TRUE;
3070 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3071 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3072 if (encoding == NULL || *encoding == '\0') {
3073 /* if local encoding is UTF-8 and no encoding specified
3074 * via the environment variable, assume ISO-8859-15 */
3075 if (g_get_charset (&encoding)) {
3076 encoding = "ISO-8859-15";
3081 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3082 (char *) "*", NULL, NULL, &err);
3085 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3086 encoding, err->message);
3090 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3091 encoding = "ISO-8859-15";
3093 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3094 encoding, (char *) "*", NULL, NULL, NULL);
3097 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3098 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3101 utf8 = g_strdup ("invalid subtitle");
3103 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3104 gst_buffer_unmap (*buf, &map);
3105 gst_buffer_copy_into (newbuf, *buf,
3106 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3108 gst_buffer_unref (*buf);
3111 gst_buffer_map (*buf, &map, GST_MAP_READ);
3115 if (sub_stream->check_markup) {
3116 /* caps claim markup text, so we need to escape text,
3117 * except if text is already markup and then needs no further escaping */
3118 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3119 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3121 if (!sub_stream->seen_markup_tag) {
3122 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3124 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3125 gst_buffer_unmap (*buf, &map);
3126 gst_buffer_copy_into (newbuf, *buf,
3127 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3128 GST_BUFFER_COPY_META, 0, -1);
3129 gst_buffer_unref (*buf);
3132 needs_unmap = FALSE;
3137 gst_buffer_unmap (*buf, &map);
3142 static GstFlowReturn
3143 gst_matroska_demux_check_aac (GstElement * element,
3144 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3149 gst_buffer_extract (*buf, 0, data, 2);
3150 size = gst_buffer_get_size (*buf);
3152 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3155 /* tss, ADTS data, remove codec_data
3156 * still assume it is at least parsed */
3157 stream->caps = gst_caps_make_writable (stream->caps);
3158 s = gst_caps_get_structure (stream->caps, 0);
3160 gst_structure_remove_field (s, "codec_data");
3161 gst_pad_set_caps (stream->pad, stream->caps);
3162 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3163 "new caps: %" GST_PTR_FORMAT, stream->caps);
3166 /* disable subsequent checking */
3167 stream->postprocess_frame = NULL;
3173 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3174 GstBuffer * buffer, gsize alignment)
3178 gst_buffer_map (buffer, &map, GST_MAP_READ);
3180 if (map.size < sizeof (guintptr)) {
3181 gst_buffer_unmap (buffer, &map);
3185 if (((guintptr) map.data) & (alignment - 1)) {
3186 GstBuffer *new_buffer;
3187 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3189 new_buffer = gst_buffer_new_allocate (NULL,
3190 gst_buffer_get_size (buffer), ¶ms);
3192 /* Copy data "by hand", so ensure alignment is kept: */
3193 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3195 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3196 GST_DEBUG_OBJECT (demux,
3197 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3200 gst_buffer_unmap (buffer, &map);
3201 gst_buffer_unref (buffer);
3206 gst_buffer_unmap (buffer, &map);
3210 static GstFlowReturn
3211 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3212 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3213 gboolean is_simpleblock)
3215 GstMatroskaTrackContext *stream = NULL;
3216 GstFlowReturn ret = GST_FLOW_OK;
3217 gboolean readblock = FALSE;
3219 guint64 block_duration = -1;
3220 gint64 block_discardpadding = 0;
3221 GstBuffer *buf = NULL;
3223 gint stream_num = -1, n, laces = 0;
3225 gint *lace_size = NULL;
3228 gint64 referenceblock = 0;
3230 GstClockTime buffer_timestamp;
3232 offset = gst_ebml_read_get_offset (ebml);
3234 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3235 if (!is_simpleblock) {
3236 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3240 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3244 /* one block inside the group. Note, block parsing is one
3245 * of the harder things, so this code is a bit complicated.
3246 * See http://www.matroska.org/ for documentation. */
3247 case GST_MATROSKA_ID_SIMPLEBLOCK:
3248 case GST_MATROSKA_ID_BLOCK:
3254 gst_buffer_unmap (buf, &map);
3255 gst_buffer_unref (buf);
3258 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3261 gst_buffer_map (buf, &map, GST_MAP_READ);
3265 /* first byte(s): blocknum */
3266 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3271 /* fetch stream from num */
3272 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3274 if (G_UNLIKELY (size < 3)) {
3275 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3276 /* non-fatal, try next block(group) */
3279 } else if (G_UNLIKELY (stream_num < 0 ||
3280 stream_num >= demux->common.num_streams)) {
3281 /* let's not give up on a stray invalid track number */
3282 GST_WARNING_OBJECT (demux,
3283 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3284 "; ignoring block", stream_num, num);
3288 stream = g_ptr_array_index (demux->common.src, stream_num);
3290 /* time (relative to cluster time) */
3291 time = ((gint16) GST_READ_UINT16_BE (data));
3294 flags = GST_READ_UINT8 (data);
3298 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3301 switch ((flags & 0x06) >> 1) {
3302 case 0x0: /* no lacing */
3304 lace_size = g_new (gint, 1);
3305 lace_size[0] = size;
3308 case 0x1: /* xiph lacing */
3309 case 0x2: /* fixed-size lacing */
3310 case 0x3: /* EBML lacing */
3312 goto invalid_lacing;
3313 laces = GST_READ_UINT8 (data) + 1;
3316 lace_size = g_new0 (gint, laces);
3318 switch ((flags & 0x06) >> 1) {
3319 case 0x1: /* xiph lacing */ {
3320 guint temp, total = 0;
3322 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3325 goto invalid_lacing;
3326 temp = GST_READ_UINT8 (data);
3327 lace_size[n] += temp;
3333 total += lace_size[n];
3335 lace_size[n] = size - total;
3339 case 0x2: /* fixed-size lacing */
3340 for (n = 0; n < laces; n++)
3341 lace_size[n] = size / laces;
3344 case 0x3: /* EBML lacing */ {
3347 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3351 total = lace_size[0] = num;
3352 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3356 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3360 lace_size[n] = lace_size[n - 1] + snum;
3361 total += lace_size[n];
3364 lace_size[n] = size - total;
3371 if (ret != GST_FLOW_OK)
3378 case GST_MATROSKA_ID_BLOCKDURATION:{
3379 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3380 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3385 case GST_MATROSKA_ID_DISCARDPADDING:{
3386 ret = gst_ebml_read_sint (ebml, &id, &block_discardpadding);
3387 GST_DEBUG_OBJECT (demux, "DiscardPadding: %" GST_STIME_FORMAT,
3388 GST_STIME_ARGS (block_discardpadding));
3392 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3393 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3394 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3399 case GST_MATROSKA_ID_CODECSTATE:{
3401 guint64 data_len = 0;
3404 gst_ebml_read_binary (ebml, &id, &data,
3405 &data_len)) != GST_FLOW_OK)
3408 if (G_UNLIKELY (stream == NULL)) {
3409 GST_WARNING_OBJECT (demux,
3410 "Unexpected CodecState subelement - ignoring");
3414 g_free (stream->codec_state);
3415 stream->codec_state = data;
3416 stream->codec_state_size = data_len;
3418 /* Decode if necessary */
3419 if (stream->encodings && stream->encodings->len > 0
3420 && stream->codec_state && stream->codec_state_size > 0) {
3421 if (!gst_matroska_decode_data (stream->encodings,
3422 &stream->codec_state, &stream->codec_state_size,
3423 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3424 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3428 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3429 stream->codec_state_size);
3434 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3438 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3439 case GST_MATROSKA_ID_BLOCKADDITIONS:
3440 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3441 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3442 case GST_MATROSKA_ID_SLICES:
3443 GST_DEBUG_OBJECT (demux,
3444 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3445 ret = gst_ebml_read_skip (ebml);
3453 /* reading a number or so could have failed */
3454 if (ret != GST_FLOW_OK)
3457 if (ret == GST_FLOW_OK && readblock) {
3458 gboolean invisible_frame = FALSE;
3459 gboolean delta_unit = FALSE;
3460 guint64 duration = 0;
3461 gint64 lace_time = 0;
3463 stream = g_ptr_array_index (demux->common.src, stream_num);
3465 if (cluster_time != GST_CLOCK_TIME_NONE) {
3466 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3467 * Drop unless the lace contains timestamp 0? */
3468 if (time < 0 && (-time) > cluster_time) {
3471 if (stream->timecodescale == 1.0)
3472 lace_time = (cluster_time + time) * demux->common.time_scale;
3475 gst_util_guint64_to_gdouble ((cluster_time + time) *
3476 demux->common.time_scale) * stream->timecodescale;
3479 lace_time = GST_CLOCK_TIME_NONE;
3482 /* need to refresh segment info ASAP */
3483 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3484 GstSegment *segment = &demux->common.segment;
3486 GstEvent *segment_event;
3488 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3489 demux->stream_start_time = lace_time;
3490 GST_DEBUG_OBJECT (demux,
3491 "Setting stream start time to %" GST_TIME_FORMAT,
3492 GST_TIME_ARGS (lace_time));
3494 clace_time = MAX (lace_time, demux->stream_start_time);
3495 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3496 demux->common.segment.position != 0) {
3497 GST_DEBUG_OBJECT (demux,
3498 "using stored seek position %" GST_TIME_FORMAT,
3499 GST_TIME_ARGS (demux->common.segment.position));
3500 clace_time = demux->common.segment.position + demux->stream_start_time;
3501 segment->position = GST_CLOCK_TIME_NONE;
3503 segment->start = clace_time;
3504 segment->stop = GST_CLOCK_TIME_NONE;
3505 segment->time = segment->start - demux->stream_start_time;
3506 segment->position = segment->start - demux->stream_start_time;
3507 GST_DEBUG_OBJECT (demux,
3508 "generated segment starting at %" GST_TIME_FORMAT ": %"
3509 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3510 /* now convey our segment notion downstream */
3511 segment_event = gst_event_new_segment (segment);
3512 if (demux->segment_seqnum)
3513 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3514 gst_matroska_demux_send_event (demux, segment_event);
3515 demux->need_segment = FALSE;
3516 demux->segment_seqnum = 0;
3519 /* send pending codec data headers for all streams,
3520 * before we perform sync across all streams */
3521 gst_matroska_demux_push_codec_data_all (demux);
3523 if (block_duration != -1) {
3524 if (stream->timecodescale == 1.0)
3525 duration = gst_util_uint64_scale (block_duration,
3526 demux->common.time_scale, 1);
3529 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3530 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3531 1)) * stream->timecodescale);
3532 } else if (stream->default_duration) {
3533 duration = stream->default_duration * laces;
3535 /* else duration is diff between timecode of this and next block */
3537 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3538 a ReferenceBlock implies that this is not a keyframe. In either
3539 case, it only makes sense for video streams. */
3540 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3541 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3543 invisible_frame = ((flags & 0x08)) &&
3544 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3545 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3549 for (n = 0; n < laces; n++) {
3552 if (G_UNLIKELY (lace_size[n] > size)) {
3553 GST_WARNING_OBJECT (demux, "Invalid lace size");
3557 /* QoS for video track with an index. the assumption is that
3558 index entries point to keyframes, but if that is not true we
3559 will instad skip until the next keyframe. */
3560 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3561 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3562 stream->index_table && demux->common.segment.rate > 0.0) {
3563 GstMatroskaTrackVideoContext *videocontext =
3564 (GstMatroskaTrackVideoContext *) stream;
3565 GstClockTime earliest_time;
3566 GstClockTime earliest_stream_time;
3568 GST_OBJECT_LOCK (demux);
3569 earliest_time = videocontext->earliest_time;
3570 GST_OBJECT_UNLOCK (demux);
3571 earliest_stream_time =
3572 gst_segment_position_from_running_time (&demux->common.segment,
3573 GST_FORMAT_TIME, earliest_time);
3575 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3576 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3577 lace_time <= earliest_stream_time) {
3578 /* find index entry (keyframe) <= earliest_stream_time */
3579 GstMatroskaIndex *entry =
3580 gst_util_array_binary_search (stream->index_table->data,
3581 stream->index_table->len, sizeof (GstMatroskaIndex),
3582 (GCompareDataFunc) gst_matroska_index_seek_find,
3583 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3585 /* if that entry (keyframe) is after the current the current
3586 buffer, we can skip pushing (and thus decoding) all
3587 buffers until that keyframe. */
3588 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3589 entry->time > lace_time) {
3590 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3591 stream->set_discont = TRUE;
3597 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3598 gst_buffer_get_size (buf) - size, lace_size[n]);
3599 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3602 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3604 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3606 if (invisible_frame)
3607 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3609 if (stream->encodings != NULL && stream->encodings->len > 0)
3610 sub = gst_matroska_decode_buffer (stream, sub);
3613 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3617 if (!stream->dts_only) {
3618 GST_BUFFER_PTS (sub) = lace_time;
3620 GST_BUFFER_DTS (sub) = lace_time;
3621 if (stream->intra_only)
3622 GST_BUFFER_PTS (sub) = lace_time;
3625 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
3627 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3628 GstClockTime last_stop_end;
3630 /* Check if this stream is after segment stop */
3631 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3632 lace_time >= demux->common.segment.stop) {
3633 GST_DEBUG_OBJECT (demux,
3634 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3635 GST_TIME_ARGS (demux->common.segment.stop));
3636 gst_buffer_unref (sub);
3639 if (offset >= stream->to_offset
3640 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3641 && lace_time > demux->to_time)) {
3642 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3644 gst_buffer_unref (sub);
3648 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3649 * that landed us with timestamps not quite intended */
3650 GST_OBJECT_LOCK (demux);
3651 if (demux->max_gap_time &&
3652 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3653 demux->common.segment.rate > 0.0) {
3654 GstClockTimeDiff diff;
3656 /* only send segments with increasing start times,
3657 * otherwise if these go back and forth downstream (sinks) increase
3658 * accumulated time and running_time */
3659 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3660 if (diff > 0 && diff > demux->max_gap_time
3661 && lace_time > demux->common.segment.start
3662 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3663 || lace_time < demux->common.segment.stop)) {
3665 GST_DEBUG_OBJECT (demux,
3666 "Gap of %" G_GINT64_FORMAT " ns detected in"
3667 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3668 "Sending updated SEGMENT events", diff,
3669 stream->index, GST_TIME_ARGS (stream->pos),
3670 GST_TIME_ARGS (lace_time));
3672 event = gst_event_new_gap (demux->last_stop_end, diff);
3673 GST_OBJECT_UNLOCK (demux);
3674 gst_pad_push_event (stream->pad, event);
3675 GST_OBJECT_LOCK (demux);
3679 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3680 || demux->common.segment.position < lace_time) {
3681 demux->common.segment.position = lace_time;
3683 GST_OBJECT_UNLOCK (demux);
3685 last_stop_end = lace_time;
3687 GST_BUFFER_DURATION (sub) = duration / laces;
3688 last_stop_end += GST_BUFFER_DURATION (sub);
3691 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3692 demux->last_stop_end < last_stop_end)
3693 demux->last_stop_end = last_stop_end;
3695 GST_OBJECT_LOCK (demux);
3696 if (demux->common.segment.duration == -1 ||
3697 demux->stream_start_time + demux->common.segment.duration <
3699 demux->common.segment.duration =
3700 last_stop_end - demux->stream_start_time;
3701 GST_OBJECT_UNLOCK (demux);
3702 if (!demux->invalid_duration) {
3703 gst_element_post_message (GST_ELEMENT_CAST (demux),
3704 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3705 demux->invalid_duration = TRUE;
3708 GST_OBJECT_UNLOCK (demux);
3712 stream->pos = lace_time;
3714 gst_matroska_demux_sync_streams (demux);
3716 if (stream->set_discont) {
3717 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3718 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3719 stream->set_discont = FALSE;
3721 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3724 /* reverse playback book-keeping */
3725 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3726 stream->from_time = lace_time;
3727 if (stream->from_offset == -1)
3728 stream->from_offset = offset;
3730 GST_DEBUG_OBJECT (demux,
3731 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3732 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3733 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3734 GST_TIME_ARGS (buffer_timestamp),
3735 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3738 if (demux->common.element_index) {
3739 if (stream->index_writer_id == -1)
3740 gst_index_get_writer_id (demux->common.element_index,
3741 GST_OBJECT (stream->pad), &stream->index_writer_id);
3743 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3744 G_GUINT64_FORMAT " for writer id %d",
3745 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
3746 stream->index_writer_id);
3747 gst_index_add_association (demux->common.element_index,
3748 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3749 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3750 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
3755 /* Postprocess the buffers depending on the codec used */
3756 if (stream->postprocess_frame) {
3757 GST_LOG_OBJECT (demux, "running post process");
3758 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3761 /* At this point, we have a sub-buffer pointing at data within a larger
3762 buffer. This data might not be aligned with anything. If the data is
3763 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3764 for 32 bit samples, etc), or bad things will happen downstream as
3765 elements typically assume minimal alignment.
3766 Therefore, create an aligned copy if necessary. */
3767 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3769 if (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
3770 guint64 start_clip = 0, end_clip = 0;
3772 /* Codec delay is part of the timestamps */
3773 if (GST_BUFFER_PTS_IS_VALID (sub) && stream->codec_delay) {
3774 if (GST_BUFFER_PTS (sub) > stream->codec_delay) {
3775 GST_BUFFER_PTS (sub) -= stream->codec_delay;
3777 GST_BUFFER_PTS (sub) = 0;
3779 gst_util_uint64_scale_round (stream->codec_delay, 48000,
3782 if (GST_BUFFER_DURATION_IS_VALID (sub)) {
3783 if (GST_BUFFER_DURATION (sub) > stream->codec_delay)
3784 GST_BUFFER_DURATION (sub) -= stream->codec_delay;
3786 GST_BUFFER_DURATION (sub) = 0;
3791 if (block_discardpadding) {
3793 gst_util_uint64_scale_round (block_discardpadding, 48000,
3797 if (start_clip || end_clip) {
3798 gst_buffer_add_audio_clipping_meta (sub, GST_FORMAT_DEFAULT,
3799 start_clip, end_clip);
3803 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3804 stream->pos = GST_BUFFER_PTS (sub);
3805 if (GST_BUFFER_DURATION_IS_VALID (sub))
3806 stream->pos += GST_BUFFER_DURATION (sub);
3807 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
3808 stream->pos = GST_BUFFER_DTS (sub);
3809 if (GST_BUFFER_DURATION_IS_VALID (sub))
3810 stream->pos += GST_BUFFER_DURATION (sub);
3813 ret = gst_pad_push (stream->pad, sub);
3815 if (demux->common.segment.rate < 0) {
3816 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3817 /* In reverse playback we can get a GST_FLOW_EOS when
3818 * we are at the end of the segment, so we just need to jump
3819 * back to the previous section. */
3820 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3825 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
3829 size -= lace_size[n];
3830 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3831 lace_time += duration / laces;
3833 lace_time = GST_CLOCK_TIME_NONE;
3839 gst_buffer_unmap (buf, &map);
3840 gst_buffer_unref (buf);
3852 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
3858 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3859 /* non-fatal, try next block(group) */
3865 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3866 /* non-fatal, try next block(group) */
3872 /* return FALSE if block(group) should be skipped (due to a seek) */
3873 static inline gboolean
3874 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3876 if (G_UNLIKELY (demux->seek_block)) {
3877 if (!(--demux->seek_block)) {
3880 GST_LOG_OBJECT (demux, "should skip block due to seek");
3888 static GstFlowReturn
3889 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3893 guint64 seek_pos = (guint64) - 1;
3894 guint32 seek_id = 0;
3897 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3899 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3900 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3904 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3905 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3909 case GST_MATROSKA_ID_SEEKID:
3913 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3916 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3921 case GST_MATROSKA_ID_SEEKPOSITION:
3925 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3928 if (t > G_MAXINT64) {
3929 GST_WARNING_OBJECT (demux,
3930 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3934 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3940 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3946 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3949 if (!seek_id || seek_pos == (guint64) - 1) {
3950 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3951 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3956 case GST_MATROSKA_ID_SEEKHEAD:
3959 case GST_MATROSKA_ID_CUES:
3960 case GST_MATROSKA_ID_TAGS:
3961 case GST_MATROSKA_ID_TRACKS:
3962 case GST_MATROSKA_ID_SEGMENTINFO:
3963 case GST_MATROSKA_ID_ATTACHMENTS:
3964 case GST_MATROSKA_ID_CHAPTERS:
3966 guint64 before_pos, length;
3970 length = gst_matroska_read_common_get_length (&demux->common);
3971 before_pos = demux->common.offset;
3973 if (length == (guint64) - 1) {
3974 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3978 /* check for validity */
3979 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3980 GST_WARNING_OBJECT (demux,
3981 "SeekHead reference lies outside file!" " (%"
3982 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3983 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3988 /* only pick up index location when streaming */
3989 if (demux->streaming) {
3990 if (seek_id == GST_MATROSKA_ID_CUES) {
3991 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3992 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3993 demux->index_offset);
3999 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
4002 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4003 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
4007 if (id != seek_id) {
4008 GST_WARNING_OBJECT (demux,
4009 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
4010 seek_id, id, seek_pos + demux->common.ebml_segment_start);
4013 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4018 demux->common.offset = before_pos;
4022 case GST_MATROSKA_ID_CLUSTER:
4024 guint64 pos = seek_pos + demux->common.ebml_segment_start;
4026 GST_LOG_OBJECT (demux, "Cluster position");
4027 if (G_UNLIKELY (!demux->clusters))
4028 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
4029 g_array_append_val (demux->clusters, pos);
4034 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
4037 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4042 static GstFlowReturn
4043 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4045 GstFlowReturn ret = GST_FLOW_OK;
4048 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4050 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4051 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4055 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4056 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4060 case GST_MATROSKA_ID_SEEKENTRY:
4062 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
4063 /* Ignore EOS and errors here */
4064 if (ret != GST_FLOW_OK) {
4065 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4072 ret = gst_matroska_read_common_parse_skip (&demux->common,
4073 ebml, "SeekHead", id);
4078 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4080 /* Sort clusters by position for easier searching */
4081 if (demux->clusters)
4082 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4087 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
4089 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4091 static inline GstFlowReturn
4092 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4094 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4095 /* only a few blocks are expected/allowed to be large,
4096 * and will be recursed into, whereas others will be read and must fit */
4097 if (demux->streaming) {
4098 /* fatal in streaming case, as we can't step over easily */
4099 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4100 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4101 "file might be corrupt.", bytes));
4102 return GST_FLOW_ERROR;
4104 /* indicate higher level to quietly give up */
4105 GST_DEBUG_OBJECT (demux,
4106 "too large block of size %" G_GUINT64_FORMAT, bytes);
4107 return GST_FLOW_ERROR;
4114 /* returns TRUE if we truely are in error state, and should give up */
4115 static inline GstFlowReturn
4116 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4118 if (!demux->streaming && demux->next_cluster_offset > 0) {
4119 /* just repositioning to where next cluster should be and try from there */
4120 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4121 G_GUINT64_FORMAT, demux->next_cluster_offset);
4122 demux->common.offset = demux->next_cluster_offset;
4123 demux->next_cluster_offset = 0;
4129 /* sigh, one last attempt above and beyond call of duty ...;
4130 * search for cluster mark following current pos */
4131 pos = demux->common.offset;
4132 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4133 if ((ret = gst_matroska_demux_search_cluster (demux, &pos)) != GST_FLOW_OK) {
4134 /* did not work, give up */
4137 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4138 /* try that position */
4139 demux->common.offset = pos;
4145 static inline GstFlowReturn
4146 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4148 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4149 demux->common.offset += flush;
4150 if (demux->streaming) {
4153 /* hard to skip large blocks when streaming */
4154 ret = gst_matroska_demux_check_read_size (demux, flush);
4155 if (ret != GST_FLOW_OK)
4157 if (flush <= gst_adapter_available (demux->common.adapter))
4158 gst_adapter_flush (demux->common.adapter, flush);
4160 return GST_FLOW_EOS;
4165 /* initializes @ebml with @bytes from input stream at current offset.
4166 * Returns EOS if insufficient available,
4167 * ERROR if too much was attempted to read. */
4168 static inline GstFlowReturn
4169 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4172 GstBuffer *buffer = NULL;
4173 GstFlowReturn ret = GST_FLOW_OK;
4175 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4177 ret = gst_matroska_demux_check_read_size (demux, bytes);
4178 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4179 if (!demux->streaming) {
4180 /* in pull mode, we can skip */
4181 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4182 ret = GST_FLOW_OVERFLOW;
4184 /* otherwise fatal */
4185 ret = GST_FLOW_ERROR;
4189 if (demux->streaming) {
4190 if (gst_adapter_available (demux->common.adapter) >= bytes)
4191 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4195 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4196 demux->common.offset, bytes, &buffer, NULL);
4197 if (G_LIKELY (buffer)) {
4198 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4199 demux->common.offset);
4200 demux->common.offset += bytes;
4207 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4210 gboolean seekable = FALSE;
4211 gint64 start = -1, stop = -1;
4213 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4214 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4215 GST_DEBUG_OBJECT (demux, "seeking query failed");
4219 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4221 /* try harder to query upstream size if we didn't get it the first time */
4222 if (seekable && stop == -1) {
4223 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4224 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4228 /* if upstream doesn't know the size, it's likely that it's not seekable in
4229 * practice even if it technically may be seekable */
4230 if (seekable && (start != 0 || stop <= start)) {
4231 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4236 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4237 G_GUINT64_FORMAT ")", seekable, start, stop);
4238 demux->seekable = seekable;
4240 gst_query_unref (query);
4243 static GstFlowReturn
4244 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4250 GstFlowReturn ret = GST_FLOW_OK;
4252 GST_WARNING_OBJECT (demux,
4253 "Found Cluster element before Tracks, searching Tracks");
4256 before_pos = demux->common.offset;
4258 /* Search Tracks element */
4260 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4261 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4262 if (ret != GST_FLOW_OK)
4265 if (id != GST_MATROSKA_ID_TRACKS) {
4266 /* we may be skipping large cluster here, so forego size check etc */
4267 /* ... but we can't skip undefined size; force error */
4268 if (length == G_MAXUINT64) {
4269 ret = gst_matroska_demux_check_read_size (demux, length);
4272 demux->common.offset += needed;
4273 demux->common.offset += length;
4278 /* will lead to track parsing ... */
4279 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4284 demux->common.offset = before_pos;
4289 #define GST_READ_CHECK(stmt) \
4291 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4292 if (ret == GST_FLOW_OVERFLOW) { \
4293 ret = GST_FLOW_OK; \
4299 static GstFlowReturn
4300 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4301 guint64 length, guint needed)
4303 GstEbmlRead ebml = { 0, };
4304 GstFlowReturn ret = GST_FLOW_OK;
4307 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4308 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4310 /* if we plan to read and parse this element, we need prefix (id + length)
4311 * and the contents */
4312 /* mind about overflow wrap-around when dealing with undefined size */
4314 if (G_LIKELY (length != G_MAXUINT64))
4317 switch (demux->common.state) {
4318 case GST_MATROSKA_READ_STATE_START:
4320 case GST_EBML_ID_HEADER:
4321 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4322 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4323 if (ret != GST_FLOW_OK)
4325 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4326 gst_matroska_demux_check_seekability (demux);
4329 goto invalid_header;
4333 case GST_MATROSKA_READ_STATE_SEGMENT:
4335 case GST_MATROSKA_ID_SEGMENT:
4336 /* eat segment prefix */
4337 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4338 GST_DEBUG_OBJECT (demux,
4339 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4340 G_GUINT64_FORMAT, demux->common.offset, length);
4341 /* seeks are from the beginning of the segment,
4342 * after the segment ID/length */
4343 demux->common.ebml_segment_start = demux->common.offset;
4345 length = G_MAXUINT64;
4346 demux->common.ebml_segment_length = length;
4347 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4350 GST_WARNING_OBJECT (demux,
4351 "Expected a Segment ID (0x%x), but received 0x%x!",
4352 GST_MATROSKA_ID_SEGMENT, id);
4353 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4357 case GST_MATROSKA_READ_STATE_SCANNING:
4358 if (id != GST_MATROSKA_ID_CLUSTER &&
4359 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4362 case GST_MATROSKA_READ_STATE_HEADER:
4363 case GST_MATROSKA_READ_STATE_DATA:
4364 case GST_MATROSKA_READ_STATE_SEEK:
4366 case GST_MATROSKA_ID_SEGMENTINFO:
4367 if (!demux->common.segmentinfo_parsed) {
4368 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4369 ret = gst_matroska_read_common_parse_info (&demux->common,
4370 GST_ELEMENT_CAST (demux), &ebml);
4371 if (ret == GST_FLOW_OK)
4372 gst_matroska_demux_send_tags (demux);
4374 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4377 case GST_MATROSKA_ID_TRACKS:
4378 if (!demux->tracks_parsed) {
4379 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4380 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4382 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4385 case GST_MATROSKA_ID_CLUSTER:
4386 if (G_UNLIKELY (!demux->tracks_parsed)) {
4387 if (demux->streaming) {
4388 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4389 goto not_streamable;
4391 ret = gst_matroska_demux_find_tracks (demux);
4392 if (!demux->tracks_parsed)
4396 if (G_UNLIKELY (demux->common.state
4397 == GST_MATROSKA_READ_STATE_HEADER)) {
4398 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4399 demux->first_cluster_offset = demux->common.offset;
4400 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4401 gst_element_no_more_pads (GST_ELEMENT (demux));
4402 /* send initial segment - we wait till we know the first
4403 incoming timestamp, so we can properly set the start of
4405 demux->need_segment = TRUE;
4407 demux->cluster_time = GST_CLOCK_TIME_NONE;
4408 demux->cluster_offset = demux->common.offset;
4409 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4410 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4411 " not found in Cluster, trying next Cluster's first block instead",
4413 demux->seek_block = 0;
4415 demux->seek_first = FALSE;
4416 /* record next cluster for recovery */
4417 if (read != G_MAXUINT64)
4418 demux->next_cluster_offset = demux->cluster_offset + read;
4419 /* eat cluster prefix */
4420 gst_matroska_demux_flush (demux, needed);
4422 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4426 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4427 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4429 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4430 demux->cluster_time = num;
4432 if (demux->common.element_index) {
4433 if (demux->common.element_index_writer_id == -1)
4434 gst_index_get_writer_id (demux->common.element_index,
4435 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4436 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4437 G_GUINT64_FORMAT " for writer id %d",
4438 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4439 demux->common.element_index_writer_id);
4440 gst_index_add_association (demux->common.element_index,
4441 demux->common.element_index_writer_id,
4442 GST_ASSOCIATION_FLAG_KEY_UNIT,
4443 GST_FORMAT_TIME, demux->cluster_time,
4444 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4449 case GST_MATROSKA_ID_BLOCKGROUP:
4450 if (!gst_matroska_demux_seek_block (demux))
4452 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4453 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4454 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4455 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4456 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4458 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4460 case GST_MATROSKA_ID_SIMPLEBLOCK:
4461 if (!gst_matroska_demux_seek_block (demux))
4463 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4464 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4465 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4466 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4467 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4469 case GST_MATROSKA_ID_ATTACHMENTS:
4470 if (!demux->common.attachments_parsed) {
4471 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4472 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4473 GST_ELEMENT_CAST (demux), &ebml);
4474 if (ret == GST_FLOW_OK)
4475 gst_matroska_demux_send_tags (demux);
4477 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4480 case GST_MATROSKA_ID_TAGS:
4481 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4482 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4483 GST_ELEMENT_CAST (demux), &ebml);
4484 if (ret == GST_FLOW_OK)
4485 gst_matroska_demux_send_tags (demux);
4487 case GST_MATROSKA_ID_CHAPTERS:
4488 if (!demux->common.chapters_parsed) {
4489 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4491 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4493 if (demux->common.toc) {
4494 gst_matroska_demux_send_event (demux,
4495 gst_event_new_toc (demux->common.toc, FALSE));
4498 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4500 case GST_MATROSKA_ID_SEEKHEAD:
4501 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4502 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4504 case GST_MATROSKA_ID_CUES:
4505 if (demux->common.index_parsed) {
4506 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4509 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4510 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4511 /* only push based; delayed index building */
4512 if (ret == GST_FLOW_OK
4513 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4516 GST_OBJECT_LOCK (demux);
4517 event = demux->seek_event;
4518 demux->seek_event = NULL;
4519 GST_OBJECT_UNLOCK (demux);
4522 /* unlikely to fail, since we managed to seek to this point */
4523 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
4524 gst_event_unref (event);
4527 gst_event_unref (event);
4528 /* resume data handling, main thread clear to seek again */
4529 GST_OBJECT_LOCK (demux);
4530 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4531 GST_OBJECT_UNLOCK (demux);
4534 case GST_MATROSKA_ID_POSITION:
4535 case GST_MATROSKA_ID_PREVSIZE:
4536 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4537 case GST_MATROSKA_ID_SILENTTRACKS:
4538 GST_DEBUG_OBJECT (demux,
4539 "Skipping Cluster subelement 0x%x - ignoring", id);
4543 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4544 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4550 if (ret == GST_FLOW_PARSE)
4554 gst_ebml_read_clear (&ebml);
4560 /* simply exit, maybe not enough data yet */
4561 /* no ebml to clear if read error */
4566 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4567 ("Failed to parse Element 0x%x", id));
4568 ret = GST_FLOW_ERROR;
4573 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4574 ("File layout does not permit streaming"));
4575 ret = GST_FLOW_ERROR;
4580 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4581 ("No Tracks element found"));
4582 ret = GST_FLOW_ERROR;
4587 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4588 ret = GST_FLOW_ERROR;
4593 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4594 ret = GST_FLOW_ERROR;
4600 gst_matroska_demux_loop (GstPad * pad)
4602 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4608 /* If we have to close a segment, send a new segment to do this now */
4609 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4610 if (G_UNLIKELY (demux->new_segment)) {
4611 gst_matroska_demux_send_event (demux, demux->new_segment);
4612 demux->new_segment = NULL;
4616 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4617 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4618 if (ret == GST_FLOW_EOS) {
4620 } else if (ret == GST_FLOW_FLUSHING) {
4622 } else if (ret != GST_FLOW_OK) {
4623 ret = gst_matroska_demux_check_parse_error (demux);
4625 /* Only handle EOS as no error if we're outside the segment already */
4626 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4627 && demux->common.offset >=
4628 demux->common.ebml_segment_start +
4629 demux->common.ebml_segment_length))
4631 else if (ret != GST_FLOW_OK)
4637 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4638 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4641 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4642 if (ret == GST_FLOW_EOS)
4644 if (ret != GST_FLOW_OK)
4647 /* check if we're at the end of a configured segment */
4648 if (G_LIKELY (demux->common.src->len)) {
4651 g_assert (demux->common.num_streams == demux->common.src->len);
4652 for (i = 0; i < demux->common.src->len; i++) {
4653 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4655 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4656 GST_TIME_ARGS (context->pos));
4657 if (context->eos == FALSE)
4661 GST_INFO_OBJECT (demux, "All streams are EOS");
4667 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4668 demux->common.offset >= demux->cached_length)) {
4669 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4670 if (demux->common.offset == demux->cached_length) {
4671 GST_LOG_OBJECT (demux, "Reached end of stream");
4682 if (demux->common.segment.rate < 0.0) {
4683 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4684 if (ret == GST_FLOW_OK)
4691 const gchar *reason = gst_flow_get_name (ret);
4692 gboolean push_eos = FALSE;
4694 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4695 gst_pad_pause_task (demux->common.sinkpad);
4697 if (ret == GST_FLOW_EOS) {
4698 /* perform EOS logic */
4700 /* If we were in the headers, make sure we send no-more-pads.
4701 This will ensure decodebin does not get stuck thinking
4702 the chain is not complete yet, and waiting indefinitely. */
4703 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4704 if (demux->common.src->len == 0) {
4705 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4706 ("No pads created"));
4708 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4709 ("Failed to finish reading headers"));
4711 gst_element_no_more_pads (GST_ELEMENT (demux));
4714 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4717 /* for segment playback we need to post when (in stream time)
4718 * we stopped, this is either stop (when set) or the duration. */
4719 if ((stop = demux->common.segment.stop) == -1)
4720 stop = demux->last_stop_end;
4722 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4723 gst_element_post_message (GST_ELEMENT (demux),
4724 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4726 gst_matroska_demux_send_event (demux,
4727 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4731 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4732 /* for fatal errors we post an error message */
4733 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4734 ("stream stopped, reason %s", reason));
4738 /* send EOS, and prevent hanging if no streams yet */
4739 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4740 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4741 (ret == GST_FLOW_EOS)) {
4742 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4743 (NULL), ("got eos but no streams (yet)"));
4751 * Create and push a flushing seek event upstream
4754 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4760 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4763 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4764 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4765 GST_SEEK_TYPE_NONE, -1);
4766 gst_event_set_seqnum (event, seqnum);
4768 res = gst_pad_push_event (demux->common.sinkpad, event);
4770 /* segment event will update offset */
4774 static GstFlowReturn
4775 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4777 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4779 GstFlowReturn ret = GST_FLOW_OK;
4784 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4785 GST_DEBUG_OBJECT (demux, "got DISCONT");
4786 gst_adapter_clear (demux->common.adapter);
4787 GST_OBJECT_LOCK (demux);
4788 gst_matroska_read_common_reset_streams (&demux->common,
4789 GST_CLOCK_TIME_NONE, FALSE);
4790 GST_OBJECT_UNLOCK (demux);
4793 gst_adapter_push (demux->common.adapter, buffer);
4797 available = gst_adapter_available (demux->common.adapter);
4799 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4800 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4801 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4802 if (demux->common.ebml_segment_length != G_MAXUINT64
4803 && demux->common.offset >=
4804 demux->common.ebml_segment_start + demux->common.ebml_segment_length)
4809 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4810 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4811 demux->common.offset, id, length, needed, available);
4813 if (needed > available)
4816 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4817 if (ret == GST_FLOW_EOS) {
4818 /* need more data */
4820 } else if (ret != GST_FLOW_OK) {
4827 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4830 gboolean res = TRUE;
4831 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4833 GST_DEBUG_OBJECT (demux,
4834 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4836 switch (GST_EVENT_TYPE (event)) {
4837 case GST_EVENT_SEGMENT:
4839 const GstSegment *segment;
4841 /* some debug output */
4842 gst_event_parse_segment (event, &segment);
4843 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4844 GST_DEBUG_OBJECT (demux,
4845 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4848 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4849 GST_DEBUG_OBJECT (demux, "still starting");
4853 /* we only expect a BYTE segment, e.g. following a seek */
4854 if (segment->format != GST_FORMAT_BYTES) {
4855 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4859 GST_DEBUG_OBJECT (demux, "clearing segment state");
4860 GST_OBJECT_LOCK (demux);
4861 /* clear current segment leftover */
4862 gst_adapter_clear (demux->common.adapter);
4863 /* and some streaming setup */
4864 demux->common.offset = segment->start;
4865 /* accumulate base based on current position */
4866 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4867 demux->common.segment.base +=
4868 (MAX (demux->common.segment.position, demux->stream_start_time)
4869 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4870 /* do not know where we are;
4871 * need to come across a cluster and generate segment */
4872 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4873 demux->cluster_time = GST_CLOCK_TIME_NONE;
4874 demux->cluster_offset = 0;
4875 demux->need_segment = TRUE;
4876 demux->segment_seqnum = gst_event_get_seqnum (event);
4877 /* but keep some of the upstream segment */
4878 demux->common.segment.rate = segment->rate;
4879 /* also check if need to keep some of the requested seek position */
4880 if (demux->seek_offset == segment->start) {
4881 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4882 demux->common.segment.position = demux->requested_seek_time;
4884 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4886 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4887 demux->seek_offset = -1;
4888 GST_OBJECT_UNLOCK (demux);
4890 /* chain will send initial segment after pads have been added,
4891 * or otherwise come up with one */
4892 GST_DEBUG_OBJECT (demux, "eating event");
4893 gst_event_unref (event);
4899 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4900 gst_event_unref (event);
4901 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4902 (NULL), ("got eos and didn't receive a complete header object"));
4903 } else if (demux->common.num_streams == 0) {
4904 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4905 (NULL), ("got eos but no streams (yet)"));
4907 gst_matroska_demux_send_event (demux, event);
4911 case GST_EVENT_FLUSH_STOP:
4915 gst_adapter_clear (demux->common.adapter);
4916 GST_OBJECT_LOCK (demux);
4917 gst_matroska_read_common_reset_streams (&demux->common,
4918 GST_CLOCK_TIME_NONE, TRUE);
4919 gst_flow_combiner_reset (demux->flowcombiner);
4920 dur = demux->common.segment.duration;
4921 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4922 demux->common.segment.duration = dur;
4923 demux->cluster_time = GST_CLOCK_TIME_NONE;
4924 demux->cluster_offset = 0;
4925 GST_OBJECT_UNLOCK (demux);
4929 res = gst_pad_event_default (pad, parent, event);
4937 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4939 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4941 gboolean pull_mode = FALSE;
4943 query = gst_query_new_scheduling ();
4945 if (gst_pad_peer_query (sinkpad, query))
4946 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4947 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4949 gst_query_unref (query);
4952 GST_DEBUG ("going to pull mode");
4953 demux->streaming = FALSE;
4954 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4956 GST_DEBUG ("going to push (streaming) mode");
4957 demux->streaming = TRUE;
4958 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4963 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4964 GstPadMode mode, gboolean active)
4967 case GST_PAD_MODE_PULL:
4969 /* if we have a scheduler we can start the task */
4970 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4973 gst_pad_stop_task (sinkpad);
4976 case GST_PAD_MODE_PUSH:
4984 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4985 videocontext, const gchar * codec_id, guint8 * data, guint size,
4986 gchar ** codec_name, guint32 * riff_fourcc)
4988 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4989 GstCaps *caps = NULL;
4991 g_assert (videocontext != NULL);
4992 g_assert (codec_name != NULL);
4997 /* TODO: check if we have all codec types from matroska-ids.h
4998 * check if we have to do more special things with codec_private
5001 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
5002 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
5005 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
5006 gst_riff_strf_vids *vids = NULL;
5009 GstBuffer *buf = NULL;
5011 vids = (gst_riff_strf_vids *) data;
5013 /* assure size is big enough */
5015 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
5018 if (size < sizeof (gst_riff_strf_vids)) {
5019 vids = g_new (gst_riff_strf_vids, 1);
5020 memcpy (vids, data, size);
5023 context->dts_only = TRUE; /* VFW files only store DTS */
5025 /* little-endian -> byte-order */
5026 vids->size = GUINT32_FROM_LE (vids->size);
5027 vids->width = GUINT32_FROM_LE (vids->width);
5028 vids->height = GUINT32_FROM_LE (vids->height);
5029 vids->planes = GUINT16_FROM_LE (vids->planes);
5030 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
5031 vids->compression = GUINT32_FROM_LE (vids->compression);
5032 vids->image_size = GUINT32_FROM_LE (vids->image_size);
5033 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
5034 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
5035 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
5036 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
5038 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
5039 gsize offset = sizeof (gst_riff_strf_vids);
5042 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
5043 size - offset), size - offset);
5047 *riff_fourcc = vids->compression;
5049 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
5050 buf, NULL, codec_name);
5053 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
5054 GST_FOURCC_ARGS (vids->compression));
5056 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
5057 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
5058 "video/x-compressed-yuv");
5059 context->intra_only =
5060 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
5064 gst_buffer_unref (buf);
5066 if (vids != (gst_riff_strf_vids *) data)
5069 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
5071 GstVideoFormat format;
5073 gst_video_info_init (&info);
5074 switch (videocontext->fourcc) {
5075 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5076 format = GST_VIDEO_FORMAT_I420;
5078 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5079 format = GST_VIDEO_FORMAT_YUY2;
5081 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5082 format = GST_VIDEO_FORMAT_YV12;
5084 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5085 format = GST_VIDEO_FORMAT_UYVY;
5087 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5088 format = GST_VIDEO_FORMAT_AYUV;
5090 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
5091 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
5092 format = GST_VIDEO_FORMAT_GRAY8;
5094 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
5095 format = GST_VIDEO_FORMAT_RGB;
5097 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
5098 format = GST_VIDEO_FORMAT_BGR;
5101 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5102 GST_FOURCC_ARGS (videocontext->fourcc));
5106 context->intra_only = TRUE;
5108 gst_video_info_set_format (&info, format, videocontext->pixel_width,
5109 videocontext->pixel_height);
5110 caps = gst_video_info_to_caps (&info);
5111 *codec_name = gst_pb_utils_get_codec_description (caps);
5112 context->alignment = 32;
5113 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5114 caps = gst_caps_new_simple ("video/x-divx",
5115 "divxversion", G_TYPE_INT, 4, NULL);
5116 *codec_name = g_strdup ("MPEG-4 simple profile");
5117 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5118 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5119 caps = gst_caps_new_simple ("video/mpeg",
5120 "mpegversion", G_TYPE_INT, 4,
5121 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5125 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5126 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5127 gst_buffer_unref (priv);
5129 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
5131 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5132 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5134 *codec_name = g_strdup ("MPEG-4 advanced profile");
5135 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5137 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5138 "divxversion", G_TYPE_INT, 3, NULL),
5139 gst_structure_new ("video/x-msmpeg",
5140 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5142 caps = gst_caps_new_simple ("video/x-msmpeg",
5143 "msmpegversion", G_TYPE_INT, 43, NULL);
5144 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5145 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5146 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5149 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5154 caps = gst_caps_new_simple ("video/mpeg",
5155 "systemstream", G_TYPE_BOOLEAN, FALSE,
5156 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5157 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5158 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5159 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5160 caps = gst_caps_new_empty_simple ("image/jpeg");
5161 *codec_name = g_strdup ("Motion-JPEG");
5162 context->intra_only = TRUE;
5163 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5164 caps = gst_caps_new_empty_simple ("video/x-h264");
5168 /* First byte is the version, second is the profile indication, and third
5169 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5170 * level indication. */
5171 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5174 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5175 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5176 gst_buffer_unref (priv);
5178 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5179 "alignment", G_TYPE_STRING, "au", NULL);
5181 GST_WARNING ("No codec data found, assuming output is byte-stream");
5182 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5185 *codec_name = g_strdup ("H264");
5186 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
5187 caps = gst_caps_new_empty_simple ("video/x-h265");
5191 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
5194 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5195 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5196 gst_buffer_unref (priv);
5198 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
5199 "alignment", G_TYPE_STRING, "au", NULL);
5201 GST_WARNING ("No codec data found, assuming output is byte-stream");
5202 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5205 *codec_name = g_strdup ("HEVC");
5206 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5207 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5208 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5209 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5210 gint rmversion = -1;
5212 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5214 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5216 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5218 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5221 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5222 "rmversion", G_TYPE_INT, rmversion, NULL);
5223 GST_DEBUG ("data:%p, size:0x%x", data, size);
5224 /* We need to extract the extradata ! */
5225 if (data && (size >= 0x22)) {
5230 subformat = GST_READ_UINT32_BE (data + 0x1a);
5231 rformat = GST_READ_UINT32_BE (data + 0x1e);
5234 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5236 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5237 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5238 gst_buffer_unref (priv);
5241 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5242 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5243 caps = gst_caps_new_empty_simple ("video/x-theora");
5244 context->stream_headers =
5245 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5246 context->codec_priv_size);
5247 /* FIXME: mark stream as broken and skip if there are no stream headers */
5248 context->send_stream_headers = TRUE;
5249 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5250 caps = gst_caps_new_empty_simple ("video/x-dirac");
5251 *codec_name = g_strdup_printf ("Dirac");
5252 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5253 caps = gst_caps_new_empty_simple ("video/x-vp8");
5254 *codec_name = g_strdup_printf ("On2 VP8");
5255 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5256 caps = gst_caps_new_empty_simple ("video/x-vp9");
5257 *codec_name = g_strdup_printf ("On2 VP9");
5258 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
5260 const gchar *variant, *variant_descr = "";
5262 /* Expect a fourcc in the codec private data */
5264 GST_WARNING ("Too small PRORESS fourcc (%d bytes)", size);
5268 fourcc = GST_STR_FOURCC (data);
5270 case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
5271 variant_descr = " 4:2:2 LT";
5274 case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
5276 variant_descr = " 4:2:2 HQ";
5278 case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
5280 variant_descr = " 4:4:4:4";
5282 case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
5284 variant_descr = " 4:2:2 Proxy";
5286 case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
5288 variant = "standard";
5289 variant_descr = " 4:2:2 SD";
5293 GST_LOG ("Prores video, codec fourcc %" GST_FOURCC_FORMAT,
5294 GST_FOURCC_ARGS (fourcc));
5296 caps = gst_caps_new_simple ("video/x-prores",
5297 "format", G_TYPE_STRING, variant, NULL);
5298 *codec_name = g_strdup_printf ("Apple ProRes%s", variant_descr);
5299 context->postprocess_frame = gst_matroska_demux_add_prores_header;
5301 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5307 GstStructure *structure;
5309 for (i = 0; i < gst_caps_get_size (caps); i++) {
5310 structure = gst_caps_get_structure (caps, i);
5312 /* FIXME: use the real unit here! */
5313 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5314 videocontext->pixel_width,
5315 videocontext->pixel_height,
5316 videocontext->display_width, videocontext->display_height);
5318 /* pixel width and height are the w and h of the video in pixels */
5319 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5320 gint w = videocontext->pixel_width;
5321 gint h = videocontext->pixel_height;
5323 gst_structure_set (structure,
5324 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5327 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5330 if (videocontext->display_width <= 0)
5331 videocontext->display_width = videocontext->pixel_width;
5332 if (videocontext->display_height <= 0)
5333 videocontext->display_height = videocontext->pixel_height;
5335 /* calculate the pixel aspect ratio using the display and pixel w/h */
5336 n = videocontext->display_width * videocontext->pixel_height;
5337 d = videocontext->display_height * videocontext->pixel_width;
5338 GST_DEBUG ("setting PAR to %d/%d", n, d);
5339 gst_structure_set (structure, "pixel-aspect-ratio",
5341 videocontext->display_width * videocontext->pixel_height,
5342 videocontext->display_height * videocontext->pixel_width, NULL);
5345 if (videocontext->default_fps > 0.0) {
5348 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5350 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5352 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5354 } else if (context->default_duration > 0) {
5357 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5359 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5360 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5362 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5363 fps_n, fps_d, NULL);
5365 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5369 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5370 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5373 if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
5374 if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
5375 videocontext->pixel_width, videocontext->pixel_height,
5376 videocontext->display_width * videocontext->pixel_height,
5377 videocontext->display_height * videocontext->pixel_width)) {
5378 videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
5380 gst_caps_set_simple (caps,
5381 "multiview-mode", G_TYPE_STRING,
5382 gst_video_multiview_mode_to_caps_string
5383 (videocontext->multiview_mode), "multiview-flags",
5384 GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
5385 GST_FLAG_SET_MASK_EXACT, NULL);
5388 caps = gst_caps_simplify (caps);
5395 * Some AAC specific code... *sigh*
5396 * FIXME: maybe we should use '15' and code the sample rate explicitly
5397 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5401 aac_rate_idx (gint rate)
5405 else if (75132 <= rate)
5407 else if (55426 <= rate)
5409 else if (46009 <= rate)
5411 else if (37566 <= rate)
5413 else if (27713 <= rate)
5415 else if (23004 <= rate)
5417 else if (18783 <= rate)
5419 else if (13856 <= rate)
5421 else if (11502 <= rate)
5423 else if (9391 <= rate)
5430 aac_profile_idx (const gchar * codec_id)
5434 if (strlen (codec_id) <= 12)
5436 else if (!strncmp (&codec_id[12], "MAIN", 4))
5438 else if (!strncmp (&codec_id[12], "LC", 2))
5440 else if (!strncmp (&codec_id[12], "SSR", 3))
5449 round_up_pow2 (guint n)
5460 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5463 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5464 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5465 gchar ** codec_name, guint16 * riff_audio_fmt)
5467 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5468 GstCaps *caps = NULL;
5470 g_assert (audiocontext != NULL);
5471 g_assert (codec_name != NULL);
5474 *riff_audio_fmt = 0;
5476 /* TODO: check if we have all codec types from matroska-ids.h
5477 * check if we have to do more special things with codec_private
5478 * check if we need bitdepth in different places too
5479 * implement channel position magic
5481 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5482 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5483 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5484 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5487 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5488 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5489 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5492 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5494 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5499 caps = gst_caps_new_simple ("audio/mpeg",
5500 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5501 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5502 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5503 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5506 GstAudioFormat format;
5508 sign = (audiocontext->bitdepth != 8);
5509 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5510 endianness = G_BIG_ENDIAN;
5512 endianness = G_LITTLE_ENDIAN;
5514 format = gst_audio_format_build_integer (sign, endianness,
5515 audiocontext->bitdepth, audiocontext->bitdepth);
5517 /* FIXME: Channel mask and reordering */
5518 caps = gst_caps_new_simple ("audio/x-raw",
5519 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5520 "layout", G_TYPE_STRING, "interleaved",
5521 "channel-mask", GST_TYPE_BITMASK,
5522 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5524 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5525 audiocontext->bitdepth);
5526 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5527 context->alignment = round_up_pow2 (context->alignment);
5528 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5529 const gchar *format;
5530 if (audiocontext->bitdepth == 32)
5534 /* FIXME: Channel mask and reordering */
5535 caps = gst_caps_new_simple ("audio/x-raw",
5536 "format", G_TYPE_STRING, format,
5537 "layout", G_TYPE_STRING, "interleaved",
5538 "channel-mask", GST_TYPE_BITMASK,
5539 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5540 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5541 audiocontext->bitdepth);
5542 context->alignment = audiocontext->bitdepth / 8;
5543 context->alignment = round_up_pow2 (context->alignment);
5544 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5545 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5546 caps = gst_caps_new_simple ("audio/x-ac3",
5547 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5548 *codec_name = g_strdup ("AC-3 audio");
5549 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5550 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5551 caps = gst_caps_new_simple ("audio/x-eac3",
5552 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5553 *codec_name = g_strdup ("E-AC-3 audio");
5554 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5555 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5556 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5557 *codec_name = g_strdup ("Dolby TrueHD");
5558 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5559 caps = gst_caps_new_empty_simple ("audio/x-dts");
5560 *codec_name = g_strdup ("DTS audio");
5561 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5562 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5563 context->stream_headers =
5564 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5565 context->codec_priv_size);
5566 /* FIXME: mark stream as broken and skip if there are no stream headers */
5567 context->send_stream_headers = TRUE;
5568 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5569 caps = gst_caps_new_empty_simple ("audio/x-flac");
5570 context->stream_headers =
5571 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5572 context->codec_priv_size);
5573 /* FIXME: mark stream as broken and skip if there are no stream headers */
5574 context->send_stream_headers = TRUE;
5575 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5576 caps = gst_caps_new_empty_simple ("audio/x-speex");
5577 context->stream_headers =
5578 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5579 context->codec_priv_size);
5580 /* FIXME: mark stream as broken and skip if there are no stream headers */
5581 context->send_stream_headers = TRUE;
5582 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5585 if (context->codec_priv_size >= 19) {
5586 if (audiocontext->samplerate)
5587 GST_WRITE_UINT32_LE ((guint8 *) context->codec_priv + 12,
5588 audiocontext->samplerate);
5589 if (context->codec_delay) {
5591 gst_util_uint64_scale_round (context->codec_delay, 48000,
5593 GST_WRITE_UINT16_LE ((guint8 *) context->codec_priv + 10, delay);
5597 gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5598 context->codec_priv_size), context->codec_priv_size);
5599 caps = gst_codec_utils_opus_create_caps_from_header (tmp, NULL);
5600 gst_buffer_unref (tmp);
5601 *codec_name = g_strdup ("Opus");
5603 GST_WARNING ("Invalid Opus codec data size");
5605 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5606 gst_riff_strf_auds auds;
5608 if (data && size >= 18) {
5609 GstBuffer *codec_data = NULL;
5611 /* little-endian -> byte-order */
5612 auds.format = GST_READ_UINT16_LE (data);
5613 auds.channels = GST_READ_UINT16_LE (data + 2);
5614 auds.rate = GST_READ_UINT32_LE (data + 4);
5615 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5616 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5617 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5619 /* 18 is the waveformatex size */
5621 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5622 data + 18, size - 18, 0, size - 18, NULL, NULL);
5626 *riff_audio_fmt = auds.format;
5628 /* FIXME: Handle reorder map */
5629 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5630 codec_data, codec_name, NULL);
5632 gst_buffer_unref (codec_data);
5635 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5638 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5640 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5641 GstBuffer *priv = NULL;
5643 gint rate_idx, profile;
5644 guint8 *data = NULL;
5646 /* unspecified AAC profile with opaque private codec data */
5647 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5648 if (context->codec_priv_size >= 2) {
5649 guint obj_type, freq_index, explicit_freq_bytes = 0;
5651 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5653 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5654 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5655 if (freq_index == 15)
5656 explicit_freq_bytes = 3;
5657 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5658 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5659 context->codec_priv_size), context->codec_priv_size);
5660 /* assume SBR if samplerate <= 24kHz */
5661 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5662 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5663 audiocontext->samplerate *= 2;
5666 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5667 /* this is pretty broken;
5668 * maybe we need to make up some default private,
5669 * or maybe ADTS data got dumped in.
5670 * Let's set up some private data now, and check actual data later */
5671 /* just try this and see what happens ... */
5672 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5673 context->postprocess_frame = gst_matroska_demux_check_aac;
5677 /* make up decoder-specific data if it is not supplied */
5681 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5682 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5684 rate_idx = aac_rate_idx (audiocontext->samplerate);
5685 profile = aac_profile_idx (codec_id);
5687 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5688 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5690 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5691 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5693 gst_buffer_unmap (priv, &map);
5694 gst_buffer_set_size (priv, 2);
5695 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5696 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5699 if (g_strrstr (codec_id, "SBR")) {
5700 /* HE-AAC (aka SBR AAC) */
5701 audiocontext->samplerate *= 2;
5702 rate_idx = aac_rate_idx (audiocontext->samplerate);
5703 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5704 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5705 data[4] = (1 << 7) | (rate_idx << 3);
5706 gst_buffer_unmap (priv, &map);
5708 gst_buffer_unmap (priv, &map);
5709 gst_buffer_set_size (priv, 2);
5712 gst_buffer_unmap (priv, &map);
5713 gst_buffer_unref (priv);
5715 GST_ERROR ("Unknown AAC profile and no codec private data");
5720 caps = gst_caps_new_simple ("audio/mpeg",
5721 "mpegversion", G_TYPE_INT, mpegversion,
5722 "framed", G_TYPE_BOOLEAN, TRUE,
5723 "stream-format", G_TYPE_STRING, "raw", NULL);
5724 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5725 if (context->codec_priv && context->codec_priv_size > 0)
5726 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5727 context->codec_priv, context->codec_priv_size);
5728 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5729 gst_buffer_unref (priv);
5731 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5732 caps = gst_caps_new_simple ("audio/x-tta",
5733 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5734 *codec_name = g_strdup ("TTA audio");
5735 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5736 caps = gst_caps_new_simple ("audio/x-wavpack",
5737 "width", G_TYPE_INT, audiocontext->bitdepth,
5738 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5739 *codec_name = g_strdup ("Wavpack audio");
5740 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5741 audiocontext->wvpk_block_index = 0;
5742 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5743 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5744 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5745 gint raversion = -1;
5747 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5749 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5754 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5755 "raversion", G_TYPE_INT, raversion, NULL);
5756 /* Extract extra information from caps, mapping varies based on codec */
5757 if (data && (size >= 0x50)) {
5764 guint extra_data_size;
5766 GST_ERROR ("real audio raversion:%d", raversion);
5767 if (raversion == 8) {
5769 flavor = GST_READ_UINT16_BE (data + 22);
5770 packet_size = GST_READ_UINT32_BE (data + 24);
5771 height = GST_READ_UINT16_BE (data + 40);
5772 leaf_size = GST_READ_UINT16_BE (data + 44);
5773 sample_width = GST_READ_UINT16_BE (data + 58);
5774 extra_data_size = GST_READ_UINT32_BE (data + 74);
5777 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5778 flavor, packet_size, height, leaf_size, sample_width,
5780 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5781 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5782 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5784 if ((size - 78) >= extra_data_size) {
5785 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5787 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5788 gst_buffer_unref (priv);
5793 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5794 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5795 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5796 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5797 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5798 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5799 *codec_name = g_strdup ("Real Audio Lossless");
5800 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5801 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5802 *codec_name = g_strdup ("Sony ATRAC3");
5804 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5809 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5812 for (i = 0; i < gst_caps_get_size (caps); i++) {
5813 gst_structure_set (gst_caps_get_structure (caps, i),
5814 "channels", G_TYPE_INT, audiocontext->channels,
5815 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5819 caps = gst_caps_simplify (caps);
5826 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5827 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5829 GstCaps *caps = NULL;
5830 GstMatroskaTrackContext *context =
5831 (GstMatroskaTrackContext *) subtitlecontext;
5833 /* for backwards compatibility */
5834 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5835 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5836 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5837 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5838 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5839 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5840 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5841 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5843 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5844 * Check if we have to do something with codec_private */
5845 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5846 /* well, plain text simply does not have a lot of markup ... */
5847 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5848 "pango-markup", NULL);
5849 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5850 subtitlecontext->check_markup = TRUE;
5851 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5852 caps = gst_caps_new_empty_simple ("application/x-ssa");
5853 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5854 subtitlecontext->check_markup = FALSE;
5855 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5856 caps = gst_caps_new_empty_simple ("application/x-ass");
5857 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5858 subtitlecontext->check_markup = FALSE;
5859 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5860 caps = gst_caps_new_empty_simple ("application/x-usf");
5861 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5862 subtitlecontext->check_markup = FALSE;
5863 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5864 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5865 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5866 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5867 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5868 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5869 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5870 context->stream_headers =
5871 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5872 context->codec_priv_size);
5873 /* FIXME: mark stream as broken and skip if there are no stream headers */
5874 context->send_stream_headers = TRUE;
5876 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5877 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5880 if (data != NULL && size > 0) {
5883 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5884 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5885 gst_buffer_unref (buf);
5893 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5895 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5897 GST_OBJECT_LOCK (demux);
5898 if (demux->common.element_index)
5899 gst_object_unref (demux->common.element_index);
5900 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5901 GST_OBJECT_UNLOCK (demux);
5902 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5903 demux->common.element_index);
5907 gst_matroska_demux_get_index (GstElement * element)
5909 GstIndex *result = NULL;
5910 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5912 GST_OBJECT_LOCK (demux);
5913 if (demux->common.element_index)
5914 result = gst_object_ref (demux->common.element_index);
5915 GST_OBJECT_UNLOCK (demux);
5917 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5923 static GstStateChangeReturn
5924 gst_matroska_demux_change_state (GstElement * element,
5925 GstStateChange transition)
5927 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5928 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5930 /* handle upwards state changes here */
5931 switch (transition) {
5936 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5938 /* handle downwards state changes */
5939 switch (transition) {
5940 case GST_STATE_CHANGE_PAUSED_TO_READY:
5941 gst_matroska_demux_reset (GST_ELEMENT (demux));
5951 gst_matroska_demux_set_property (GObject * object,
5952 guint prop_id, const GValue * value, GParamSpec * pspec)
5954 GstMatroskaDemux *demux;
5956 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5957 demux = GST_MATROSKA_DEMUX (object);
5960 case PROP_MAX_GAP_TIME:
5961 GST_OBJECT_LOCK (demux);
5962 demux->max_gap_time = g_value_get_uint64 (value);
5963 GST_OBJECT_UNLOCK (demux);
5966 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5972 gst_matroska_demux_get_property (GObject * object,
5973 guint prop_id, GValue * value, GParamSpec * pspec)
5975 GstMatroskaDemux *demux;
5977 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5978 demux = GST_MATROSKA_DEMUX (object);
5981 case PROP_MAX_GAP_TIME:
5982 GST_OBJECT_LOCK (demux);
5983 g_value_set_uint64 (value, demux->max_gap_time);
5984 GST_OBJECT_UNLOCK (demux);
5987 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5993 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5997 /* parser helper separate debug */
5998 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5999 0, "EBML stream helper class");
6001 /* create an elementfactory for the matroska_demux element */
6002 if (!gst_element_register (plugin, "matroskademux",
6003 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))