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)
2587 GstClockTime gap_threshold;
2590 GST_OBJECT_LOCK (demux);
2592 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2593 GST_TIME_ARGS (demux->common.segment.position));
2595 g_assert (demux->common.num_streams == demux->common.src->len);
2596 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2597 GstMatroskaTrackContext *context;
2599 context = g_ptr_array_index (demux->common.src, stream_nr);
2601 GST_LOG_OBJECT (demux,
2602 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2603 GST_TIME_ARGS (context->pos));
2605 /* Only send gap events on non-subtitle streams if lagging way behind.
2606 * The 0.5 second threshold for subtitle streams is also quite random. */
2607 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
2608 gap_threshold = GST_SECOND / 2;
2610 gap_threshold = 3 * GST_SECOND;
2612 /* Lag need only be considered if we have advanced into requested segment */
2613 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2614 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2615 demux->common.segment.position > demux->common.segment.start &&
2616 context->pos + gap_threshold < demux->common.segment.position) {
2619 guint64 start = context->pos;
2620 guint64 stop = demux->common.segment.position - gap_threshold;
2622 GST_DEBUG_OBJECT (demux,
2623 "Synchronizing stream %d with other by advancing time from %"
2624 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2625 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2627 context->pos = stop;
2629 event = gst_event_new_gap (start, stop - start);
2630 GST_OBJECT_UNLOCK (demux);
2631 gst_pad_push_event (context->pad, event);
2632 GST_OBJECT_LOCK (demux);
2636 GST_OBJECT_UNLOCK (demux);
2639 static GstFlowReturn
2640 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2641 GstMatroskaTrackContext * stream)
2643 GstFlowReturn ret = GST_FLOW_OK;
2646 num = gst_buffer_list_length (stream->stream_headers);
2647 for (i = 0; i < num; ++i) {
2650 buf = gst_buffer_list_get (stream->stream_headers, i);
2651 buf = gst_buffer_copy (buf);
2653 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2655 if (stream->set_discont) {
2656 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2657 stream->set_discont = FALSE;
2659 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2662 /* push out all headers in one go and use last flow return */
2663 ret = gst_pad_push (stream->pad, buf);
2666 /* don't need these any longer */
2667 gst_buffer_list_unref (stream->stream_headers);
2668 stream->stream_headers = NULL;
2671 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2677 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2678 GstMatroskaTrackContext * stream)
2682 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2684 if (!stream->codec_priv)
2687 /* ideally, VobSub private data should be parsed and stored more convenient
2688 * elsewhere, but for now, only interested in a small part */
2690 /* make sure we have terminating 0 */
2691 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2693 /* just locate and parse palette part */
2694 start = strstr (buf, "palette:");
2699 guint8 r, g, b, y, u, v;
2702 while (g_ascii_isspace (*start))
2704 for (i = 0; i < 16; i++) {
2705 if (sscanf (start, "%06x", &col) != 1)
2708 while ((*start == ',') || g_ascii_isspace (*start))
2710 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2711 r = (col >> 16) & 0xff;
2712 g = (col >> 8) & 0xff;
2714 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2716 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2717 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2718 clut[i] = (y << 16) | (u << 8) | v;
2721 /* got them all without problems; build and send event */
2725 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2726 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2727 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2728 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2729 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2730 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2731 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2732 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2733 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2734 G_TYPE_INT, clut[15], NULL);
2736 gst_pad_push_event (stream->pad,
2737 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2744 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2748 GST_OBJECT_LOCK (demux);
2750 g_assert (demux->common.num_streams == demux->common.src->len);
2751 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2752 GstMatroskaTrackContext *stream;
2754 stream = g_ptr_array_index (demux->common.src, stream_nr);
2756 if (stream->send_stream_headers) {
2757 if (stream->stream_headers != NULL) {
2758 gst_matroska_demux_push_stream_headers (demux, stream);
2760 /* FIXME: perhaps we can just disable and skip this stream then */
2761 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2762 ("Failed to extract stream headers from codec private data"));
2764 stream->send_stream_headers = FALSE;
2767 if (stream->send_dvd_event) {
2768 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2769 /* FIXME: should we send this event again after (flushing) seek ? */
2770 stream->send_dvd_event = FALSE;
2774 GST_OBJECT_UNLOCK (demux);
2777 static GstFlowReturn
2778 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2779 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2782 guint seq_header_len;
2783 guint32 header, tmp;
2785 if (stream->codec_state) {
2786 seq_header = stream->codec_state;
2787 seq_header_len = stream->codec_state_size;
2788 } else if (stream->codec_priv) {
2789 seq_header = stream->codec_priv;
2790 seq_header_len = stream->codec_priv_size;
2795 /* Sequence header only needed for keyframes */
2796 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2799 if (gst_buffer_get_size (*buf) < 4)
2802 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2803 header = GUINT32_FROM_BE (tmp);
2805 /* Sequence start code, if not found prepend */
2806 if (header != 0x000001b3) {
2809 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2811 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2814 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2815 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2816 gst_buffer_get_size (*buf));
2818 gst_buffer_unref (*buf);
2825 static GstFlowReturn
2826 gst_matroska_demux_add_wvpk_header (GstElement * element,
2827 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2829 GstMatroskaTrackAudioContext *audiocontext =
2830 (GstMatroskaTrackAudioContext *) stream;
2831 GstBuffer *newbuf = NULL;
2832 GstMapInfo map, outmap;
2833 guint8 *buf_data, *data;
2841 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2844 wvh.total_samples = -1;
2845 wvh.block_index = audiocontext->wvpk_block_index;
2847 if (audiocontext->channels <= 2) {
2848 guint32 block_samples, tmp;
2849 gsize size = gst_buffer_get_size (*buf);
2851 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2852 block_samples = GUINT32_FROM_LE (tmp);
2853 /* we need to reconstruct the header of the wavpack block */
2855 /* -20 because ck_size is the size of the wavpack block -8
2856 * and lace_size is the size of the wavpack block + 12
2857 * (the three guint32 of the header that already are in the buffer) */
2858 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2860 /* block_samples, flags and crc are already in the buffer */
2861 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2863 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2869 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2870 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2871 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2872 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2873 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2874 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2876 /* Append data from buf: */
2877 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2878 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2880 gst_buffer_unref (*buf);
2882 audiocontext->wvpk_block_index += block_samples;
2884 guint8 *outdata = NULL;
2886 gsize buf_size, size, out_size = 0;
2887 guint32 block_samples, flags, crc, blocksize;
2889 gst_buffer_map (*buf, &map, GST_MAP_READ);
2890 buf_data = map.data;
2891 buf_size = map.size;
2894 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2895 gst_buffer_unmap (*buf, &map);
2896 return GST_FLOW_ERROR;
2902 block_samples = GST_READ_UINT32_LE (data);
2907 flags = GST_READ_UINT32_LE (data);
2910 crc = GST_READ_UINT32_LE (data);
2913 blocksize = GST_READ_UINT32_LE (data);
2917 if (blocksize == 0 || size < blocksize)
2920 g_assert ((newbuf == NULL) == (outdata == NULL));
2922 if (newbuf == NULL) {
2923 out_size = sizeof (Wavpack4Header) + blocksize;
2924 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2926 gst_buffer_copy_into (newbuf, *buf,
2927 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2930 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2931 outdata = outmap.data;
2933 gst_buffer_unmap (newbuf, &outmap);
2934 out_size += sizeof (Wavpack4Header) + blocksize;
2935 gst_buffer_set_size (newbuf, out_size);
2936 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2937 outdata = outmap.data;
2940 outdata[outpos] = 'w';
2941 outdata[outpos + 1] = 'v';
2942 outdata[outpos + 2] = 'p';
2943 outdata[outpos + 3] = 'k';
2946 GST_WRITE_UINT32_LE (outdata + outpos,
2947 blocksize + sizeof (Wavpack4Header) - 8);
2948 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2949 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2950 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2951 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2952 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2953 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2954 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2955 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2958 memmove (outdata + outpos, data, blocksize);
2959 outpos += blocksize;
2963 gst_buffer_unmap (*buf, &map);
2964 gst_buffer_unref (*buf);
2967 gst_buffer_unmap (newbuf, &outmap);
2970 audiocontext->wvpk_block_index += block_samples;
2976 static GstFlowReturn
2977 gst_matroska_demux_add_prores_header (GstElement * element,
2978 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2980 GstBuffer *newbuf = gst_buffer_new_allocate (NULL, 8, NULL);
2984 if (!gst_buffer_map (newbuf, &map, GST_MAP_WRITE)) {
2985 GST_ERROR ("Failed to map newly allocated buffer");
2986 return GST_FLOW_ERROR;
2989 frame_size = gst_buffer_get_size (*buf);
2991 GST_WRITE_UINT32_BE (map.data, frame_size);
2997 gst_buffer_unmap (newbuf, &map);
2998 *buf = gst_buffer_append (newbuf, *buf);
3003 /* @text must be null-terminated */
3005 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
3010 g_return_val_if_fail (text != NULL, FALSE);
3012 /* yes, this might all lead to false positives ... */
3013 tag = (gchar *) text;
3014 while ((tag = strchr (tag, '<'))) {
3016 if (*tag != '\0' && *(tag + 1) == '>') {
3017 /* some common convenience ones */
3018 /* maybe any character will do here ? */
3031 if (strstr (text, "<span"))
3037 static GstFlowReturn
3038 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
3039 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3041 GstMatroskaTrackSubtitleContext *sub_stream;
3042 const gchar *encoding;
3047 gboolean needs_unmap = TRUE;
3049 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3051 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
3054 /* The subtitle buffer we push out should not include a NUL terminator as
3055 * part of the data. */
3056 if (map.data[map.size - 1] == '\0') {
3057 gst_buffer_set_size (*buf, map.size - 1);
3058 gst_buffer_unmap (*buf, &map);
3059 gst_buffer_map (*buf, &map, GST_MAP_READ);
3062 if (!sub_stream->invalid_utf8) {
3063 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
3066 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
3067 " is not valid UTF-8, this is broken according to the matroska"
3068 " specification", stream->num);
3069 sub_stream->invalid_utf8 = TRUE;
3072 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3073 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3074 if (encoding == NULL || *encoding == '\0') {
3075 /* if local encoding is UTF-8 and no encoding specified
3076 * via the environment variable, assume ISO-8859-15 */
3077 if (g_get_charset (&encoding)) {
3078 encoding = "ISO-8859-15";
3083 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3084 (char *) "*", NULL, NULL, &err);
3087 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3088 encoding, err->message);
3092 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3093 encoding = "ISO-8859-15";
3095 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3096 encoding, (char *) "*", NULL, NULL, NULL);
3099 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3100 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3103 utf8 = g_strdup ("invalid subtitle");
3105 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3106 gst_buffer_unmap (*buf, &map);
3107 gst_buffer_copy_into (newbuf, *buf,
3108 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3110 gst_buffer_unref (*buf);
3113 gst_buffer_map (*buf, &map, GST_MAP_READ);
3117 if (sub_stream->check_markup) {
3118 /* caps claim markup text, so we need to escape text,
3119 * except if text is already markup and then needs no further escaping */
3120 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3121 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3123 if (!sub_stream->seen_markup_tag) {
3124 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3126 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3127 gst_buffer_unmap (*buf, &map);
3128 gst_buffer_copy_into (newbuf, *buf,
3129 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3130 GST_BUFFER_COPY_META, 0, -1);
3131 gst_buffer_unref (*buf);
3134 needs_unmap = FALSE;
3139 gst_buffer_unmap (*buf, &map);
3144 static GstFlowReturn
3145 gst_matroska_demux_check_aac (GstElement * element,
3146 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3151 gst_buffer_extract (*buf, 0, data, 2);
3152 size = gst_buffer_get_size (*buf);
3154 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3157 /* tss, ADTS data, remove codec_data
3158 * still assume it is at least parsed */
3159 stream->caps = gst_caps_make_writable (stream->caps);
3160 s = gst_caps_get_structure (stream->caps, 0);
3162 gst_structure_remove_field (s, "codec_data");
3163 gst_pad_set_caps (stream->pad, stream->caps);
3164 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3165 "new caps: %" GST_PTR_FORMAT, stream->caps);
3168 /* disable subsequent checking */
3169 stream->postprocess_frame = NULL;
3175 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3176 GstBuffer * buffer, gsize alignment)
3180 gst_buffer_map (buffer, &map, GST_MAP_READ);
3182 if (map.size < sizeof (guintptr)) {
3183 gst_buffer_unmap (buffer, &map);
3187 if (((guintptr) map.data) & (alignment - 1)) {
3188 GstBuffer *new_buffer;
3189 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3191 new_buffer = gst_buffer_new_allocate (NULL,
3192 gst_buffer_get_size (buffer), ¶ms);
3194 /* Copy data "by hand", so ensure alignment is kept: */
3195 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3197 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3198 GST_DEBUG_OBJECT (demux,
3199 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3202 gst_buffer_unmap (buffer, &map);
3203 gst_buffer_unref (buffer);
3208 gst_buffer_unmap (buffer, &map);
3212 static GstFlowReturn
3213 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3214 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3215 gboolean is_simpleblock)
3217 GstMatroskaTrackContext *stream = NULL;
3218 GstFlowReturn ret = GST_FLOW_OK;
3219 gboolean readblock = FALSE;
3221 guint64 block_duration = -1;
3222 gint64 block_discardpadding = 0;
3223 GstBuffer *buf = NULL;
3225 gint stream_num = -1, n, laces = 0;
3227 gint *lace_size = NULL;
3230 gint64 referenceblock = 0;
3232 GstClockTime buffer_timestamp;
3234 offset = gst_ebml_read_get_offset (ebml);
3236 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3237 if (!is_simpleblock) {
3238 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3242 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3246 /* one block inside the group. Note, block parsing is one
3247 * of the harder things, so this code is a bit complicated.
3248 * See http://www.matroska.org/ for documentation. */
3249 case GST_MATROSKA_ID_SIMPLEBLOCK:
3250 case GST_MATROSKA_ID_BLOCK:
3256 gst_buffer_unmap (buf, &map);
3257 gst_buffer_unref (buf);
3260 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3263 gst_buffer_map (buf, &map, GST_MAP_READ);
3267 /* first byte(s): blocknum */
3268 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3273 /* fetch stream from num */
3274 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3276 if (G_UNLIKELY (size < 3)) {
3277 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3278 /* non-fatal, try next block(group) */
3281 } else if (G_UNLIKELY (stream_num < 0 ||
3282 stream_num >= demux->common.num_streams)) {
3283 /* let's not give up on a stray invalid track number */
3284 GST_WARNING_OBJECT (demux,
3285 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3286 "; ignoring block", stream_num, num);
3290 stream = g_ptr_array_index (demux->common.src, stream_num);
3292 /* time (relative to cluster time) */
3293 time = ((gint16) GST_READ_UINT16_BE (data));
3296 flags = GST_READ_UINT8 (data);
3300 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3303 switch ((flags & 0x06) >> 1) {
3304 case 0x0: /* no lacing */
3306 lace_size = g_new (gint, 1);
3307 lace_size[0] = size;
3310 case 0x1: /* xiph lacing */
3311 case 0x2: /* fixed-size lacing */
3312 case 0x3: /* EBML lacing */
3314 goto invalid_lacing;
3315 laces = GST_READ_UINT8 (data) + 1;
3318 lace_size = g_new0 (gint, laces);
3320 switch ((flags & 0x06) >> 1) {
3321 case 0x1: /* xiph lacing */ {
3322 guint temp, total = 0;
3324 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3327 goto invalid_lacing;
3328 temp = GST_READ_UINT8 (data);
3329 lace_size[n] += temp;
3335 total += lace_size[n];
3337 lace_size[n] = size - total;
3341 case 0x2: /* fixed-size lacing */
3342 for (n = 0; n < laces; n++)
3343 lace_size[n] = size / laces;
3346 case 0x3: /* EBML lacing */ {
3349 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3353 total = lace_size[0] = num;
3354 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3358 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3362 lace_size[n] = lace_size[n - 1] + snum;
3363 total += lace_size[n];
3366 lace_size[n] = size - total;
3373 if (ret != GST_FLOW_OK)
3380 case GST_MATROSKA_ID_BLOCKDURATION:{
3381 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3382 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3387 case GST_MATROSKA_ID_DISCARDPADDING:{
3388 ret = gst_ebml_read_sint (ebml, &id, &block_discardpadding);
3389 GST_DEBUG_OBJECT (demux, "DiscardPadding: %" GST_STIME_FORMAT,
3390 GST_STIME_ARGS (block_discardpadding));
3394 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3395 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3396 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3401 case GST_MATROSKA_ID_CODECSTATE:{
3403 guint64 data_len = 0;
3406 gst_ebml_read_binary (ebml, &id, &data,
3407 &data_len)) != GST_FLOW_OK)
3410 if (G_UNLIKELY (stream == NULL)) {
3411 GST_WARNING_OBJECT (demux,
3412 "Unexpected CodecState subelement - ignoring");
3416 g_free (stream->codec_state);
3417 stream->codec_state = data;
3418 stream->codec_state_size = data_len;
3420 /* Decode if necessary */
3421 if (stream->encodings && stream->encodings->len > 0
3422 && stream->codec_state && stream->codec_state_size > 0) {
3423 if (!gst_matroska_decode_data (stream->encodings,
3424 &stream->codec_state, &stream->codec_state_size,
3425 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3426 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3430 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3431 stream->codec_state_size);
3436 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3440 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3441 case GST_MATROSKA_ID_BLOCKADDITIONS:
3442 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3443 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3444 case GST_MATROSKA_ID_SLICES:
3445 GST_DEBUG_OBJECT (demux,
3446 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3447 ret = gst_ebml_read_skip (ebml);
3455 /* reading a number or so could have failed */
3456 if (ret != GST_FLOW_OK)
3459 if (ret == GST_FLOW_OK && readblock) {
3460 gboolean invisible_frame = FALSE;
3461 gboolean delta_unit = FALSE;
3462 guint64 duration = 0;
3463 gint64 lace_time = 0;
3465 stream = g_ptr_array_index (demux->common.src, stream_num);
3467 if (cluster_time != GST_CLOCK_TIME_NONE) {
3468 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3469 * Drop unless the lace contains timestamp 0? */
3470 if (time < 0 && (-time) > cluster_time) {
3473 if (stream->timecodescale == 1.0)
3474 lace_time = (cluster_time + time) * demux->common.time_scale;
3477 gst_util_guint64_to_gdouble ((cluster_time + time) *
3478 demux->common.time_scale) * stream->timecodescale;
3481 lace_time = GST_CLOCK_TIME_NONE;
3484 /* need to refresh segment info ASAP */
3485 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3486 GstSegment *segment = &demux->common.segment;
3488 GstEvent *segment_event;
3490 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3491 demux->stream_start_time = lace_time;
3492 GST_DEBUG_OBJECT (demux,
3493 "Setting stream start time to %" GST_TIME_FORMAT,
3494 GST_TIME_ARGS (lace_time));
3496 clace_time = MAX (lace_time, demux->stream_start_time);
3497 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3498 demux->common.segment.position != 0) {
3499 GST_DEBUG_OBJECT (demux,
3500 "using stored seek position %" GST_TIME_FORMAT,
3501 GST_TIME_ARGS (demux->common.segment.position));
3502 clace_time = demux->common.segment.position + demux->stream_start_time;
3503 segment->position = GST_CLOCK_TIME_NONE;
3505 segment->start = clace_time;
3506 segment->stop = GST_CLOCK_TIME_NONE;
3507 segment->time = segment->start - demux->stream_start_time;
3508 segment->position = segment->start - demux->stream_start_time;
3509 GST_DEBUG_OBJECT (demux,
3510 "generated segment starting at %" GST_TIME_FORMAT ": %"
3511 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3512 /* now convey our segment notion downstream */
3513 segment_event = gst_event_new_segment (segment);
3514 if (demux->segment_seqnum)
3515 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3516 gst_matroska_demux_send_event (demux, segment_event);
3517 demux->need_segment = FALSE;
3518 demux->segment_seqnum = 0;
3521 /* send pending codec data headers for all streams,
3522 * before we perform sync across all streams */
3523 gst_matroska_demux_push_codec_data_all (demux);
3525 if (block_duration != -1) {
3526 if (stream->timecodescale == 1.0)
3527 duration = gst_util_uint64_scale (block_duration,
3528 demux->common.time_scale, 1);
3531 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3532 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3533 1)) * stream->timecodescale);
3534 } else if (stream->default_duration) {
3535 duration = stream->default_duration * laces;
3537 /* else duration is diff between timecode of this and next block */
3539 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3540 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3541 a ReferenceBlock implies that this is not a keyframe. In either
3542 case, it only makes sense for video streams. */
3543 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3545 invisible_frame = ((flags & 0x08)) &&
3546 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3547 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3550 /* If we're doing a keyframe-only trickmode, only push keyframes on video
3554 segment.flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) {
3555 GST_LOG_OBJECT (demux, "Skipping non-keyframe on stream %d",
3562 for (n = 0; n < laces; n++) {
3565 if (G_UNLIKELY (lace_size[n] > size)) {
3566 GST_WARNING_OBJECT (demux, "Invalid lace size");
3570 /* QoS for video track with an index. the assumption is that
3571 index entries point to keyframes, but if that is not true we
3572 will instad skip until the next keyframe. */
3573 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3574 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3575 stream->index_table && demux->common.segment.rate > 0.0) {
3576 GstMatroskaTrackVideoContext *videocontext =
3577 (GstMatroskaTrackVideoContext *) stream;
3578 GstClockTime earliest_time;
3579 GstClockTime earliest_stream_time;
3581 GST_OBJECT_LOCK (demux);
3582 earliest_time = videocontext->earliest_time;
3583 GST_OBJECT_UNLOCK (demux);
3584 earliest_stream_time =
3585 gst_segment_position_from_running_time (&demux->common.segment,
3586 GST_FORMAT_TIME, earliest_time);
3588 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3589 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3590 lace_time <= earliest_stream_time) {
3591 /* find index entry (keyframe) <= earliest_stream_time */
3592 GstMatroskaIndex *entry =
3593 gst_util_array_binary_search (stream->index_table->data,
3594 stream->index_table->len, sizeof (GstMatroskaIndex),
3595 (GCompareDataFunc) gst_matroska_index_seek_find,
3596 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3598 /* if that entry (keyframe) is after the current the current
3599 buffer, we can skip pushing (and thus decoding) all
3600 buffers until that keyframe. */
3601 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3602 entry->time > lace_time) {
3603 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3604 stream->set_discont = TRUE;
3610 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3611 gst_buffer_get_size (buf) - size, lace_size[n]);
3612 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3615 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3617 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3619 if (invisible_frame)
3620 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3622 if (stream->encodings != NULL && stream->encodings->len > 0)
3623 sub = gst_matroska_decode_buffer (stream, sub);
3626 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3630 if (!stream->dts_only) {
3631 GST_BUFFER_PTS (sub) = lace_time;
3633 GST_BUFFER_DTS (sub) = lace_time;
3634 if (stream->intra_only)
3635 GST_BUFFER_PTS (sub) = lace_time;
3638 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
3640 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3641 GstClockTime last_stop_end;
3643 /* Check if this stream is after segment stop */
3644 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3645 lace_time >= demux->common.segment.stop) {
3646 GST_DEBUG_OBJECT (demux,
3647 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3648 GST_TIME_ARGS (demux->common.segment.stop));
3649 gst_buffer_unref (sub);
3652 if (offset >= stream->to_offset
3653 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3654 && lace_time > demux->to_time)) {
3655 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3657 gst_buffer_unref (sub);
3661 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3662 * that landed us with timestamps not quite intended */
3663 GST_OBJECT_LOCK (demux);
3664 if (demux->max_gap_time &&
3665 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3666 demux->common.segment.rate > 0.0) {
3667 GstClockTimeDiff diff;
3669 /* only send segments with increasing start times,
3670 * otherwise if these go back and forth downstream (sinks) increase
3671 * accumulated time and running_time */
3672 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3673 if (diff > 0 && diff > demux->max_gap_time
3674 && lace_time > demux->common.segment.start
3675 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3676 || lace_time < demux->common.segment.stop)) {
3678 GST_DEBUG_OBJECT (demux,
3679 "Gap of %" G_GINT64_FORMAT " ns detected in"
3680 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3681 "Sending updated SEGMENT events", diff,
3682 stream->index, GST_TIME_ARGS (stream->pos),
3683 GST_TIME_ARGS (lace_time));
3685 event = gst_event_new_gap (demux->last_stop_end, diff);
3686 GST_OBJECT_UNLOCK (demux);
3687 gst_pad_push_event (stream->pad, event);
3688 GST_OBJECT_LOCK (demux);
3692 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3693 || demux->common.segment.position < lace_time) {
3694 demux->common.segment.position = lace_time;
3696 GST_OBJECT_UNLOCK (demux);
3698 last_stop_end = lace_time;
3700 GST_BUFFER_DURATION (sub) = duration / laces;
3701 last_stop_end += GST_BUFFER_DURATION (sub);
3704 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3705 demux->last_stop_end < last_stop_end)
3706 demux->last_stop_end = last_stop_end;
3708 GST_OBJECT_LOCK (demux);
3709 if (demux->common.segment.duration == -1 ||
3710 demux->stream_start_time + demux->common.segment.duration <
3712 demux->common.segment.duration =
3713 last_stop_end - demux->stream_start_time;
3714 GST_OBJECT_UNLOCK (demux);
3715 if (!demux->invalid_duration) {
3716 gst_element_post_message (GST_ELEMENT_CAST (demux),
3717 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3718 demux->invalid_duration = TRUE;
3721 GST_OBJECT_UNLOCK (demux);
3725 stream->pos = lace_time;
3727 gst_matroska_demux_sync_streams (demux);
3729 if (stream->set_discont) {
3730 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3731 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3732 stream->set_discont = FALSE;
3734 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3737 /* reverse playback book-keeping */
3738 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3739 stream->from_time = lace_time;
3740 if (stream->from_offset == -1)
3741 stream->from_offset = offset;
3743 GST_DEBUG_OBJECT (demux,
3744 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3745 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3746 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3747 GST_TIME_ARGS (buffer_timestamp),
3748 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3751 if (demux->common.element_index) {
3752 if (stream->index_writer_id == -1)
3753 gst_index_get_writer_id (demux->common.element_index,
3754 GST_OBJECT (stream->pad), &stream->index_writer_id);
3756 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3757 G_GUINT64_FORMAT " for writer id %d",
3758 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
3759 stream->index_writer_id);
3760 gst_index_add_association (demux->common.element_index,
3761 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3762 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3763 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
3768 /* Postprocess the buffers depending on the codec used */
3769 if (stream->postprocess_frame) {
3770 GST_LOG_OBJECT (demux, "running post process");
3771 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3774 /* At this point, we have a sub-buffer pointing at data within a larger
3775 buffer. This data might not be aligned with anything. If the data is
3776 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3777 for 32 bit samples, etc), or bad things will happen downstream as
3778 elements typically assume minimal alignment.
3779 Therefore, create an aligned copy if necessary. */
3780 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3782 if (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
3783 guint64 start_clip = 0, end_clip = 0;
3785 /* Codec delay is part of the timestamps */
3786 if (GST_BUFFER_PTS_IS_VALID (sub) && stream->codec_delay) {
3787 if (GST_BUFFER_PTS (sub) > stream->codec_delay) {
3788 GST_BUFFER_PTS (sub) -= stream->codec_delay;
3790 GST_BUFFER_PTS (sub) = 0;
3792 gst_util_uint64_scale_round (stream->codec_delay, 48000,
3795 if (GST_BUFFER_DURATION_IS_VALID (sub)) {
3796 if (GST_BUFFER_DURATION (sub) > stream->codec_delay)
3797 GST_BUFFER_DURATION (sub) -= stream->codec_delay;
3799 GST_BUFFER_DURATION (sub) = 0;
3804 if (block_discardpadding) {
3806 gst_util_uint64_scale_round (block_discardpadding, 48000,
3810 if (start_clip || end_clip) {
3811 gst_buffer_add_audio_clipping_meta (sub, GST_FORMAT_DEFAULT,
3812 start_clip, end_clip);
3816 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3817 stream->pos = GST_BUFFER_PTS (sub);
3818 if (GST_BUFFER_DURATION_IS_VALID (sub))
3819 stream->pos += GST_BUFFER_DURATION (sub);
3820 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
3821 stream->pos = GST_BUFFER_DTS (sub);
3822 if (GST_BUFFER_DURATION_IS_VALID (sub))
3823 stream->pos += GST_BUFFER_DURATION (sub);
3826 ret = gst_pad_push (stream->pad, sub);
3828 if (demux->common.segment.rate < 0) {
3829 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3830 /* In reverse playback we can get a GST_FLOW_EOS when
3831 * we are at the end of the segment, so we just need to jump
3832 * back to the previous section. */
3833 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3838 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
3842 size -= lace_size[n];
3843 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3844 lace_time += duration / laces;
3846 lace_time = GST_CLOCK_TIME_NONE;
3852 gst_buffer_unmap (buf, &map);
3853 gst_buffer_unref (buf);
3865 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
3871 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3872 /* non-fatal, try next block(group) */
3878 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3879 /* non-fatal, try next block(group) */
3885 /* return FALSE if block(group) should be skipped (due to a seek) */
3886 static inline gboolean
3887 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3889 if (G_UNLIKELY (demux->seek_block)) {
3890 if (!(--demux->seek_block)) {
3893 GST_LOG_OBJECT (demux, "should skip block due to seek");
3901 static GstFlowReturn
3902 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3906 guint64 seek_pos = (guint64) - 1;
3907 guint32 seek_id = 0;
3910 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3912 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3913 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3917 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3918 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3922 case GST_MATROSKA_ID_SEEKID:
3926 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3929 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3934 case GST_MATROSKA_ID_SEEKPOSITION:
3938 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3941 if (t > G_MAXINT64) {
3942 GST_WARNING_OBJECT (demux,
3943 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3947 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3953 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3959 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3962 if (!seek_id || seek_pos == (guint64) - 1) {
3963 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3964 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3969 case GST_MATROSKA_ID_SEEKHEAD:
3972 case GST_MATROSKA_ID_CUES:
3973 case GST_MATROSKA_ID_TAGS:
3974 case GST_MATROSKA_ID_TRACKS:
3975 case GST_MATROSKA_ID_SEGMENTINFO:
3976 case GST_MATROSKA_ID_ATTACHMENTS:
3977 case GST_MATROSKA_ID_CHAPTERS:
3979 guint64 before_pos, length;
3983 length = gst_matroska_read_common_get_length (&demux->common);
3984 before_pos = demux->common.offset;
3986 if (length == (guint64) - 1) {
3987 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3991 /* check for validity */
3992 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3993 GST_WARNING_OBJECT (demux,
3994 "SeekHead reference lies outside file!" " (%"
3995 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3996 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
4001 /* only pick up index location when streaming */
4002 if (demux->streaming) {
4003 if (seek_id == GST_MATROSKA_ID_CUES) {
4004 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
4005 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
4006 demux->index_offset);
4012 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
4015 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4016 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
4020 if (id != seek_id) {
4021 GST_WARNING_OBJECT (demux,
4022 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
4023 seek_id, id, seek_pos + demux->common.ebml_segment_start);
4026 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4031 demux->common.offset = before_pos;
4035 case GST_MATROSKA_ID_CLUSTER:
4037 guint64 pos = seek_pos + demux->common.ebml_segment_start;
4039 GST_LOG_OBJECT (demux, "Cluster position");
4040 if (G_UNLIKELY (!demux->clusters))
4041 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
4042 g_array_append_val (demux->clusters, pos);
4047 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
4050 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4055 static GstFlowReturn
4056 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4058 GstFlowReturn ret = GST_FLOW_OK;
4061 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4063 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4064 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4068 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4069 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4073 case GST_MATROSKA_ID_SEEKENTRY:
4075 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
4076 /* Ignore EOS and errors here */
4077 if (ret != GST_FLOW_OK) {
4078 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4085 ret = gst_matroska_read_common_parse_skip (&demux->common,
4086 ebml, "SeekHead", id);
4091 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4093 /* Sort clusters by position for easier searching */
4094 if (demux->clusters)
4095 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4100 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
4102 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4104 static inline GstFlowReturn
4105 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4107 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4108 /* only a few blocks are expected/allowed to be large,
4109 * and will be recursed into, whereas others will be read and must fit */
4110 if (demux->streaming) {
4111 /* fatal in streaming case, as we can't step over easily */
4112 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4113 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4114 "file might be corrupt.", bytes));
4115 return GST_FLOW_ERROR;
4117 /* indicate higher level to quietly give up */
4118 GST_DEBUG_OBJECT (demux,
4119 "too large block of size %" G_GUINT64_FORMAT, bytes);
4120 return GST_FLOW_ERROR;
4127 /* returns TRUE if we truely are in error state, and should give up */
4128 static inline GstFlowReturn
4129 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4131 if (!demux->streaming && demux->next_cluster_offset > 0) {
4132 /* just repositioning to where next cluster should be and try from there */
4133 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4134 G_GUINT64_FORMAT, demux->next_cluster_offset);
4135 demux->common.offset = demux->next_cluster_offset;
4136 demux->next_cluster_offset = 0;
4142 /* sigh, one last attempt above and beyond call of duty ...;
4143 * search for cluster mark following current pos */
4144 pos = demux->common.offset;
4145 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4146 if ((ret = gst_matroska_demux_search_cluster (demux, &pos)) != GST_FLOW_OK) {
4147 /* did not work, give up */
4150 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4151 /* try that position */
4152 demux->common.offset = pos;
4158 static inline GstFlowReturn
4159 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4161 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4162 demux->common.offset += flush;
4163 if (demux->streaming) {
4166 /* hard to skip large blocks when streaming */
4167 ret = gst_matroska_demux_check_read_size (demux, flush);
4168 if (ret != GST_FLOW_OK)
4170 if (flush <= gst_adapter_available (demux->common.adapter))
4171 gst_adapter_flush (demux->common.adapter, flush);
4173 return GST_FLOW_EOS;
4178 /* initializes @ebml with @bytes from input stream at current offset.
4179 * Returns EOS if insufficient available,
4180 * ERROR if too much was attempted to read. */
4181 static inline GstFlowReturn
4182 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4185 GstBuffer *buffer = NULL;
4186 GstFlowReturn ret = GST_FLOW_OK;
4188 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4190 ret = gst_matroska_demux_check_read_size (demux, bytes);
4191 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4192 if (!demux->streaming) {
4193 /* in pull mode, we can skip */
4194 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4195 ret = GST_FLOW_OVERFLOW;
4197 /* otherwise fatal */
4198 ret = GST_FLOW_ERROR;
4202 if (demux->streaming) {
4203 if (gst_adapter_available (demux->common.adapter) >= bytes)
4204 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4208 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4209 demux->common.offset, bytes, &buffer, NULL);
4210 if (G_LIKELY (buffer)) {
4211 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4212 demux->common.offset);
4213 demux->common.offset += bytes;
4220 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4223 gboolean seekable = FALSE;
4224 gint64 start = -1, stop = -1;
4226 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4227 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4228 GST_DEBUG_OBJECT (demux, "seeking query failed");
4232 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4234 /* try harder to query upstream size if we didn't get it the first time */
4235 if (seekable && stop == -1) {
4236 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4237 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4241 /* if upstream doesn't know the size, it's likely that it's not seekable in
4242 * practice even if it technically may be seekable */
4243 if (seekable && (start != 0 || stop <= start)) {
4244 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4249 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4250 G_GUINT64_FORMAT ")", seekable, start, stop);
4251 demux->seekable = seekable;
4253 gst_query_unref (query);
4256 static GstFlowReturn
4257 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4263 GstFlowReturn ret = GST_FLOW_OK;
4265 GST_WARNING_OBJECT (demux,
4266 "Found Cluster element before Tracks, searching Tracks");
4269 before_pos = demux->common.offset;
4271 /* Search Tracks element */
4273 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4274 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4275 if (ret != GST_FLOW_OK)
4278 if (id != GST_MATROSKA_ID_TRACKS) {
4279 /* we may be skipping large cluster here, so forego size check etc */
4280 /* ... but we can't skip undefined size; force error */
4281 if (length == G_MAXUINT64) {
4282 ret = gst_matroska_demux_check_read_size (demux, length);
4285 demux->common.offset += needed;
4286 demux->common.offset += length;
4291 /* will lead to track parsing ... */
4292 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4297 demux->common.offset = before_pos;
4302 #define GST_READ_CHECK(stmt) \
4304 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4305 if (ret == GST_FLOW_OVERFLOW) { \
4306 ret = GST_FLOW_OK; \
4312 static GstFlowReturn
4313 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4314 guint64 length, guint needed)
4316 GstEbmlRead ebml = { 0, };
4317 GstFlowReturn ret = GST_FLOW_OK;
4320 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4321 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4323 /* if we plan to read and parse this element, we need prefix (id + length)
4324 * and the contents */
4325 /* mind about overflow wrap-around when dealing with undefined size */
4327 if (G_LIKELY (length != G_MAXUINT64))
4330 switch (demux->common.state) {
4331 case GST_MATROSKA_READ_STATE_START:
4333 case GST_EBML_ID_HEADER:
4334 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4335 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4336 if (ret != GST_FLOW_OK)
4338 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4339 gst_matroska_demux_check_seekability (demux);
4342 goto invalid_header;
4346 case GST_MATROSKA_READ_STATE_SEGMENT:
4348 case GST_MATROSKA_ID_SEGMENT:
4349 /* eat segment prefix */
4350 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4351 GST_DEBUG_OBJECT (demux,
4352 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4353 G_GUINT64_FORMAT, demux->common.offset, length);
4354 /* seeks are from the beginning of the segment,
4355 * after the segment ID/length */
4356 demux->common.ebml_segment_start = demux->common.offset;
4358 length = G_MAXUINT64;
4359 demux->common.ebml_segment_length = length;
4360 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4363 GST_WARNING_OBJECT (demux,
4364 "Expected a Segment ID (0x%x), but received 0x%x!",
4365 GST_MATROSKA_ID_SEGMENT, id);
4366 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4370 case GST_MATROSKA_READ_STATE_SCANNING:
4371 if (id != GST_MATROSKA_ID_CLUSTER &&
4372 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4375 case GST_MATROSKA_READ_STATE_HEADER:
4376 case GST_MATROSKA_READ_STATE_DATA:
4377 case GST_MATROSKA_READ_STATE_SEEK:
4379 case GST_MATROSKA_ID_SEGMENTINFO:
4380 if (!demux->common.segmentinfo_parsed) {
4381 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4382 ret = gst_matroska_read_common_parse_info (&demux->common,
4383 GST_ELEMENT_CAST (demux), &ebml);
4384 if (ret == GST_FLOW_OK)
4385 gst_matroska_demux_send_tags (demux);
4387 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4390 case GST_MATROSKA_ID_TRACKS:
4391 if (!demux->tracks_parsed) {
4392 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4393 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4395 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4398 case GST_MATROSKA_ID_CLUSTER:
4399 if (G_UNLIKELY (!demux->tracks_parsed)) {
4400 if (demux->streaming) {
4401 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4402 goto not_streamable;
4404 ret = gst_matroska_demux_find_tracks (demux);
4405 if (!demux->tracks_parsed)
4409 if (G_UNLIKELY (demux->common.state
4410 == GST_MATROSKA_READ_STATE_HEADER)) {
4411 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4412 demux->first_cluster_offset = demux->common.offset;
4413 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4414 gst_element_no_more_pads (GST_ELEMENT (demux));
4415 /* send initial segment - we wait till we know the first
4416 incoming timestamp, so we can properly set the start of
4418 demux->need_segment = TRUE;
4420 demux->cluster_time = GST_CLOCK_TIME_NONE;
4421 demux->cluster_offset = demux->common.offset;
4422 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4423 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4424 " not found in Cluster, trying next Cluster's first block instead",
4426 demux->seek_block = 0;
4428 demux->seek_first = FALSE;
4429 /* record next cluster for recovery */
4430 if (read != G_MAXUINT64)
4431 demux->next_cluster_offset = demux->cluster_offset + read;
4432 /* eat cluster prefix */
4433 gst_matroska_demux_flush (demux, needed);
4435 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4439 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4440 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4442 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4443 demux->cluster_time = num;
4445 if (demux->common.element_index) {
4446 if (demux->common.element_index_writer_id == -1)
4447 gst_index_get_writer_id (demux->common.element_index,
4448 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4449 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4450 G_GUINT64_FORMAT " for writer id %d",
4451 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4452 demux->common.element_index_writer_id);
4453 gst_index_add_association (demux->common.element_index,
4454 demux->common.element_index_writer_id,
4455 GST_ASSOCIATION_FLAG_KEY_UNIT,
4456 GST_FORMAT_TIME, demux->cluster_time,
4457 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4462 case GST_MATROSKA_ID_BLOCKGROUP:
4463 if (!gst_matroska_demux_seek_block (demux))
4465 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4466 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4467 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4468 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4469 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4471 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4473 case GST_MATROSKA_ID_SIMPLEBLOCK:
4474 if (!gst_matroska_demux_seek_block (demux))
4476 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4477 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4478 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4479 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4480 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4482 case GST_MATROSKA_ID_ATTACHMENTS:
4483 if (!demux->common.attachments_parsed) {
4484 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4485 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4486 GST_ELEMENT_CAST (demux), &ebml);
4487 if (ret == GST_FLOW_OK)
4488 gst_matroska_demux_send_tags (demux);
4490 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4493 case GST_MATROSKA_ID_TAGS:
4494 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4495 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4496 GST_ELEMENT_CAST (demux), &ebml);
4497 if (ret == GST_FLOW_OK)
4498 gst_matroska_demux_send_tags (demux);
4500 case GST_MATROSKA_ID_CHAPTERS:
4501 if (!demux->common.chapters_parsed) {
4502 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4504 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4506 if (demux->common.toc) {
4507 gst_matroska_demux_send_event (demux,
4508 gst_event_new_toc (demux->common.toc, FALSE));
4511 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4513 case GST_MATROSKA_ID_SEEKHEAD:
4514 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4515 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4517 case GST_MATROSKA_ID_CUES:
4518 if (demux->common.index_parsed) {
4519 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4522 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4523 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4524 /* only push based; delayed index building */
4525 if (ret == GST_FLOW_OK
4526 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4529 GST_OBJECT_LOCK (demux);
4530 event = demux->seek_event;
4531 demux->seek_event = NULL;
4532 GST_OBJECT_UNLOCK (demux);
4535 /* unlikely to fail, since we managed to seek to this point */
4536 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
4537 gst_event_unref (event);
4540 gst_event_unref (event);
4541 /* resume data handling, main thread clear to seek again */
4542 GST_OBJECT_LOCK (demux);
4543 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4544 GST_OBJECT_UNLOCK (demux);
4547 case GST_MATROSKA_ID_POSITION:
4548 case GST_MATROSKA_ID_PREVSIZE:
4549 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4550 case GST_MATROSKA_ID_SILENTTRACKS:
4551 GST_DEBUG_OBJECT (demux,
4552 "Skipping Cluster subelement 0x%x - ignoring", id);
4556 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4557 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4563 if (ret == GST_FLOW_PARSE)
4567 gst_ebml_read_clear (&ebml);
4573 /* simply exit, maybe not enough data yet */
4574 /* no ebml to clear if read error */
4579 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4580 ("Failed to parse Element 0x%x", id));
4581 ret = GST_FLOW_ERROR;
4586 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4587 ("File layout does not permit streaming"));
4588 ret = GST_FLOW_ERROR;
4593 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4594 ("No Tracks element found"));
4595 ret = GST_FLOW_ERROR;
4600 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4601 ret = GST_FLOW_ERROR;
4606 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4607 ret = GST_FLOW_ERROR;
4613 gst_matroska_demux_loop (GstPad * pad)
4615 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4621 /* If we have to close a segment, send a new segment to do this now */
4622 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4623 if (G_UNLIKELY (demux->new_segment)) {
4624 gst_matroska_demux_send_event (demux, demux->new_segment);
4625 demux->new_segment = NULL;
4629 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4630 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4631 if (ret == GST_FLOW_EOS) {
4633 } else if (ret == GST_FLOW_FLUSHING) {
4635 } else if (ret != GST_FLOW_OK) {
4636 ret = gst_matroska_demux_check_parse_error (demux);
4638 /* Only handle EOS as no error if we're outside the segment already */
4639 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4640 && demux->common.offset >=
4641 demux->common.ebml_segment_start +
4642 demux->common.ebml_segment_length))
4644 else if (ret != GST_FLOW_OK)
4650 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4651 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4654 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4655 if (ret == GST_FLOW_EOS)
4657 if (ret != GST_FLOW_OK)
4660 /* check if we're at the end of a configured segment */
4661 if (G_LIKELY (demux->common.src->len)) {
4664 g_assert (demux->common.num_streams == demux->common.src->len);
4665 for (i = 0; i < demux->common.src->len; i++) {
4666 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4668 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4669 GST_TIME_ARGS (context->pos));
4670 if (context->eos == FALSE)
4674 GST_INFO_OBJECT (demux, "All streams are EOS");
4680 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4681 demux->common.offset >= demux->cached_length)) {
4682 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4683 if (demux->common.offset == demux->cached_length) {
4684 GST_LOG_OBJECT (demux, "Reached end of stream");
4695 if (demux->common.segment.rate < 0.0) {
4696 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4697 if (ret == GST_FLOW_OK)
4704 const gchar *reason = gst_flow_get_name (ret);
4705 gboolean push_eos = FALSE;
4707 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4708 gst_pad_pause_task (demux->common.sinkpad);
4710 if (ret == GST_FLOW_EOS) {
4711 /* perform EOS logic */
4713 /* If we were in the headers, make sure we send no-more-pads.
4714 This will ensure decodebin does not get stuck thinking
4715 the chain is not complete yet, and waiting indefinitely. */
4716 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4717 if (demux->common.src->len == 0) {
4718 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4719 ("No pads created"));
4721 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4722 ("Failed to finish reading headers"));
4724 gst_element_no_more_pads (GST_ELEMENT (demux));
4727 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4730 /* for segment playback we need to post when (in stream time)
4731 * we stopped, this is either stop (when set) or the duration. */
4732 if ((stop = demux->common.segment.stop) == -1)
4733 stop = demux->last_stop_end;
4735 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4736 gst_element_post_message (GST_ELEMENT (demux),
4737 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4739 gst_matroska_demux_send_event (demux,
4740 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4744 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4745 /* for fatal errors we post an error message */
4746 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4747 ("stream stopped, reason %s", reason));
4751 /* send EOS, and prevent hanging if no streams yet */
4752 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4753 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4754 (ret == GST_FLOW_EOS)) {
4755 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4756 (NULL), ("got eos but no streams (yet)"));
4764 * Create and push a flushing seek event upstream
4767 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4773 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4776 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4777 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4778 GST_SEEK_TYPE_NONE, -1);
4779 gst_event_set_seqnum (event, seqnum);
4781 res = gst_pad_push_event (demux->common.sinkpad, event);
4783 /* segment event will update offset */
4787 static GstFlowReturn
4788 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4790 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4792 GstFlowReturn ret = GST_FLOW_OK;
4797 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4798 GST_DEBUG_OBJECT (demux, "got DISCONT");
4799 gst_adapter_clear (demux->common.adapter);
4800 GST_OBJECT_LOCK (demux);
4801 gst_matroska_read_common_reset_streams (&demux->common,
4802 GST_CLOCK_TIME_NONE, FALSE);
4803 GST_OBJECT_UNLOCK (demux);
4806 gst_adapter_push (demux->common.adapter, buffer);
4810 available = gst_adapter_available (demux->common.adapter);
4812 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4813 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4814 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4815 if (demux->common.ebml_segment_length != G_MAXUINT64
4816 && demux->common.offset >=
4817 demux->common.ebml_segment_start + demux->common.ebml_segment_length)
4822 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4823 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4824 demux->common.offset, id, length, needed, available);
4826 if (needed > available)
4829 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4830 if (ret == GST_FLOW_EOS) {
4831 /* need more data */
4833 } else if (ret != GST_FLOW_OK) {
4840 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4843 gboolean res = TRUE;
4844 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4846 GST_DEBUG_OBJECT (demux,
4847 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4849 switch (GST_EVENT_TYPE (event)) {
4850 case GST_EVENT_SEGMENT:
4852 const GstSegment *segment;
4854 /* some debug output */
4855 gst_event_parse_segment (event, &segment);
4856 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4857 GST_DEBUG_OBJECT (demux,
4858 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4861 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4862 GST_DEBUG_OBJECT (demux, "still starting");
4866 /* we only expect a BYTE segment, e.g. following a seek */
4867 if (segment->format != GST_FORMAT_BYTES) {
4868 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4872 GST_DEBUG_OBJECT (demux, "clearing segment state");
4873 GST_OBJECT_LOCK (demux);
4874 /* clear current segment leftover */
4875 gst_adapter_clear (demux->common.adapter);
4876 /* and some streaming setup */
4877 demux->common.offset = segment->start;
4878 /* accumulate base based on current position */
4879 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4880 demux->common.segment.base +=
4881 (MAX (demux->common.segment.position, demux->stream_start_time)
4882 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4883 /* do not know where we are;
4884 * need to come across a cluster and generate segment */
4885 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4886 demux->cluster_time = GST_CLOCK_TIME_NONE;
4887 demux->cluster_offset = 0;
4888 demux->need_segment = TRUE;
4889 demux->segment_seqnum = gst_event_get_seqnum (event);
4890 /* but keep some of the upstream segment */
4891 demux->common.segment.rate = segment->rate;
4892 /* also check if need to keep some of the requested seek position */
4893 if (demux->seek_offset == segment->start) {
4894 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4895 demux->common.segment.position = demux->requested_seek_time;
4897 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4899 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4900 demux->seek_offset = -1;
4901 GST_OBJECT_UNLOCK (demux);
4903 /* chain will send initial segment after pads have been added,
4904 * or otherwise come up with one */
4905 GST_DEBUG_OBJECT (demux, "eating event");
4906 gst_event_unref (event);
4912 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4913 gst_event_unref (event);
4914 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4915 (NULL), ("got eos and didn't receive a complete header object"));
4916 } else if (demux->common.num_streams == 0) {
4917 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4918 (NULL), ("got eos but no streams (yet)"));
4920 gst_matroska_demux_send_event (demux, event);
4924 case GST_EVENT_FLUSH_STOP:
4928 gst_adapter_clear (demux->common.adapter);
4929 GST_OBJECT_LOCK (demux);
4930 gst_matroska_read_common_reset_streams (&demux->common,
4931 GST_CLOCK_TIME_NONE, TRUE);
4932 gst_flow_combiner_reset (demux->flowcombiner);
4933 dur = demux->common.segment.duration;
4934 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4935 demux->common.segment.duration = dur;
4936 demux->cluster_time = GST_CLOCK_TIME_NONE;
4937 demux->cluster_offset = 0;
4938 GST_OBJECT_UNLOCK (demux);
4942 res = gst_pad_event_default (pad, parent, event);
4950 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4952 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4954 gboolean pull_mode = FALSE;
4956 query = gst_query_new_scheduling ();
4958 if (gst_pad_peer_query (sinkpad, query))
4959 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4960 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4962 gst_query_unref (query);
4965 GST_DEBUG ("going to pull mode");
4966 demux->streaming = FALSE;
4967 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4969 GST_DEBUG ("going to push (streaming) mode");
4970 demux->streaming = TRUE;
4971 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4976 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4977 GstPadMode mode, gboolean active)
4980 case GST_PAD_MODE_PULL:
4982 /* if we have a scheduler we can start the task */
4983 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4986 gst_pad_stop_task (sinkpad);
4989 case GST_PAD_MODE_PUSH:
4997 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4998 videocontext, const gchar * codec_id, guint8 * data, guint size,
4999 gchar ** codec_name, guint32 * riff_fourcc)
5001 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
5002 GstCaps *caps = NULL;
5004 g_assert (videocontext != NULL);
5005 g_assert (codec_name != NULL);
5010 /* TODO: check if we have all codec types from matroska-ids.h
5011 * check if we have to do more special things with codec_private
5014 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
5015 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
5018 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
5019 gst_riff_strf_vids *vids = NULL;
5022 GstBuffer *buf = NULL;
5024 vids = (gst_riff_strf_vids *) data;
5026 /* assure size is big enough */
5028 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
5031 if (size < sizeof (gst_riff_strf_vids)) {
5032 vids = g_new (gst_riff_strf_vids, 1);
5033 memcpy (vids, data, size);
5036 context->dts_only = TRUE; /* VFW files only store DTS */
5038 /* little-endian -> byte-order */
5039 vids->size = GUINT32_FROM_LE (vids->size);
5040 vids->width = GUINT32_FROM_LE (vids->width);
5041 vids->height = GUINT32_FROM_LE (vids->height);
5042 vids->planes = GUINT16_FROM_LE (vids->planes);
5043 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
5044 vids->compression = GUINT32_FROM_LE (vids->compression);
5045 vids->image_size = GUINT32_FROM_LE (vids->image_size);
5046 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
5047 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
5048 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
5049 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
5051 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
5052 gsize offset = sizeof (gst_riff_strf_vids);
5055 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
5056 size - offset), size - offset);
5060 *riff_fourcc = vids->compression;
5062 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
5063 buf, NULL, codec_name);
5066 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
5067 GST_FOURCC_ARGS (vids->compression));
5069 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
5070 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
5071 "video/x-compressed-yuv");
5072 context->intra_only =
5073 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
5077 gst_buffer_unref (buf);
5079 if (vids != (gst_riff_strf_vids *) data)
5082 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
5084 GstVideoFormat format;
5086 gst_video_info_init (&info);
5087 switch (videocontext->fourcc) {
5088 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5089 format = GST_VIDEO_FORMAT_I420;
5091 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5092 format = GST_VIDEO_FORMAT_YUY2;
5094 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5095 format = GST_VIDEO_FORMAT_YV12;
5097 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5098 format = GST_VIDEO_FORMAT_UYVY;
5100 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5101 format = GST_VIDEO_FORMAT_AYUV;
5103 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
5104 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
5105 format = GST_VIDEO_FORMAT_GRAY8;
5107 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
5108 format = GST_VIDEO_FORMAT_RGB;
5110 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
5111 format = GST_VIDEO_FORMAT_BGR;
5114 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5115 GST_FOURCC_ARGS (videocontext->fourcc));
5119 context->intra_only = TRUE;
5121 gst_video_info_set_format (&info, format, videocontext->pixel_width,
5122 videocontext->pixel_height);
5123 caps = gst_video_info_to_caps (&info);
5124 *codec_name = gst_pb_utils_get_codec_description (caps);
5125 context->alignment = 32;
5126 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5127 caps = gst_caps_new_simple ("video/x-divx",
5128 "divxversion", G_TYPE_INT, 4, NULL);
5129 *codec_name = g_strdup ("MPEG-4 simple profile");
5130 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5131 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5132 caps = gst_caps_new_simple ("video/mpeg",
5133 "mpegversion", G_TYPE_INT, 4,
5134 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5138 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5139 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5140 gst_buffer_unref (priv);
5142 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
5144 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5145 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5147 *codec_name = g_strdup ("MPEG-4 advanced profile");
5148 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5150 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5151 "divxversion", G_TYPE_INT, 3, NULL),
5152 gst_structure_new ("video/x-msmpeg",
5153 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5155 caps = gst_caps_new_simple ("video/x-msmpeg",
5156 "msmpegversion", G_TYPE_INT, 43, NULL);
5157 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5158 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5159 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5162 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5167 caps = gst_caps_new_simple ("video/mpeg",
5168 "systemstream", G_TYPE_BOOLEAN, FALSE,
5169 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5170 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5171 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5172 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5173 caps = gst_caps_new_empty_simple ("image/jpeg");
5174 *codec_name = g_strdup ("Motion-JPEG");
5175 context->intra_only = TRUE;
5176 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5177 caps = gst_caps_new_empty_simple ("video/x-h264");
5181 /* First byte is the version, second is the profile indication, and third
5182 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5183 * level indication. */
5184 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5187 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5188 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5189 gst_buffer_unref (priv);
5191 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5192 "alignment", G_TYPE_STRING, "au", NULL);
5194 GST_WARNING ("No codec data found, assuming output is byte-stream");
5195 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5198 *codec_name = g_strdup ("H264");
5199 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
5200 caps = gst_caps_new_empty_simple ("video/x-h265");
5204 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
5207 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5208 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5209 gst_buffer_unref (priv);
5211 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
5212 "alignment", G_TYPE_STRING, "au", NULL);
5214 GST_WARNING ("No codec data found, assuming output is byte-stream");
5215 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5218 *codec_name = g_strdup ("HEVC");
5219 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5220 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5221 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5222 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5223 gint rmversion = -1;
5225 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5227 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5229 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5231 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5234 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5235 "rmversion", G_TYPE_INT, rmversion, NULL);
5236 GST_DEBUG ("data:%p, size:0x%x", data, size);
5237 /* We need to extract the extradata ! */
5238 if (data && (size >= 0x22)) {
5243 subformat = GST_READ_UINT32_BE (data + 0x1a);
5244 rformat = GST_READ_UINT32_BE (data + 0x1e);
5247 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5249 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5250 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5251 gst_buffer_unref (priv);
5254 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5255 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5256 caps = gst_caps_new_empty_simple ("video/x-theora");
5257 context->stream_headers =
5258 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5259 context->codec_priv_size);
5260 /* FIXME: mark stream as broken and skip if there are no stream headers */
5261 context->send_stream_headers = TRUE;
5262 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5263 caps = gst_caps_new_empty_simple ("video/x-dirac");
5264 *codec_name = g_strdup_printf ("Dirac");
5265 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5266 caps = gst_caps_new_empty_simple ("video/x-vp8");
5267 *codec_name = g_strdup_printf ("On2 VP8");
5268 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5269 caps = gst_caps_new_empty_simple ("video/x-vp9");
5270 *codec_name = g_strdup_printf ("On2 VP9");
5271 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
5273 const gchar *variant, *variant_descr = "";
5275 /* Expect a fourcc in the codec private data */
5276 if (!data || size < 4) {
5277 GST_WARNING ("No or too small PRORESS fourcc (%d bytes)", size);
5281 fourcc = GST_STR_FOURCC (data);
5283 case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
5284 variant_descr = " 4:2:2 LT";
5287 case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
5289 variant_descr = " 4:2:2 HQ";
5291 case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
5293 variant_descr = " 4:4:4:4";
5295 case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
5297 variant_descr = " 4:2:2 Proxy";
5299 case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
5301 variant = "standard";
5302 variant_descr = " 4:2:2 SD";
5306 GST_LOG ("Prores video, codec fourcc %" GST_FOURCC_FORMAT,
5307 GST_FOURCC_ARGS (fourcc));
5309 caps = gst_caps_new_simple ("video/x-prores",
5310 "format", G_TYPE_STRING, variant, NULL);
5311 *codec_name = g_strdup_printf ("Apple ProRes%s", variant_descr);
5312 context->postprocess_frame = gst_matroska_demux_add_prores_header;
5314 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5320 GstStructure *structure;
5322 for (i = 0; i < gst_caps_get_size (caps); i++) {
5323 structure = gst_caps_get_structure (caps, i);
5325 /* FIXME: use the real unit here! */
5326 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5327 videocontext->pixel_width,
5328 videocontext->pixel_height,
5329 videocontext->display_width, videocontext->display_height);
5331 /* pixel width and height are the w and h of the video in pixels */
5332 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5333 gint w = videocontext->pixel_width;
5334 gint h = videocontext->pixel_height;
5336 gst_structure_set (structure,
5337 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5340 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5343 if (videocontext->display_width <= 0)
5344 videocontext->display_width = videocontext->pixel_width;
5345 if (videocontext->display_height <= 0)
5346 videocontext->display_height = videocontext->pixel_height;
5348 /* calculate the pixel aspect ratio using the display and pixel w/h */
5349 n = videocontext->display_width * videocontext->pixel_height;
5350 d = videocontext->display_height * videocontext->pixel_width;
5351 GST_DEBUG ("setting PAR to %d/%d", n, d);
5352 gst_structure_set (structure, "pixel-aspect-ratio",
5354 videocontext->display_width * videocontext->pixel_height,
5355 videocontext->display_height * videocontext->pixel_width, NULL);
5358 if (videocontext->default_fps > 0.0) {
5361 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5363 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5365 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5367 } else if (context->default_duration > 0) {
5370 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5372 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5373 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5375 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5376 fps_n, fps_d, NULL);
5378 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5382 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5383 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5386 if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
5387 if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
5388 videocontext->pixel_width, videocontext->pixel_height,
5389 videocontext->display_width * videocontext->pixel_height,
5390 videocontext->display_height * videocontext->pixel_width)) {
5391 videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
5393 gst_caps_set_simple (caps,
5394 "multiview-mode", G_TYPE_STRING,
5395 gst_video_multiview_mode_to_caps_string
5396 (videocontext->multiview_mode), "multiview-flags",
5397 GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
5398 GST_FLAG_SET_MASK_EXACT, NULL);
5401 caps = gst_caps_simplify (caps);
5408 * Some AAC specific code... *sigh*
5409 * FIXME: maybe we should use '15' and code the sample rate explicitly
5410 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5414 aac_rate_idx (gint rate)
5418 else if (75132 <= rate)
5420 else if (55426 <= rate)
5422 else if (46009 <= rate)
5424 else if (37566 <= rate)
5426 else if (27713 <= rate)
5428 else if (23004 <= rate)
5430 else if (18783 <= rate)
5432 else if (13856 <= rate)
5434 else if (11502 <= rate)
5436 else if (9391 <= rate)
5443 aac_profile_idx (const gchar * codec_id)
5447 if (strlen (codec_id) <= 12)
5449 else if (!strncmp (&codec_id[12], "MAIN", 4))
5451 else if (!strncmp (&codec_id[12], "LC", 2))
5453 else if (!strncmp (&codec_id[12], "SSR", 3))
5462 round_up_pow2 (guint n)
5473 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5476 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5477 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5478 gchar ** codec_name, guint16 * riff_audio_fmt)
5480 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5481 GstCaps *caps = NULL;
5483 g_assert (audiocontext != NULL);
5484 g_assert (codec_name != NULL);
5487 *riff_audio_fmt = 0;
5489 /* TODO: check if we have all codec types from matroska-ids.h
5490 * check if we have to do more special things with codec_private
5491 * check if we need bitdepth in different places too
5492 * implement channel position magic
5494 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5495 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5496 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5497 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5500 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5501 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5502 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5505 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5507 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5512 caps = gst_caps_new_simple ("audio/mpeg",
5513 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5514 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5515 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5516 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5519 GstAudioFormat format;
5521 sign = (audiocontext->bitdepth != 8);
5522 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5523 endianness = G_BIG_ENDIAN;
5525 endianness = G_LITTLE_ENDIAN;
5527 format = gst_audio_format_build_integer (sign, endianness,
5528 audiocontext->bitdepth, audiocontext->bitdepth);
5530 /* FIXME: Channel mask and reordering */
5531 caps = gst_caps_new_simple ("audio/x-raw",
5532 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5533 "layout", G_TYPE_STRING, "interleaved",
5534 "channel-mask", GST_TYPE_BITMASK,
5535 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5537 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5538 audiocontext->bitdepth);
5539 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5540 context->alignment = round_up_pow2 (context->alignment);
5541 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5542 const gchar *format;
5543 if (audiocontext->bitdepth == 32)
5547 /* FIXME: Channel mask and reordering */
5548 caps = gst_caps_new_simple ("audio/x-raw",
5549 "format", G_TYPE_STRING, format,
5550 "layout", G_TYPE_STRING, "interleaved",
5551 "channel-mask", GST_TYPE_BITMASK,
5552 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5553 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5554 audiocontext->bitdepth);
5555 context->alignment = audiocontext->bitdepth / 8;
5556 context->alignment = round_up_pow2 (context->alignment);
5557 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5558 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5559 caps = gst_caps_new_simple ("audio/x-ac3",
5560 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5561 *codec_name = g_strdup ("AC-3 audio");
5562 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5563 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5564 caps = gst_caps_new_simple ("audio/x-eac3",
5565 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5566 *codec_name = g_strdup ("E-AC-3 audio");
5567 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5568 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5569 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5570 *codec_name = g_strdup ("Dolby TrueHD");
5571 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5572 caps = gst_caps_new_empty_simple ("audio/x-dts");
5573 *codec_name = g_strdup ("DTS audio");
5574 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5575 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5576 context->stream_headers =
5577 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5578 context->codec_priv_size);
5579 /* FIXME: mark stream as broken and skip if there are no stream headers */
5580 context->send_stream_headers = TRUE;
5581 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5582 caps = gst_caps_new_empty_simple ("audio/x-flac");
5583 context->stream_headers =
5584 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5585 context->codec_priv_size);
5586 /* FIXME: mark stream as broken and skip if there are no stream headers */
5587 context->send_stream_headers = TRUE;
5588 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5589 caps = gst_caps_new_empty_simple ("audio/x-speex");
5590 context->stream_headers =
5591 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5592 context->codec_priv_size);
5593 /* FIXME: mark stream as broken and skip if there are no stream headers */
5594 context->send_stream_headers = TRUE;
5595 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5598 if (context->codec_priv_size >= 19) {
5599 if (audiocontext->samplerate)
5600 GST_WRITE_UINT32_LE ((guint8 *) context->codec_priv + 12,
5601 audiocontext->samplerate);
5602 if (context->codec_delay) {
5604 gst_util_uint64_scale_round (context->codec_delay, 48000,
5606 GST_WRITE_UINT16_LE ((guint8 *) context->codec_priv + 10, delay);
5610 gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5611 context->codec_priv_size), context->codec_priv_size);
5612 caps = gst_codec_utils_opus_create_caps_from_header (tmp, NULL);
5613 gst_buffer_unref (tmp);
5614 *codec_name = g_strdup ("Opus");
5616 GST_WARNING ("Invalid Opus codec data size");
5618 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5619 gst_riff_strf_auds auds;
5621 if (data && size >= 18) {
5622 GstBuffer *codec_data = NULL;
5624 /* little-endian -> byte-order */
5625 auds.format = GST_READ_UINT16_LE (data);
5626 auds.channels = GST_READ_UINT16_LE (data + 2);
5627 auds.rate = GST_READ_UINT32_LE (data + 4);
5628 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5629 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5630 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5632 /* 18 is the waveformatex size */
5634 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5635 data + 18, size - 18, 0, size - 18, NULL, NULL);
5639 *riff_audio_fmt = auds.format;
5641 /* FIXME: Handle reorder map */
5642 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5643 codec_data, codec_name, NULL);
5645 gst_buffer_unref (codec_data);
5648 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5651 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5653 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5654 GstBuffer *priv = NULL;
5656 gint rate_idx, profile;
5657 guint8 *data = NULL;
5659 /* unspecified AAC profile with opaque private codec data */
5660 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5661 if (context->codec_priv_size >= 2) {
5662 guint obj_type, freq_index, explicit_freq_bytes = 0;
5664 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5666 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5667 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5668 if (freq_index == 15)
5669 explicit_freq_bytes = 3;
5670 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5671 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5672 context->codec_priv_size), context->codec_priv_size);
5673 /* assume SBR if samplerate <= 24kHz */
5674 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5675 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5676 audiocontext->samplerate *= 2;
5679 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5680 /* this is pretty broken;
5681 * maybe we need to make up some default private,
5682 * or maybe ADTS data got dumped in.
5683 * Let's set up some private data now, and check actual data later */
5684 /* just try this and see what happens ... */
5685 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5686 context->postprocess_frame = gst_matroska_demux_check_aac;
5690 /* make up decoder-specific data if it is not supplied */
5694 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5695 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5697 rate_idx = aac_rate_idx (audiocontext->samplerate);
5698 profile = aac_profile_idx (codec_id);
5700 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5701 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5703 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5704 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5706 gst_buffer_unmap (priv, &map);
5707 gst_buffer_set_size (priv, 2);
5708 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5709 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5712 if (g_strrstr (codec_id, "SBR")) {
5713 /* HE-AAC (aka SBR AAC) */
5714 audiocontext->samplerate *= 2;
5715 rate_idx = aac_rate_idx (audiocontext->samplerate);
5716 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5717 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5718 data[4] = (1 << 7) | (rate_idx << 3);
5719 gst_buffer_unmap (priv, &map);
5721 gst_buffer_unmap (priv, &map);
5722 gst_buffer_set_size (priv, 2);
5725 gst_buffer_unmap (priv, &map);
5726 gst_buffer_unref (priv);
5728 GST_ERROR ("Unknown AAC profile and no codec private data");
5733 caps = gst_caps_new_simple ("audio/mpeg",
5734 "mpegversion", G_TYPE_INT, mpegversion,
5735 "framed", G_TYPE_BOOLEAN, TRUE,
5736 "stream-format", G_TYPE_STRING, "raw", NULL);
5737 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5738 if (context->codec_priv && context->codec_priv_size > 0)
5739 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5740 context->codec_priv, context->codec_priv_size);
5741 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5742 gst_buffer_unref (priv);
5744 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5745 caps = gst_caps_new_simple ("audio/x-tta",
5746 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5747 *codec_name = g_strdup ("TTA audio");
5748 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5749 caps = gst_caps_new_simple ("audio/x-wavpack",
5750 "width", G_TYPE_INT, audiocontext->bitdepth,
5751 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5752 *codec_name = g_strdup ("Wavpack audio");
5753 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5754 audiocontext->wvpk_block_index = 0;
5755 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5756 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5757 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5758 gint raversion = -1;
5760 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5762 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5767 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5768 "raversion", G_TYPE_INT, raversion, NULL);
5769 /* Extract extra information from caps, mapping varies based on codec */
5770 if (data && (size >= 0x50)) {
5777 guint extra_data_size;
5779 GST_ERROR ("real audio raversion:%d", raversion);
5780 if (raversion == 8) {
5782 flavor = GST_READ_UINT16_BE (data + 22);
5783 packet_size = GST_READ_UINT32_BE (data + 24);
5784 height = GST_READ_UINT16_BE (data + 40);
5785 leaf_size = GST_READ_UINT16_BE (data + 44);
5786 sample_width = GST_READ_UINT16_BE (data + 58);
5787 extra_data_size = GST_READ_UINT32_BE (data + 74);
5790 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5791 flavor, packet_size, height, leaf_size, sample_width,
5793 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5794 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5795 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5797 if ((size - 78) >= extra_data_size) {
5798 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5800 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5801 gst_buffer_unref (priv);
5806 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5807 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5808 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5809 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5810 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5811 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5812 *codec_name = g_strdup ("Real Audio Lossless");
5813 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5814 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5815 *codec_name = g_strdup ("Sony ATRAC3");
5817 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5822 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5825 for (i = 0; i < gst_caps_get_size (caps); i++) {
5826 gst_structure_set (gst_caps_get_structure (caps, i),
5827 "channels", G_TYPE_INT, audiocontext->channels,
5828 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5832 caps = gst_caps_simplify (caps);
5839 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5840 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5842 GstCaps *caps = NULL;
5843 GstMatroskaTrackContext *context =
5844 (GstMatroskaTrackContext *) subtitlecontext;
5846 /* for backwards compatibility */
5847 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5848 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5849 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5850 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5851 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5852 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5853 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5854 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5856 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5857 * Check if we have to do something with codec_private */
5858 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5859 /* well, plain text simply does not have a lot of markup ... */
5860 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5861 "pango-markup", NULL);
5862 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5863 subtitlecontext->check_markup = TRUE;
5864 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5865 caps = gst_caps_new_empty_simple ("application/x-ssa");
5866 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5867 subtitlecontext->check_markup = FALSE;
5868 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5869 caps = gst_caps_new_empty_simple ("application/x-ass");
5870 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5871 subtitlecontext->check_markup = FALSE;
5872 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5873 caps = gst_caps_new_empty_simple ("application/x-usf");
5874 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5875 subtitlecontext->check_markup = FALSE;
5876 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5877 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5878 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5879 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5880 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5881 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5882 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5883 context->stream_headers =
5884 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5885 context->codec_priv_size);
5886 /* FIXME: mark stream as broken and skip if there are no stream headers */
5887 context->send_stream_headers = TRUE;
5889 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5890 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5893 if (data != NULL && size > 0) {
5896 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5897 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5898 gst_buffer_unref (buf);
5906 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5908 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5910 GST_OBJECT_LOCK (demux);
5911 if (demux->common.element_index)
5912 gst_object_unref (demux->common.element_index);
5913 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5914 GST_OBJECT_UNLOCK (demux);
5915 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5916 demux->common.element_index);
5920 gst_matroska_demux_get_index (GstElement * element)
5922 GstIndex *result = NULL;
5923 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5925 GST_OBJECT_LOCK (demux);
5926 if (demux->common.element_index)
5927 result = gst_object_ref (demux->common.element_index);
5928 GST_OBJECT_UNLOCK (demux);
5930 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5936 static GstStateChangeReturn
5937 gst_matroska_demux_change_state (GstElement * element,
5938 GstStateChange transition)
5940 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5941 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5943 /* handle upwards state changes here */
5944 switch (transition) {
5949 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5951 /* handle downwards state changes */
5952 switch (transition) {
5953 case GST_STATE_CHANGE_PAUSED_TO_READY:
5954 gst_matroska_demux_reset (GST_ELEMENT (demux));
5964 gst_matroska_demux_set_property (GObject * object,
5965 guint prop_id, const GValue * value, GParamSpec * pspec)
5967 GstMatroskaDemux *demux;
5969 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5970 demux = GST_MATROSKA_DEMUX (object);
5973 case PROP_MAX_GAP_TIME:
5974 GST_OBJECT_LOCK (demux);
5975 demux->max_gap_time = g_value_get_uint64 (value);
5976 GST_OBJECT_UNLOCK (demux);
5979 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5985 gst_matroska_demux_get_property (GObject * object,
5986 guint prop_id, GValue * value, GParamSpec * pspec)
5988 GstMatroskaDemux *demux;
5990 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5991 demux = GST_MATROSKA_DEMUX (object);
5994 case PROP_MAX_GAP_TIME:
5995 GST_OBJECT_LOCK (demux);
5996 g_value_set_uint64 (value, demux->max_gap_time);
5997 GST_OBJECT_UNLOCK (demux);
6000 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6006 gst_matroska_demux_plugin_init (GstPlugin * plugin)
6010 /* parser helper separate debug */
6011 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
6012 0, "EBML stream helper class");
6014 /* create an elementfactory for the matroska_demux element */
6015 if (!gst_element_register (plugin, "matroskademux",
6016 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))