1 /* GStreamer Matroska muxer/demuxer
2 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3 * (c) 2006 Tim-Philipp Müller <tim centricular net>
4 * (c) 2008 Sebastian Dröge <slomo@circular-chaos.org>
5 * (c) 2011 Debarshi Ray <rishi@gnu.org>
7 * matroska-demux.c: matroska file/stream demuxer
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
25 /* TODO: check CRC32 if present
26 * TODO: there can be a segment after the first segment. Handle like
27 * chained oggs. Fixes #334082
28 * TODO: Test samples: http://www.matroska.org/samples/matrix/index.html
29 * http://samples.mplayerhq.hu/Matroska/
30 * TODO: check if demuxing is done correct for all codecs according to spec
31 * TODO: seeking with incomplete or without CUE
35 * SECTION:element-matroskademux
37 * matroskademux demuxes a Matroska file into the different contained streams.
40 * <title>Example launch line</title>
42 * gst-launch-1.0 -v filesrc location=/path/to/mkv ! matroskademux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
43 * ]| This pipeline demuxes a Matroska file and outputs the contained Vorbis audio.
54 #include <glib/gprintf.h>
56 /* For AVI compatibility mode
57 and for fourcc stuff */
58 #include <gst/riff/riff-read.h>
59 #include <gst/riff/riff-ids.h>
60 #include <gst/riff/riff-media.h>
62 #include <gst/audio/audio.h>
63 #include <gst/tag/tag.h>
64 #include <gst/pbutils/pbutils.h>
65 #include <gst/video/video.h>
67 #include "matroska-demux.h"
68 #include "matroska-ids.h"
70 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
71 #define GST_CAT_DEFAULT matroskademux_debug
73 #define DEBUG_ELEMENT_START(demux, ebml, element) \
74 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
75 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
77 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
78 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
79 " finished with '%s'", gst_flow_get_name (ret))
89 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
91 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
94 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
95 "video/x-matroska-3d; audio/webm; video/webm")
98 /* TODO: fill in caps! */
100 static GstStaticPadTemplate audio_src_templ =
101 GST_STATIC_PAD_TEMPLATE ("audio_%u",
104 GST_STATIC_CAPS ("ANY")
107 static GstStaticPadTemplate video_src_templ =
108 GST_STATIC_PAD_TEMPLATE ("video_%u",
111 GST_STATIC_CAPS ("ANY")
114 static GstStaticPadTemplate subtitle_src_templ =
115 GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
118 GST_STATIC_CAPS ("text/x-raw, format=pango-markup; application/x-ssa; "
119 "application/x-ass;application/x-usf; subpicture/x-dvd; "
120 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
123 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
124 guint32 id, guint64 length, guint needed);
126 /* element functions */
127 static void gst_matroska_demux_loop (GstPad * pad);
129 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
131 static gboolean gst_matroska_demux_element_query (GstElement * element,
135 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad,
137 static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
138 GstObject * parent, GstPadMode mode, gboolean active);
140 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
141 GstPad * pad, GstEvent * event);
142 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
143 GstObject * parent, GstEvent * event);
144 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
145 GstObject * parent, GstQuery * query);
147 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
148 GstObject * parent, GstEvent * event);
149 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
150 GstObject * object, GstBuffer * buffer);
152 static GstStateChangeReturn
153 gst_matroska_demux_change_state (GstElement * element,
154 GstStateChange transition);
157 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
158 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
162 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
163 * videocontext, const gchar * codec_id, guint8 * data, guint size,
164 gchar ** codec_name, guint32 * riff_fourcc);
165 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
166 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
167 gchar ** codec_name, guint16 * riff_audio_fmt);
169 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
170 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
173 static void gst_matroska_demux_reset (GstElement * element);
174 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
175 gdouble rate, guint64 offset, guint32 seqnum);
177 /* gobject functions */
178 static void gst_matroska_demux_set_property (GObject * object,
179 guint prop_id, const GValue * value, GParamSpec * pspec);
180 static void gst_matroska_demux_get_property (GObject * object,
181 guint prop_id, GValue * value, GParamSpec * pspec);
183 GType gst_matroska_demux_get_type (void);
184 #define parent_class gst_matroska_demux_parent_class
185 G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
188 gst_matroska_demux_finalize (GObject * object)
190 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
192 gst_matroska_read_common_finalize (&demux->common);
193 gst_flow_combiner_free (demux->flowcombiner);
194 G_OBJECT_CLASS (parent_class)->finalize (object);
198 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
200 GObjectClass *gobject_class = (GObjectClass *) klass;
201 GstElementClass *gstelement_class = (GstElementClass *) klass;
203 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
206 gobject_class->finalize = gst_matroska_demux_finalize;
208 gobject_class->get_property = gst_matroska_demux_get_property;
209 gobject_class->set_property = gst_matroska_demux_set_property;
211 g_object_class_install_property (gobject_class, PROP_MAX_GAP_TIME,
212 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
213 "The demuxer sends out segment events for skipping "
214 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
215 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
217 gstelement_class->change_state =
218 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
219 gstelement_class->send_event =
220 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
221 gstelement_class->query =
222 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
224 gstelement_class->set_index =
225 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
226 gstelement_class->get_index =
227 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
230 gst_element_class_add_pad_template (gstelement_class,
231 gst_static_pad_template_get (&video_src_templ));
232 gst_element_class_add_pad_template (gstelement_class,
233 gst_static_pad_template_get (&audio_src_templ));
234 gst_element_class_add_pad_template (gstelement_class,
235 gst_static_pad_template_get (&subtitle_src_templ));
236 gst_element_class_add_pad_template (gstelement_class,
237 gst_static_pad_template_get (&sink_templ));
239 gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
241 "Demuxes Matroska/WebM streams into video/audio/subtitles",
242 "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
246 gst_matroska_demux_init (GstMatroskaDemux * demux)
248 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
250 gst_pad_set_activate_function (demux->common.sinkpad,
251 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
252 gst_pad_set_activatemode_function (demux->common.sinkpad,
253 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
254 gst_pad_set_chain_function (demux->common.sinkpad,
255 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
256 gst_pad_set_event_function (demux->common.sinkpad,
257 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
258 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
260 /* init defaults for common read context */
261 gst_matroska_read_common_init (&demux->common);
263 /* property defaults */
264 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
266 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
268 demux->flowcombiner = gst_flow_combiner_new ();
271 gst_matroska_demux_reset (GST_ELEMENT (demux));
275 gst_matroska_demux_reset (GstElement * element)
277 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
279 GST_DEBUG_OBJECT (demux, "Resetting state");
281 gst_matroska_read_common_reset (GST_ELEMENT (demux), &demux->common);
283 demux->num_a_streams = 0;
284 demux->num_t_streams = 0;
285 demux->num_v_streams = 0;
287 demux->have_group_id = FALSE;
288 demux->group_id = G_MAXUINT;
291 demux->tracks_parsed = FALSE;
293 if (demux->clusters) {
294 g_array_free (demux->clusters, TRUE);
295 demux->clusters = NULL;
298 g_list_foreach (demux->seek_parsed,
299 (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
300 g_list_free (demux->seek_parsed);
301 demux->seek_parsed = NULL;
303 demux->last_stop_end = GST_CLOCK_TIME_NONE;
304 demux->seek_block = 0;
305 demux->stream_start_time = GST_CLOCK_TIME_NONE;
306 demux->to_time = GST_CLOCK_TIME_NONE;
307 demux->cluster_time = GST_CLOCK_TIME_NONE;
308 demux->cluster_offset = 0;
309 demux->next_cluster_offset = 0;
310 demux->index_offset = 0;
311 demux->seekable = FALSE;
312 demux->need_segment = FALSE;
313 demux->segment_seqnum = 0;
314 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
315 demux->seek_offset = -1;
316 demux->building_index = FALSE;
317 if (demux->seek_event) {
318 gst_event_unref (demux->seek_event);
319 demux->seek_event = NULL;
322 demux->seek_index = NULL;
323 demux->seek_entry = 0;
325 if (demux->new_segment) {
326 gst_event_unref (demux->new_segment);
327 demux->new_segment = NULL;
330 demux->invalid_duration = FALSE;
332 demux->cached_length = G_MAXUINT64;
334 gst_flow_combiner_clear (demux->flowcombiner);
338 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
344 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
346 GST_DEBUG ("decoding buffer %p", buf);
348 gst_buffer_map (buf, &map, GST_MAP_READ);
352 g_return_val_if_fail (size > 0, buf);
354 if (gst_matroska_decode_data (context->encodings, &data, &size,
355 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
356 gst_buffer_unmap (buf, &map);
357 gst_buffer_unref (buf);
358 return gst_buffer_new_wrapped (data, size);
360 GST_DEBUG ("decode data failed");
361 gst_buffer_unmap (buf, &map);
362 gst_buffer_unref (buf);
368 gst_matroska_demux_add_stream_headers_to_caps (GstMatroskaDemux * demux,
369 GstBufferList * list, GstCaps * caps)
372 GValue arr_val = G_VALUE_INIT;
373 GValue buf_val = G_VALUE_INIT;
376 g_assert (gst_caps_is_writable (caps));
378 g_value_init (&arr_val, GST_TYPE_ARRAY);
379 g_value_init (&buf_val, GST_TYPE_BUFFER);
381 num = gst_buffer_list_length (list);
382 for (i = 0; i < num; ++i) {
383 g_value_set_boxed (&buf_val, gst_buffer_list_get (list, i));
384 gst_value_array_append_value (&arr_val, &buf_val);
387 s = gst_caps_get_structure (caps, 0);
388 gst_structure_take_value (s, "streamheader", &arr_val);
389 g_value_unset (&buf_val);
393 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
395 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
396 GstMatroskaTrackContext *context;
397 GstPadTemplate *templ = NULL;
398 GstStreamFlags stream_flags;
399 GstCaps *caps = NULL;
400 GstTagList *cached_taglist;
401 gchar *padname = NULL;
403 guint32 id, riff_fourcc = 0;
404 guint16 riff_audio_fmt = 0;
405 GstEvent *stream_start;
409 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
411 /* start with the master */
412 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
413 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
417 /* allocate generic... if we know the type, we'll g_renew()
418 * with the precise type */
419 context = g_new0 (GstMatroskaTrackContext, 1);
420 g_ptr_array_add (demux->common.src, context);
421 context->index = demux->common.num_streams;
422 context->index_writer_id = -1;
423 context->type = 0; /* no type yet */
424 context->default_duration = 0;
426 context->set_discont = TRUE;
427 context->timecodescale = 1.0;
429 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
430 GST_MATROSKA_TRACK_LACING;
431 context->from_time = GST_CLOCK_TIME_NONE;
432 context->from_offset = -1;
433 context->to_offset = G_MAXINT64;
434 context->alignment = 1;
435 context->dts_only = FALSE;
436 context->intra_only = FALSE;
437 context->tags = gst_tag_list_new_empty ();
438 demux->common.num_streams++;
439 g_assert (demux->common.src->len == demux->common.num_streams);
441 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
443 /* try reading the trackentry headers */
444 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
445 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
449 /* track number (unique stream ID) */
450 case GST_MATROSKA_ID_TRACKNUMBER:{
453 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
457 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
458 ret = GST_FLOW_ERROR;
460 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
462 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
463 " is not unique", num);
464 ret = GST_FLOW_ERROR;
468 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
472 /* track UID (unique identifier) */
473 case GST_MATROSKA_ID_TRACKUID:{
476 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
480 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
481 ret = GST_FLOW_ERROR;
485 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
490 /* track type (video, audio, combined, subtitle, etc.) */
491 case GST_MATROSKA_ID_TRACKTYPE:{
494 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
498 if (context->type != 0 && context->type != track_type) {
499 GST_WARNING_OBJECT (demux,
500 "More than one tracktype defined in a TrackEntry - skipping");
502 } else if (track_type < 1 || track_type > 254) {
503 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
508 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
510 /* ok, so we're actually going to reallocate this thing */
511 switch (track_type) {
512 case GST_MATROSKA_TRACK_TYPE_VIDEO:
513 gst_matroska_track_init_video_context (&context);
515 case GST_MATROSKA_TRACK_TYPE_AUDIO:
516 gst_matroska_track_init_audio_context (&context);
518 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
519 gst_matroska_track_init_subtitle_context (&context);
521 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
522 case GST_MATROSKA_TRACK_TYPE_LOGO:
523 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
524 case GST_MATROSKA_TRACK_TYPE_CONTROL:
526 GST_WARNING_OBJECT (demux,
527 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
532 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
537 /* tracktype specific stuff for video */
538 case GST_MATROSKA_ID_TRACKVIDEO:{
539 GstMatroskaTrackVideoContext *videocontext;
541 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
543 if (!gst_matroska_track_init_video_context (&context)) {
544 GST_WARNING_OBJECT (demux,
545 "TrackVideo element in non-video track - ignoring track");
546 ret = GST_FLOW_ERROR;
548 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
551 videocontext = (GstMatroskaTrackVideoContext *) context;
552 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
555 while (ret == GST_FLOW_OK &&
556 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
557 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
561 /* Should be one level up but some broken muxers write it here. */
562 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
565 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
569 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
573 GST_DEBUG_OBJECT (demux,
574 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
575 context->default_duration = num;
579 /* video framerate */
580 /* NOTE: This one is here only for backward compatibility.
581 * Use _TRACKDEFAULDURATION one level up. */
582 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
585 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
589 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
593 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
594 if (context->default_duration == 0)
595 context->default_duration =
596 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
597 videocontext->default_fps = num;
601 /* width of the size to display the video at */
602 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
605 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
609 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
613 GST_DEBUG_OBJECT (demux,
614 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
615 videocontext->display_width = num;
619 /* height of the size to display the video at */
620 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
623 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
627 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
631 GST_DEBUG_OBJECT (demux,
632 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
633 videocontext->display_height = num;
637 /* width of the video in the file */
638 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
641 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
645 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
649 GST_DEBUG_OBJECT (demux,
650 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
651 videocontext->pixel_width = num;
655 /* height of the video in the file */
656 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
659 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
663 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
667 GST_DEBUG_OBJECT (demux,
668 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
669 videocontext->pixel_height = num;
673 /* whether the video is interlaced */
674 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
677 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
681 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
683 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
684 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
685 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
690 /* aspect ratio behaviour */
691 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
694 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
697 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
698 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
699 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
700 GST_WARNING_OBJECT (demux,
701 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
704 GST_DEBUG_OBJECT (demux,
705 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
706 videocontext->asr_mode = num;
710 /* colourspace (only matters for raw video) fourcc */
711 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
716 gst_ebml_read_binary (ebml, &id, &data,
717 &datalen)) != GST_FLOW_OK)
722 GST_WARNING_OBJECT (demux,
723 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
728 memcpy (&videocontext->fourcc, data, 4);
729 GST_DEBUG_OBJECT (demux,
730 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
731 GST_FOURCC_ARGS (videocontext->fourcc));
735 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
739 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
742 GST_DEBUG_OBJECT (demux, "StereoMode: %" G_GUINT64_FORMAT, num);
745 case GST_MATROSKA_STEREO_MODE_SBS_RL:
746 videocontext->multiview_flags =
747 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
749 case GST_MATROSKA_STEREO_MODE_SBS_LR:
750 videocontext->multiview_mode =
751 GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
753 case GST_MATROSKA_STEREO_MODE_TB_RL:
754 videocontext->multiview_flags =
755 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
757 case GST_MATROSKA_STEREO_MODE_TB_LR:
758 videocontext->multiview_mode =
759 GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM;
761 case GST_MATROSKA_STEREO_MODE_CHECKER_RL:
762 videocontext->multiview_flags =
763 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
765 case GST_MATROSKA_STEREO_MODE_CHECKER_LR:
766 videocontext->multiview_mode =
767 GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD;
769 case GST_MATROSKA_STEREO_MODE_FBF_RL:
770 videocontext->multiview_flags =
771 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
773 case GST_MATROSKA_STEREO_MODE_FBF_LR:
774 videocontext->multiview_mode =
775 GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
776 /* FIXME: In frame-by-frame mode, left/right frame buffers are
777 * laced within one block, and we'll need to apply FIRST_IN_BUNDLE
778 * accordingly. See http://www.matroska.org/technical/specs/index.html#StereoMode */
779 GST_FIXME_OBJECT (demux,
780 "Frame-by-frame stereoscopic mode not fully implemented");
787 GST_WARNING_OBJECT (demux,
788 "Unknown TrackVideo subelement 0x%x - ignoring", id);
790 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
791 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
792 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
793 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
794 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
795 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
796 ret = gst_ebml_read_skip (ebml);
801 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
805 /* tracktype specific stuff for audio */
806 case GST_MATROSKA_ID_TRACKAUDIO:{
807 GstMatroskaTrackAudioContext *audiocontext;
809 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
811 if (!gst_matroska_track_init_audio_context (&context)) {
812 GST_WARNING_OBJECT (demux,
813 "TrackAudio element in non-audio track - ignoring track");
814 ret = GST_FLOW_ERROR;
818 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
821 audiocontext = (GstMatroskaTrackAudioContext *) context;
822 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
825 while (ret == GST_FLOW_OK &&
826 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
827 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
832 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
835 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
840 GST_WARNING_OBJECT (demux,
841 "Invalid TrackAudioSamplingFrequency %lf", num);
845 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
846 audiocontext->samplerate = num;
851 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
854 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
858 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
862 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
864 audiocontext->bitdepth = num;
869 case GST_MATROSKA_ID_AUDIOCHANNELS:{
872 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
876 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
880 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
882 audiocontext->channels = num;
887 GST_WARNING_OBJECT (demux,
888 "Unknown TrackAudio subelement 0x%x - ignoring", id);
890 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
891 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
892 ret = gst_ebml_read_skip (ebml);
897 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
902 /* codec identifier */
903 case GST_MATROSKA_ID_CODECID:{
906 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
909 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
910 context->codec_id = text;
914 /* codec private data */
915 case GST_MATROSKA_ID_CODECPRIVATE:{
920 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
923 context->codec_priv = data;
924 context->codec_priv_size = size;
926 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
931 /* name of the codec */
932 case GST_MATROSKA_ID_CODECNAME:{
935 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
938 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
939 context->codec_name = text;
944 case GST_MATROSKA_ID_CODECDELAY:{
947 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
950 context->codec_delay = num;
952 GST_DEBUG_OBJECT (demux, "CodecDelay: %" GST_TIME_FORMAT,
953 GST_TIME_ARGS (num));
958 case GST_MATROSKA_ID_SEEKPREROLL:{
961 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
964 context->seek_preroll = num;
966 GST_DEBUG_OBJECT (demux, "SeekPreroll: %" GST_TIME_FORMAT,
967 GST_TIME_ARGS (num));
971 /* name of this track */
972 case GST_MATROSKA_ID_TRACKNAME:{
975 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
978 context->name = text;
979 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
983 /* language (matters for audio/subtitles, mostly) */
984 case GST_MATROSKA_ID_TRACKLANGUAGE:{
987 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
991 context->language = text;
994 if (strlen (context->language) >= 4 && context->language[3] == '-')
995 context->language[3] = '\0';
997 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
998 GST_STR_NULL (context->language));
1002 /* whether this is actually used */
1003 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1006 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1010 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1012 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1014 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1015 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1019 /* whether it's the default for this track type */
1020 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1023 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1027 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1029 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1031 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1032 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
1036 /* whether the track must be used during playback */
1037 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1040 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1044 context->flags |= GST_MATROSKA_TRACK_FORCED;
1046 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1048 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1049 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
1053 /* lacing (like MPEG, where blocks don't end/start on frame
1055 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1058 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1062 context->flags |= GST_MATROSKA_TRACK_LACING;
1064 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1066 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1067 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
1071 /* default length (in time) of one data block in this track */
1072 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1075 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1080 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1084 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1086 context->default_duration = num;
1090 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1091 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1096 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1099 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1103 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1107 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1108 context->timecodescale = num;
1113 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1116 /* we ignore these because they're nothing useful (i.e. crap)
1117 * or simply not implemented yet. */
1118 case GST_MATROSKA_ID_TRACKMINCACHE:
1119 case GST_MATROSKA_ID_TRACKMAXCACHE:
1120 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1121 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1122 case GST_MATROSKA_ID_TRACKOVERLAY:
1123 case GST_MATROSKA_ID_TRACKTRANSLATE:
1124 case GST_MATROSKA_ID_TRACKOFFSET:
1125 case GST_MATROSKA_ID_CODECSETTINGS:
1126 case GST_MATROSKA_ID_CODECINFOURL:
1127 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1128 case GST_MATROSKA_ID_CODECDECODEALL:
1129 ret = gst_ebml_read_skip (ebml);
1134 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1136 /* Decode codec private data if necessary */
1137 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1138 && context->codec_priv_size > 0) {
1139 if (!gst_matroska_decode_data (context->encodings,
1140 &context->codec_priv, &context->codec_priv_size,
1141 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1142 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1143 ret = GST_FLOW_ERROR;
1147 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1148 && ret != GST_FLOW_EOS)) {
1149 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1150 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1152 demux->common.num_streams--;
1153 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1154 g_assert (demux->common.src->len == demux->common.num_streams);
1155 gst_matroska_track_free (context);
1160 /* check for a cached track taglist */
1162 (GstTagList *) g_hash_table_lookup (demux->common.cached_track_taglists,
1163 GUINT_TO_POINTER (context->uid));
1165 gst_tag_list_insert (context->tags, cached_taglist, GST_TAG_MERGE_APPEND);
1167 /* now create the GStreamer connectivity */
1168 switch (context->type) {
1169 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1170 GstMatroskaTrackVideoContext *videocontext =
1171 (GstMatroskaTrackVideoContext *) context;
1173 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1174 templ = gst_element_class_get_pad_template (klass, "video_%u");
1175 caps = gst_matroska_demux_video_caps (videocontext,
1176 context->codec_id, context->codec_priv,
1177 context->codec_priv_size, &codec, &riff_fourcc);
1180 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1181 GST_TAG_VIDEO_CODEC, codec, NULL);
1182 context->tags_changed = TRUE;
1188 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1189 GstMatroskaTrackAudioContext *audiocontext =
1190 (GstMatroskaTrackAudioContext *) context;
1192 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1193 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1194 caps = gst_matroska_demux_audio_caps (audiocontext,
1195 context->codec_id, context->codec_priv, context->codec_priv_size,
1196 &codec, &riff_audio_fmt);
1199 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1200 GST_TAG_AUDIO_CODEC, codec, NULL);
1201 context->tags_changed = TRUE;
1207 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1208 GstMatroskaTrackSubtitleContext *subtitlecontext =
1209 (GstMatroskaTrackSubtitleContext *) context;
1211 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1212 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1213 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1214 context->codec_id, context->codec_priv, context->codec_priv_size);
1218 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1219 case GST_MATROSKA_TRACK_TYPE_LOGO:
1220 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1221 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1223 /* we should already have quit by now */
1224 g_assert_not_reached ();
1227 if ((context->language == NULL || *context->language == '\0') &&
1228 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1229 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1230 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1231 context->language = g_strdup ("eng");
1234 if (context->language) {
1237 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1238 lang = gst_tag_get_language_code (context->language);
1239 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1240 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1241 context->tags_changed = TRUE;
1245 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1246 "codec_id='%s'", context->codec_id);
1247 switch (context->type) {
1248 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1249 caps = gst_caps_new_empty_simple ("video/x-unknown");
1251 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1252 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1254 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1255 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1257 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1259 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1262 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1265 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1266 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1267 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1268 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1269 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1270 GST_FOURCC_ARGS (riff_fourcc));
1271 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1274 } else if (context->stream_headers != NULL) {
1275 gst_matroska_demux_add_stream_headers_to_caps (demux,
1276 context->stream_headers, caps);
1279 /* the pad in here */
1280 context->pad = gst_pad_new_from_template (templ, padname);
1281 context->caps = caps;
1283 gst_pad_set_event_function (context->pad,
1284 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1285 gst_pad_set_query_function (context->pad,
1286 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1288 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1291 gst_pad_set_element_private (context->pad, context);
1293 gst_pad_use_fixed_caps (context->pad);
1294 gst_pad_set_active (context->pad, TRUE);
1297 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1298 "%03" G_GUINT64_FORMAT ":%03" G_GUINT64_FORMAT,
1299 context->num, context->uid);
1301 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1304 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1305 demux->have_group_id = TRUE;
1307 demux->have_group_id = FALSE;
1308 gst_event_unref (stream_start);
1309 } else if (!demux->have_group_id) {
1310 demux->have_group_id = TRUE;
1311 demux->group_id = gst_util_group_id_next ();
1314 stream_start = gst_event_new_stream_start (stream_id);
1316 if (demux->have_group_id)
1317 gst_event_set_group_id (stream_start, demux->group_id);
1318 stream_flags = GST_STREAM_FLAG_NONE;
1319 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1320 stream_flags |= GST_STREAM_FLAG_SPARSE;
1321 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1322 stream_flags |= GST_STREAM_FLAG_SELECT;
1323 gst_event_set_stream_flags (stream_start, stream_flags);
1324 gst_pad_push_event (context->pad, stream_start);
1325 gst_pad_set_caps (context->pad, context->caps);
1328 if (demux->common.global_tags) {
1329 GstEvent *tag_event;
1331 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1332 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1333 GST_DEBUG_OBJECT (context->pad, "Sending global_tags %p: %" GST_PTR_FORMAT,
1334 demux->common.global_tags, demux->common.global_tags);
1337 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1339 gst_pad_push_event (context->pad, tag_event);
1342 if (G_UNLIKELY (context->tags_changed)) {
1343 GST_DEBUG_OBJECT (context->pad, "Sending tags %p: %"
1344 GST_PTR_FORMAT, context->tags, context->tags);
1345 gst_pad_push_event (context->pad,
1346 gst_event_new_tag (gst_tag_list_copy (context->tags)));
1347 context->tags_changed = FALSE;
1350 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1351 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1360 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1363 gboolean res = FALSE;
1364 GstMatroskaTrackContext *context = NULL;
1367 context = gst_pad_get_element_private (pad);
1370 switch (GST_QUERY_TYPE (query)) {
1371 case GST_QUERY_POSITION:
1375 gst_query_parse_position (query, &format, NULL);
1378 if (format == GST_FORMAT_TIME) {
1379 GST_OBJECT_LOCK (demux);
1381 gst_query_set_position (query, GST_FORMAT_TIME,
1382 MAX (context->pos, demux->stream_start_time) -
1383 demux->stream_start_time);
1385 gst_query_set_position (query, GST_FORMAT_TIME,
1386 MAX (demux->common.segment.position, demux->stream_start_time) -
1387 demux->stream_start_time);
1388 GST_OBJECT_UNLOCK (demux);
1389 } else if (format == GST_FORMAT_DEFAULT && context
1390 && context->default_duration) {
1391 GST_OBJECT_LOCK (demux);
1392 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1393 context->pos / context->default_duration);
1394 GST_OBJECT_UNLOCK (demux);
1396 GST_DEBUG_OBJECT (demux,
1397 "only position query in TIME and DEFAULT format is supported");
1403 case GST_QUERY_DURATION:
1407 gst_query_parse_duration (query, &format, NULL);
1410 if (format == GST_FORMAT_TIME) {
1411 GST_OBJECT_LOCK (demux);
1412 gst_query_set_duration (query, GST_FORMAT_TIME,
1413 demux->common.segment.duration);
1414 GST_OBJECT_UNLOCK (demux);
1415 } else if (format == GST_FORMAT_DEFAULT && context
1416 && context->default_duration) {
1417 GST_OBJECT_LOCK (demux);
1418 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1419 demux->common.segment.duration / context->default_duration);
1420 GST_OBJECT_UNLOCK (demux);
1422 GST_DEBUG_OBJECT (demux,
1423 "only duration query in TIME and DEFAULT format is supported");
1429 case GST_QUERY_SEEKING:
1433 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1434 GST_OBJECT_LOCK (demux);
1435 if (fmt == GST_FORMAT_TIME) {
1438 if (demux->streaming) {
1439 /* assuming we'll be able to get an index ... */
1440 seekable = demux->seekable;
1445 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1446 0, demux->common.segment.duration);
1449 GST_OBJECT_UNLOCK (demux);
1452 case GST_QUERY_SEGMENT:
1457 format = demux->common.segment.format;
1460 gst_segment_to_stream_time (&demux->common.segment, format,
1461 demux->common.segment.start);
1462 if ((stop = demux->common.segment.stop) == -1)
1463 stop = demux->common.segment.duration;
1466 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1468 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1475 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1478 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1487 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1489 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1493 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1496 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1498 return gst_matroska_demux_query (demux, pad, query);
1501 /* returns FALSE if there are no pads to deliver event to,
1502 * otherwise TRUE (whatever the outcome of event sending),
1503 * takes ownership of the passed event! */
1505 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1507 gboolean ret = FALSE;
1510 g_return_val_if_fail (event != NULL, FALSE);
1512 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1513 GST_EVENT_TYPE_NAME (event));
1515 g_assert (demux->common.src->len == demux->common.num_streams);
1516 for (i = 0; i < demux->common.src->len; i++) {
1517 GstMatroskaTrackContext *stream;
1519 stream = g_ptr_array_index (demux->common.src, i);
1520 gst_event_ref (event);
1521 gst_pad_push_event (stream->pad, event);
1525 gst_event_unref (event);
1530 gst_matroska_demux_send_tags (GstMatroskaDemux * demux)
1534 if (G_UNLIKELY (demux->common.global_tags_changed)) {
1535 GstEvent *tag_event;
1536 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1537 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1538 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1539 demux->common.global_tags, demux->common.global_tags);
1542 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1544 for (i = 0; i < demux->common.src->len; i++) {
1545 GstMatroskaTrackContext *stream;
1547 stream = g_ptr_array_index (demux->common.src, i);
1548 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1551 gst_event_unref (tag_event);
1552 demux->common.global_tags_changed = FALSE;
1555 g_assert (demux->common.src->len == demux->common.num_streams);
1556 for (i = 0; i < demux->common.src->len; i++) {
1557 GstMatroskaTrackContext *stream;
1559 stream = g_ptr_array_index (demux->common.src, i);
1561 if (G_UNLIKELY (stream->tags_changed)) {
1562 GST_DEBUG_OBJECT (demux, "Sending tags %p for pad %s:%s : %"
1563 GST_PTR_FORMAT, stream->tags,
1564 GST_DEBUG_PAD_NAME (stream->pad), stream->tags);
1565 gst_pad_push_event (stream->pad,
1566 gst_event_new_tag (gst_tag_list_copy (stream->tags)));
1567 stream->tags_changed = FALSE;
1573 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1575 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1578 g_return_val_if_fail (event != NULL, FALSE);
1580 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1581 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1583 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1584 GST_EVENT_TYPE_NAME (event));
1587 gst_event_unref (event);
1592 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1593 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1597 GST_OBJECT_LOCK (demux);
1600 /* seek (relative to matroska segment) */
1601 /* position might be invalid; will error when streaming resumes ... */
1602 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1603 demux->next_cluster_offset = 0;
1605 GST_DEBUG_OBJECT (demux,
1606 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1607 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1608 entry->block, GST_TIME_ARGS (entry->time));
1610 /* update the time */
1611 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1612 gst_flow_combiner_reset (demux->flowcombiner);
1613 demux->common.segment.position = entry->time;
1614 demux->seek_block = entry->block;
1615 demux->seek_first = TRUE;
1616 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1619 for (i = 0; i < demux->common.src->len; i++) {
1620 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1623 stream->to_offset = G_MAXINT64;
1625 if (stream->from_offset != -1)
1626 stream->to_offset = stream->from_offset;
1628 stream->from_offset = -1;
1629 stream->from_time = GST_CLOCK_TIME_NONE;
1632 GST_OBJECT_UNLOCK (demux);
1638 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1648 /* searches for a cluster start from @pos,
1649 * return GST_FLOW_OK and cluster position in @pos if found */
1650 static GstFlowReturn
1651 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1653 gint64 newpos = *pos;
1655 GstFlowReturn ret = GST_FLOW_OK;
1656 const guint chunk = 64 * 1024;
1657 GstBuffer *buf = NULL;
1659 gpointer data = NULL;
1664 gint64 oldpos, oldlength;
1666 orig_offset = demux->common.offset;
1668 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1671 if (demux->clusters) {
1674 cpos = gst_util_array_binary_search (demux->clusters->data,
1675 demux->clusters->len, sizeof (gint64),
1676 (GCompareDataFunc) gst_matroska_cluster_compare,
1677 GST_SEARCH_MODE_AFTER, pos, NULL);
1680 GST_DEBUG_OBJECT (demux,
1681 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1682 demux->common.offset = *cpos;
1683 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1684 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1685 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1692 /* read in at newpos and scan for ebml cluster id */
1693 oldpos = oldlength = -1;
1695 GstByteReader reader;
1699 gst_buffer_unmap (buf, &map);
1700 gst_buffer_unref (buf);
1703 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1704 if (ret != GST_FLOW_OK)
1706 GST_DEBUG_OBJECT (demux,
1707 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1708 gst_buffer_get_size (buf), newpos);
1709 gst_buffer_map (buf, &map, GST_MAP_READ);
1712 if (oldpos == newpos && oldlength == map.size) {
1713 GST_ERROR_OBJECT (demux, "Stuck at same position");
1714 ret = GST_FLOW_ERROR;
1718 oldlength = map.size;
1721 gst_byte_reader_init (&reader, data, size);
1723 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1724 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1725 if (cluster_pos >= 0) {
1726 newpos += cluster_pos;
1727 /* prepare resuming at next byte */
1728 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1729 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1732 GST_DEBUG_OBJECT (demux,
1733 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1734 /* extra checks whether we really sync'ed to a cluster:
1735 * - either it is the first and only cluster
1736 * - either there is a cluster after this one
1737 * - either cluster length is undefined
1739 /* ok if first cluster (there may not a subsequent one) */
1740 if (newpos == demux->first_cluster_offset) {
1741 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1744 demux->common.offset = newpos;
1745 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1746 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1747 if (ret != GST_FLOW_OK) {
1748 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1751 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1752 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1754 /* ok if undefined length or first cluster */
1755 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1756 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1760 demux->common.offset += length + needed;
1761 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1762 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1763 if (ret != GST_FLOW_OK)
1765 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1766 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1767 if (id == GST_MATROSKA_ID_CLUSTER)
1769 /* not ok, resume */
1772 /* partial cluster id may have been in tail of buffer */
1773 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1778 gst_buffer_unmap (buf, &map);
1779 gst_buffer_unref (buf);
1784 demux->common.offset = orig_offset;
1789 /* bisect and scan through file for cluster starting before @time,
1790 * returns fake index entry with corresponding info on cluster */
1791 static GstMatroskaIndex *
1792 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1794 GstMatroskaIndex *entry = NULL;
1795 GstMatroskaReadState current_state;
1796 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1797 gint64 opos, newpos, startpos = 0, current_offset;
1798 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1799 const guint chunk = 64 * 1024;
1805 /* (under)estimate new position, resync using cluster ebml id,
1806 * and scan forward to appropriate cluster
1807 * (and re-estimate if need to go backward) */
1809 prev_cluster_time = GST_CLOCK_TIME_NONE;
1811 /* store some current state */
1812 current_state = demux->common.state;
1813 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1815 current_cluster_offset = demux->cluster_offset;
1816 current_cluster_time = demux->cluster_time;
1817 current_offset = demux->common.offset;
1819 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1821 /* estimate using start and current position */
1822 GST_OBJECT_LOCK (demux);
1823 opos = demux->common.offset - demux->common.ebml_segment_start;
1824 otime = demux->common.segment.position;
1825 GST_OBJECT_UNLOCK (demux);
1828 time = MAX (time, demux->stream_start_time);
1830 /* avoid division by zero in first estimation below */
1831 if (otime <= demux->stream_start_time)
1835 GST_LOG_OBJECT (demux,
1836 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1837 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1838 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1839 GST_TIME_ARGS (otime - demux->stream_start_time),
1840 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1842 if (otime <= demux->stream_start_time) {
1846 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1847 time - demux->stream_start_time,
1848 otime - demux->stream_start_time) - chunk;
1852 /* favour undershoot */
1853 newpos = newpos * 90 / 100;
1854 newpos += demux->common.ebml_segment_start;
1856 GST_DEBUG_OBJECT (demux,
1857 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1858 GST_TIME_ARGS (time), newpos);
1860 /* and at least start scanning before previous scan start to avoid looping */
1861 startpos = startpos * 90 / 100;
1862 if (startpos && startpos < newpos)
1865 /* read in at newpos and scan for ebml cluster id */
1869 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1870 if (ret == GST_FLOW_EOS) {
1871 /* heuristic HACK */
1872 newpos = startpos * 80 / 100;
1873 GST_DEBUG_OBJECT (demux, "EOS; "
1874 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1875 GST_TIME_ARGS (time), newpos);
1878 } else if (ret != GST_FLOW_OK) {
1885 /* then start scanning and parsing for cluster time,
1886 * re-estimate if overshoot, otherwise next cluster and so on */
1887 demux->common.offset = newpos;
1888 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1890 guint64 cluster_size = 0;
1892 /* peek and parse some elements */
1893 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1894 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1895 if (ret != GST_FLOW_OK)
1897 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1898 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1900 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1901 if (ret != GST_FLOW_OK)
1904 if (id == GST_MATROSKA_ID_CLUSTER) {
1905 cluster_time = GST_CLOCK_TIME_NONE;
1906 if (length == G_MAXUINT64)
1909 cluster_size = length + needed;
1911 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1912 cluster_time == GST_CLOCK_TIME_NONE) {
1913 cluster_time = demux->cluster_time * demux->common.time_scale;
1914 cluster_offset = demux->cluster_offset;
1915 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1916 " with time %" GST_TIME_FORMAT, cluster_offset,
1917 GST_TIME_ARGS (cluster_time));
1918 if (cluster_time > time) {
1919 GST_DEBUG_OBJECT (demux, "overshot target");
1920 /* cluster overshoots */
1921 if (cluster_offset == demux->first_cluster_offset) {
1922 /* but no prev one */
1923 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1924 prev_cluster_time = cluster_time;
1925 prev_cluster_offset = cluster_offset;
1928 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1929 /* prev cluster did not overshoot, so prev cluster is target */
1932 /* re-estimate using this new position info */
1933 opos = cluster_offset;
1934 otime = cluster_time;
1938 /* cluster undershoots, goto next one */
1939 prev_cluster_time = cluster_time;
1940 prev_cluster_offset = cluster_offset;
1941 /* skip cluster if length is defined,
1942 * otherwise will be skippingly parsed into */
1944 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1945 demux->common.offset = cluster_offset + cluster_size;
1946 demux->cluster_time = GST_CLOCK_TIME_NONE;
1948 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1955 if (ret == GST_FLOW_EOS) {
1956 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1962 entry = g_new0 (GstMatroskaIndex, 1);
1963 entry->time = prev_cluster_time;
1964 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1965 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1966 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1970 /* restore some state */
1971 demux->cluster_offset = current_cluster_offset;
1972 demux->cluster_time = current_cluster_time;
1973 demux->common.offset = current_offset;
1974 demux->common.state = current_state;
1980 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1981 GstPad * pad, GstEvent * event)
1983 GstMatroskaIndex *entry = NULL;
1984 GstMatroskaIndex scan_entry;
1986 GstSeekType cur_type, stop_type;
1988 gboolean flush, keyunit, before, after, snap_next;
1991 GstMatroskaTrackContext *track = NULL;
1992 GstSegment seeksegment = { 0, };
1993 gboolean update = TRUE;
1994 gboolean pad_locked = FALSE;
1996 GstSearchMode snap_dir;
1998 g_return_val_if_fail (event != NULL, FALSE);
2001 track = gst_pad_get_element_private (pad);
2003 GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
2005 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2007 seqnum = gst_event_get_seqnum (event);
2009 /* we can only seek on time */
2010 if (format != GST_FORMAT_TIME) {
2011 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2015 /* copy segment, we need this because we still need the old
2016 * segment when we close the current segment. */
2017 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
2019 /* pull mode without index means that the actual duration is not known,
2020 * we might be playing a file that's still being recorded
2021 * so, invalidate our current duration, which is only a moving target,
2022 * and should not be used to clamp anything */
2023 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
2024 seeksegment.duration = GST_CLOCK_TIME_NONE;
2027 GST_DEBUG_OBJECT (demux, "configuring seek");
2028 /* Subtract stream_start_time so we always seek on a segment
2030 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2031 seeksegment.start -= demux->stream_start_time;
2032 seeksegment.position -= demux->stream_start_time;
2033 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2034 seeksegment.stop -= demux->stream_start_time;
2036 seeksegment.stop = seeksegment.duration;
2039 gst_segment_do_seek (&seeksegment, rate, format, flags,
2040 cur_type, cur, stop_type, stop, &update);
2042 /* Restore the clip timestamp offset */
2043 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2044 seeksegment.position += demux->stream_start_time;
2045 seeksegment.start += demux->stream_start_time;
2046 if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2047 seeksegment.stop = seeksegment.duration;
2048 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2049 seeksegment.stop += demux->stream_start_time;
2052 /* restore segment duration (if any effect),
2053 * would be determined again when parsing, but anyway ... */
2054 seeksegment.duration = demux->common.segment.duration;
2056 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2057 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2058 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
2059 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
2061 /* always do full update if flushing,
2062 * otherwise problems might arise downstream with missing keyframes etc */
2063 update = update || flush;
2065 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2067 /* check sanity before we start flushing and all that */
2068 snap_next = after && !before;
2069 if (seeksegment.rate < 0)
2070 snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
2072 snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
2074 GST_OBJECT_LOCK (demux);
2075 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2076 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2077 seeksegment.position, &demux->seek_index, &demux->seek_entry,
2078 snap_dir)) == NULL) {
2079 /* pull mode without index can scan later on */
2080 if (demux->streaming) {
2081 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2082 GST_OBJECT_UNLOCK (demux);
2084 } else if (rate < 0.0) {
2085 /* FIXME: We should build an index during playback or when scanning
2086 * that can be used here. The reverse playback code requires seek_index
2087 * and seek_entry to be set!
2089 GST_DEBUG_OBJECT (demux,
2090 "No matching seek entry in index, needed for reverse playback");
2091 GST_OBJECT_UNLOCK (demux);
2095 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2096 GST_OBJECT_UNLOCK (demux);
2099 /* only have to update some segment,
2100 * but also still have to honour flush and so on */
2101 GST_DEBUG_OBJECT (demux, "... no update");
2102 /* bad goto, bad ... */
2106 if (demux->streaming)
2111 GstEvent *flush_event = gst_event_new_flush_start ();
2112 gst_event_set_seqnum (flush_event, seqnum);
2113 GST_DEBUG_OBJECT (demux, "Starting flush");
2114 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2115 gst_matroska_demux_send_event (demux, flush_event);
2117 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2118 gst_pad_pause_task (demux->common.sinkpad);
2122 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2127 /* now grab the stream lock so that streaming cannot continue, for
2128 * non flushing seeks when the element is in PAUSED this could block
2130 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2131 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2134 /* pull mode without index can do some scanning */
2135 if (!demux->streaming && !entry) {
2136 GstEvent *flush_event;
2138 /* need to stop flushing upstream as we need it next */
2140 flush_event = gst_event_new_flush_stop (TRUE);
2141 gst_event_set_seqnum (flush_event, seqnum);
2142 gst_pad_push_event (demux->common.sinkpad, flush_event);
2144 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2145 /* keep local copy */
2147 scan_entry = *entry;
2149 entry = &scan_entry;
2151 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2153 flush_event = gst_event_new_flush_stop (TRUE);
2154 gst_event_set_seqnum (flush_event, seqnum);
2155 gst_matroska_demux_send_event (demux, flush_event);
2163 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2164 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2165 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2166 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2167 seeksegment.position = seeksegment.start;
2168 seeksegment.time = seeksegment.start - demux->stream_start_time;
2171 if (demux->streaming) {
2172 GST_OBJECT_LOCK (demux);
2173 /* track real position we should start at */
2174 GST_DEBUG_OBJECT (demux, "storing segment start");
2175 demux->requested_seek_time = seeksegment.position;
2176 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2177 GST_OBJECT_UNLOCK (demux);
2178 /* need to seek to cluster start to pick up cluster time */
2179 /* upstream takes care of flushing and all that
2180 * ... and newsegment event handling takes care of the rest */
2181 return perform_seek_to_offset (demux, rate,
2182 entry->pos + demux->common.ebml_segment_start, seqnum);
2187 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2188 gst_event_set_seqnum (flush_event, seqnum);
2189 GST_DEBUG_OBJECT (demux, "Stopping flush");
2190 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2191 gst_matroska_demux_send_event (demux, flush_event);
2194 GST_OBJECT_LOCK (demux);
2195 /* now update the real segment info */
2196 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2197 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2198 GST_OBJECT_UNLOCK (demux);
2200 /* update some (segment) state */
2201 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2204 /* notify start of new segment */
2205 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2208 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2209 GST_FORMAT_TIME, demux->common.segment.start);
2210 gst_message_set_seqnum (msg, seqnum);
2211 gst_element_post_message (GST_ELEMENT (demux), msg);
2214 GST_OBJECT_LOCK (demux);
2215 if (demux->new_segment)
2216 gst_event_unref (demux->new_segment);
2218 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2219 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2220 gst_event_set_seqnum (demux->new_segment, seqnum);
2221 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2222 demux->to_time = demux->common.segment.position;
2224 demux->to_time = GST_CLOCK_TIME_NONE;
2225 GST_OBJECT_UNLOCK (demux);
2227 /* restart our task since it might have been stopped when we did the
2229 gst_pad_start_task (demux->common.sinkpad,
2230 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2232 /* streaming can continue now */
2234 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2242 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2244 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2250 * Handle whether we can perform the seek event or if we have to let the chain
2251 * function handle seeks to build the seek indexes first.
2254 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2258 GstSeekType cur_type, stop_type;
2263 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2268 /* we can only seek on time */
2269 if (format != GST_FORMAT_TIME) {
2270 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2274 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2275 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2279 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2280 GST_DEBUG_OBJECT (demux,
2281 "Non-flushing seek not supported in streaming mode");
2285 if (flags & GST_SEEK_FLAG_SEGMENT) {
2286 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2290 /* check for having parsed index already */
2291 if (!demux->common.index_parsed) {
2292 gboolean building_index;
2295 if (!demux->index_offset) {
2296 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2300 GST_OBJECT_LOCK (demux);
2301 /* handle the seek event in the chain function */
2302 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2303 /* no more seek can be issued until state reset to _DATA */
2305 /* copy the event */
2306 if (demux->seek_event)
2307 gst_event_unref (demux->seek_event);
2308 demux->seek_event = gst_event_ref (event);
2310 /* set the building_index flag so that only one thread can setup the
2311 * structures for index seeking. */
2312 building_index = demux->building_index;
2313 if (!building_index) {
2314 demux->building_index = TRUE;
2315 offset = demux->index_offset;
2317 GST_OBJECT_UNLOCK (demux);
2319 if (!building_index) {
2320 /* seek to the first subindex or legacy index */
2321 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2322 return perform_seek_to_offset (demux, rate, offset,
2323 gst_event_get_seqnum (event));
2326 /* well, we are handling it already */
2330 /* delegate to tweaked regular seek */
2331 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2335 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2338 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2339 gboolean res = TRUE;
2341 switch (GST_EVENT_TYPE (event)) {
2342 case GST_EVENT_SEEK:
2343 /* no seeking until we are (safely) ready */
2344 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2345 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2346 gst_event_unref (event);
2349 if (!demux->streaming)
2350 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2352 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2353 gst_event_unref (event);
2358 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2359 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2360 GstMatroskaTrackVideoContext *videocontext =
2361 (GstMatroskaTrackVideoContext *) context;
2363 GstClockTimeDiff diff;
2364 GstClockTime timestamp;
2366 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2368 GST_OBJECT_LOCK (demux);
2369 videocontext->earliest_time = timestamp + diff;
2370 GST_OBJECT_UNLOCK (demux);
2373 gst_event_unref (event);
2377 case GST_EVENT_TOC_SELECT:
2380 GstTocEntry *entry = NULL;
2381 GstEvent *seek_event;
2384 if (!demux->common.toc) {
2385 GST_DEBUG_OBJECT (demux, "no TOC to select");
2388 gst_event_parse_toc_select (event, &uid);
2390 GST_OBJECT_LOCK (demux);
2391 entry = gst_toc_find_entry (demux->common.toc, uid);
2392 if (entry == NULL) {
2393 GST_OBJECT_UNLOCK (demux);
2394 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2397 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2398 GST_OBJECT_UNLOCK (demux);
2399 seek_event = gst_event_new_seek (1.0,
2401 GST_SEEK_FLAG_FLUSH,
2402 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2403 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2404 gst_event_unref (seek_event);
2408 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2412 gst_event_unref (event);
2416 /* events we don't need to handle */
2417 case GST_EVENT_NAVIGATION:
2418 gst_event_unref (event);
2422 case GST_EVENT_LATENCY:
2424 res = gst_pad_push_event (demux->common.sinkpad, event);
2431 static GstFlowReturn
2432 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2434 GstFlowReturn ret = GST_FLOW_EOS;
2435 gboolean done = TRUE;
2438 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2439 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2442 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2444 if (!demux->seek_entry) {
2445 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2449 for (i = 0; i < demux->common.src->len; i++) {
2450 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2452 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2453 ", stream %d at %" GST_TIME_FORMAT,
2454 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2455 GST_TIME_ARGS (stream->from_time));
2456 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2457 if (stream->from_time > demux->common.segment.start) {
2458 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2462 /* nothing pushed for this stream;
2463 * likely seek entry did not start at keyframe, so all was skipped.
2464 * So we need an earlier entry */
2470 GstMatroskaIndex *entry;
2472 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2473 --demux->seek_entry);
2474 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2484 static GstFlowReturn
2485 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2487 GstFlowReturn ret = GST_FLOW_OK;
2490 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2492 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2493 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2497 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2498 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2502 /* one track within the "all-tracks" header */
2503 case GST_MATROSKA_ID_TRACKENTRY:
2504 ret = gst_matroska_demux_add_stream (demux, ebml);
2508 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2513 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2515 demux->tracks_parsed = TRUE;
2521 * Read signed/unsigned "EBML" numbers.
2522 * Return: number of bytes processed.
2526 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2528 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2536 while (read <= 8 && !(total & len_mask)) {
2543 if ((total &= (len_mask - 1)) == len_mask - 1)
2548 if (data[n] == 0xff)
2550 total = (total << 8) | data[n];
2554 if (read == num_ffs && total != 0)
2563 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2568 /* read as unsigned number first */
2569 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2573 if (unum == G_MAXUINT64)
2576 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2582 * Mostly used for subtitles. We add void filler data for each
2583 * lagging stream to make sure we don't deadlock.
2587 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2589 GstClockTime gap_threshold;
2592 GST_OBJECT_LOCK (demux);
2594 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2595 GST_TIME_ARGS (demux->common.segment.position));
2597 g_assert (demux->common.num_streams == demux->common.src->len);
2598 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2599 GstMatroskaTrackContext *context;
2601 context = g_ptr_array_index (demux->common.src, stream_nr);
2603 GST_LOG_OBJECT (demux,
2604 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2605 GST_TIME_ARGS (context->pos));
2607 /* Only send gap events on non-subtitle streams if lagging way behind.
2608 * The 0.5 second threshold for subtitle streams is also quite random. */
2609 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
2610 gap_threshold = GST_SECOND / 2;
2612 gap_threshold = 3 * GST_SECOND;
2614 /* Lag need only be considered if we have advanced into requested segment */
2615 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2616 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2617 demux->common.segment.position > demux->common.segment.start &&
2618 context->pos + gap_threshold < demux->common.segment.position) {
2621 guint64 start = context->pos;
2622 guint64 stop = demux->common.segment.position - gap_threshold;
2624 GST_DEBUG_OBJECT (demux,
2625 "Synchronizing stream %d with other by advancing time from %"
2626 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2627 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2629 context->pos = stop;
2631 event = gst_event_new_gap (start, stop - start);
2632 GST_OBJECT_UNLOCK (demux);
2633 gst_pad_push_event (context->pad, event);
2634 GST_OBJECT_LOCK (demux);
2638 GST_OBJECT_UNLOCK (demux);
2641 static GstFlowReturn
2642 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2643 GstMatroskaTrackContext * stream)
2645 GstFlowReturn ret = GST_FLOW_OK;
2648 num = gst_buffer_list_length (stream->stream_headers);
2649 for (i = 0; i < num; ++i) {
2652 buf = gst_buffer_list_get (stream->stream_headers, i);
2653 buf = gst_buffer_copy (buf);
2655 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2657 if (stream->set_discont) {
2658 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2659 stream->set_discont = FALSE;
2661 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2664 /* push out all headers in one go and use last flow return */
2665 ret = gst_pad_push (stream->pad, buf);
2668 /* don't need these any longer */
2669 gst_buffer_list_unref (stream->stream_headers);
2670 stream->stream_headers = NULL;
2673 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2679 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2680 GstMatroskaTrackContext * stream)
2684 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2686 if (!stream->codec_priv)
2689 /* ideally, VobSub private data should be parsed and stored more convenient
2690 * elsewhere, but for now, only interested in a small part */
2692 /* make sure we have terminating 0 */
2693 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2695 /* just locate and parse palette part */
2696 start = strstr (buf, "palette:");
2701 guint8 r, g, b, y, u, v;
2704 while (g_ascii_isspace (*start))
2706 for (i = 0; i < 16; i++) {
2707 if (sscanf (start, "%06x", &col) != 1)
2710 while ((*start == ',') || g_ascii_isspace (*start))
2712 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2713 r = (col >> 16) & 0xff;
2714 g = (col >> 8) & 0xff;
2716 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2718 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2719 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2720 clut[i] = (y << 16) | (u << 8) | v;
2723 /* got them all without problems; build and send event */
2727 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2728 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2729 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2730 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2731 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2732 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2733 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2734 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2735 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2736 G_TYPE_INT, clut[15], NULL);
2738 gst_pad_push_event (stream->pad,
2739 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2746 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2750 GST_OBJECT_LOCK (demux);
2752 g_assert (demux->common.num_streams == demux->common.src->len);
2753 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2754 GstMatroskaTrackContext *stream;
2756 stream = g_ptr_array_index (demux->common.src, stream_nr);
2758 if (stream->send_stream_headers) {
2759 if (stream->stream_headers != NULL) {
2760 gst_matroska_demux_push_stream_headers (demux, stream);
2762 /* FIXME: perhaps we can just disable and skip this stream then */
2763 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2764 ("Failed to extract stream headers from codec private data"));
2766 stream->send_stream_headers = FALSE;
2769 if (stream->send_dvd_event) {
2770 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2771 /* FIXME: should we send this event again after (flushing) seek ? */
2772 stream->send_dvd_event = FALSE;
2776 GST_OBJECT_UNLOCK (demux);
2779 static GstFlowReturn
2780 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2781 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2784 guint seq_header_len;
2785 guint32 header, tmp;
2787 if (stream->codec_state) {
2788 seq_header = stream->codec_state;
2789 seq_header_len = stream->codec_state_size;
2790 } else if (stream->codec_priv) {
2791 seq_header = stream->codec_priv;
2792 seq_header_len = stream->codec_priv_size;
2797 /* Sequence header only needed for keyframes */
2798 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2801 if (gst_buffer_get_size (*buf) < 4)
2804 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2805 header = GUINT32_FROM_BE (tmp);
2807 /* Sequence start code, if not found prepend */
2808 if (header != 0x000001b3) {
2811 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2813 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2816 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2817 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2818 gst_buffer_get_size (*buf));
2820 gst_buffer_unref (*buf);
2827 static GstFlowReturn
2828 gst_matroska_demux_add_wvpk_header (GstElement * element,
2829 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2831 GstMatroskaTrackAudioContext *audiocontext =
2832 (GstMatroskaTrackAudioContext *) stream;
2833 GstBuffer *newbuf = NULL;
2834 GstMapInfo map, outmap;
2835 guint8 *buf_data, *data;
2843 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2846 wvh.total_samples = -1;
2847 wvh.block_index = audiocontext->wvpk_block_index;
2849 if (audiocontext->channels <= 2) {
2850 guint32 block_samples, tmp;
2851 gsize size = gst_buffer_get_size (*buf);
2853 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2854 block_samples = GUINT32_FROM_LE (tmp);
2855 /* we need to reconstruct the header of the wavpack block */
2857 /* -20 because ck_size is the size of the wavpack block -8
2858 * and lace_size is the size of the wavpack block + 12
2859 * (the three guint32 of the header that already are in the buffer) */
2860 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2862 /* block_samples, flags and crc are already in the buffer */
2863 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2865 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2871 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2872 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2873 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2874 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2875 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2876 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2877 gst_buffer_unmap (newbuf, &outmap);
2879 /* Append data from buf: */
2880 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2881 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2883 gst_buffer_unref (*buf);
2885 audiocontext->wvpk_block_index += block_samples;
2887 guint8 *outdata = NULL;
2889 gsize buf_size, size, out_size = 0;
2890 guint32 block_samples, flags, crc, blocksize;
2892 gst_buffer_map (*buf, &map, GST_MAP_READ);
2893 buf_data = map.data;
2894 buf_size = map.size;
2897 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2898 gst_buffer_unmap (*buf, &map);
2899 return GST_FLOW_ERROR;
2905 block_samples = GST_READ_UINT32_LE (data);
2910 flags = GST_READ_UINT32_LE (data);
2913 crc = GST_READ_UINT32_LE (data);
2916 blocksize = GST_READ_UINT32_LE (data);
2920 if (blocksize == 0 || size < blocksize)
2923 g_assert ((newbuf == NULL) == (outdata == NULL));
2925 if (newbuf == NULL) {
2926 out_size = sizeof (Wavpack4Header) + blocksize;
2927 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2929 gst_buffer_copy_into (newbuf, *buf,
2930 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2933 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2934 outdata = outmap.data;
2936 gst_buffer_unmap (newbuf, &outmap);
2937 out_size += sizeof (Wavpack4Header) + blocksize;
2938 gst_buffer_set_size (newbuf, out_size);
2939 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2940 outdata = outmap.data;
2943 outdata[outpos] = 'w';
2944 outdata[outpos + 1] = 'v';
2945 outdata[outpos + 2] = 'p';
2946 outdata[outpos + 3] = 'k';
2949 GST_WRITE_UINT32_LE (outdata + outpos,
2950 blocksize + sizeof (Wavpack4Header) - 8);
2951 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2952 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2953 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2954 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2955 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2956 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2957 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2958 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2961 memmove (outdata + outpos, data, blocksize);
2962 outpos += blocksize;
2966 gst_buffer_unmap (*buf, &map);
2967 gst_buffer_unref (*buf);
2970 gst_buffer_unmap (newbuf, &outmap);
2973 audiocontext->wvpk_block_index += block_samples;
2979 static GstFlowReturn
2980 gst_matroska_demux_add_prores_header (GstElement * element,
2981 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2983 GstBuffer *newbuf = gst_buffer_new_allocate (NULL, 8, NULL);
2987 if (!gst_buffer_map (newbuf, &map, GST_MAP_WRITE)) {
2988 GST_ERROR ("Failed to map newly allocated buffer");
2989 return GST_FLOW_ERROR;
2992 frame_size = gst_buffer_get_size (*buf);
2994 GST_WRITE_UINT32_BE (map.data, frame_size);
3000 gst_buffer_unmap (newbuf, &map);
3001 *buf = gst_buffer_append (newbuf, *buf);
3006 /* @text must be null-terminated */
3008 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
3013 g_return_val_if_fail (text != NULL, FALSE);
3015 /* yes, this might all lead to false positives ... */
3016 tag = (gchar *) text;
3017 while ((tag = strchr (tag, '<'))) {
3019 if (*tag != '\0' && *(tag + 1) == '>') {
3020 /* some common convenience ones */
3021 /* maybe any character will do here ? */
3034 if (strstr (text, "<span"))
3040 static GstFlowReturn
3041 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
3042 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3044 GstMatroskaTrackSubtitleContext *sub_stream;
3045 const gchar *encoding;
3050 gboolean needs_unmap = TRUE;
3052 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3054 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
3057 /* The subtitle buffer we push out should not include a NUL terminator as
3058 * part of the data. */
3059 if (map.data[map.size - 1] == '\0') {
3060 gst_buffer_set_size (*buf, map.size - 1);
3061 gst_buffer_unmap (*buf, &map);
3062 gst_buffer_map (*buf, &map, GST_MAP_READ);
3065 if (!sub_stream->invalid_utf8) {
3066 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
3069 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
3070 " is not valid UTF-8, this is broken according to the matroska"
3071 " specification", stream->num);
3072 sub_stream->invalid_utf8 = TRUE;
3075 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3076 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3077 if (encoding == NULL || *encoding == '\0') {
3078 /* if local encoding is UTF-8 and no encoding specified
3079 * via the environment variable, assume ISO-8859-15 */
3080 if (g_get_charset (&encoding)) {
3081 encoding = "ISO-8859-15";
3086 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3087 (char *) "*", NULL, NULL, &err);
3090 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3091 encoding, err->message);
3095 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3096 encoding = "ISO-8859-15";
3098 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3099 encoding, (char *) "*", NULL, NULL, NULL);
3102 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3103 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3106 utf8 = g_strdup ("invalid subtitle");
3108 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3109 gst_buffer_unmap (*buf, &map);
3110 gst_buffer_copy_into (newbuf, *buf,
3111 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3113 gst_buffer_unref (*buf);
3116 gst_buffer_map (*buf, &map, GST_MAP_READ);
3120 if (sub_stream->check_markup) {
3121 /* caps claim markup text, so we need to escape text,
3122 * except if text is already markup and then needs no further escaping */
3123 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3124 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3126 if (!sub_stream->seen_markup_tag) {
3127 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3129 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3130 gst_buffer_unmap (*buf, &map);
3131 gst_buffer_copy_into (newbuf, *buf,
3132 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3133 GST_BUFFER_COPY_META, 0, -1);
3134 gst_buffer_unref (*buf);
3137 needs_unmap = FALSE;
3142 gst_buffer_unmap (*buf, &map);
3147 static GstFlowReturn
3148 gst_matroska_demux_check_aac (GstElement * element,
3149 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3154 gst_buffer_extract (*buf, 0, data, 2);
3155 size = gst_buffer_get_size (*buf);
3157 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3160 /* tss, ADTS data, remove codec_data
3161 * still assume it is at least parsed */
3162 stream->caps = gst_caps_make_writable (stream->caps);
3163 s = gst_caps_get_structure (stream->caps, 0);
3165 gst_structure_remove_field (s, "codec_data");
3166 gst_pad_set_caps (stream->pad, stream->caps);
3167 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3168 "new caps: %" GST_PTR_FORMAT, stream->caps);
3171 /* disable subsequent checking */
3172 stream->postprocess_frame = NULL;
3178 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3179 GstBuffer * buffer, gsize alignment)
3183 gst_buffer_map (buffer, &map, GST_MAP_READ);
3185 if (map.size < sizeof (guintptr)) {
3186 gst_buffer_unmap (buffer, &map);
3190 if (((guintptr) map.data) & (alignment - 1)) {
3191 GstBuffer *new_buffer;
3192 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3194 new_buffer = gst_buffer_new_allocate (NULL,
3195 gst_buffer_get_size (buffer), ¶ms);
3197 /* Copy data "by hand", so ensure alignment is kept: */
3198 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3200 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3201 GST_DEBUG_OBJECT (demux,
3202 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3205 gst_buffer_unmap (buffer, &map);
3206 gst_buffer_unref (buffer);
3211 gst_buffer_unmap (buffer, &map);
3215 static GstFlowReturn
3216 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3217 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3218 gboolean is_simpleblock)
3220 GstMatroskaTrackContext *stream = NULL;
3221 GstFlowReturn ret = GST_FLOW_OK;
3222 gboolean readblock = FALSE;
3224 guint64 block_duration = -1;
3225 gint64 block_discardpadding = 0;
3226 GstBuffer *buf = NULL;
3228 gint stream_num = -1, n, laces = 0;
3230 gint *lace_size = NULL;
3233 gint64 referenceblock = 0;
3235 GstClockTime buffer_timestamp;
3237 offset = gst_ebml_read_get_offset (ebml);
3239 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3240 if (!is_simpleblock) {
3241 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3245 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3249 /* one block inside the group. Note, block parsing is one
3250 * of the harder things, so this code is a bit complicated.
3251 * See http://www.matroska.org/ for documentation. */
3252 case GST_MATROSKA_ID_SIMPLEBLOCK:
3253 case GST_MATROSKA_ID_BLOCK:
3259 gst_buffer_unmap (buf, &map);
3260 gst_buffer_unref (buf);
3263 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3266 gst_buffer_map (buf, &map, GST_MAP_READ);
3270 /* first byte(s): blocknum */
3271 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3276 /* fetch stream from num */
3277 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3279 if (G_UNLIKELY (size < 3)) {
3280 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3281 /* non-fatal, try next block(group) */
3284 } else if (G_UNLIKELY (stream_num < 0 ||
3285 stream_num >= demux->common.num_streams)) {
3286 /* let's not give up on a stray invalid track number */
3287 GST_WARNING_OBJECT (demux,
3288 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3289 "; ignoring block", stream_num, num);
3293 stream = g_ptr_array_index (demux->common.src, stream_num);
3295 /* time (relative to cluster time) */
3296 time = ((gint16) GST_READ_UINT16_BE (data));
3299 flags = GST_READ_UINT8 (data);
3303 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3306 switch ((flags & 0x06) >> 1) {
3307 case 0x0: /* no lacing */
3309 lace_size = g_new (gint, 1);
3310 lace_size[0] = size;
3313 case 0x1: /* xiph lacing */
3314 case 0x2: /* fixed-size lacing */
3315 case 0x3: /* EBML lacing */
3317 goto invalid_lacing;
3318 laces = GST_READ_UINT8 (data) + 1;
3321 lace_size = g_new0 (gint, laces);
3323 switch ((flags & 0x06) >> 1) {
3324 case 0x1: /* xiph lacing */ {
3325 guint temp, total = 0;
3327 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3330 goto invalid_lacing;
3331 temp = GST_READ_UINT8 (data);
3332 lace_size[n] += temp;
3338 total += lace_size[n];
3340 lace_size[n] = size - total;
3344 case 0x2: /* fixed-size lacing */
3345 for (n = 0; n < laces; n++)
3346 lace_size[n] = size / laces;
3349 case 0x3: /* EBML lacing */ {
3352 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3356 total = lace_size[0] = num;
3357 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3361 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3365 lace_size[n] = lace_size[n - 1] + snum;
3366 total += lace_size[n];
3369 lace_size[n] = size - total;
3376 if (ret != GST_FLOW_OK)
3383 case GST_MATROSKA_ID_BLOCKDURATION:{
3384 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3385 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3390 case GST_MATROSKA_ID_DISCARDPADDING:{
3391 ret = gst_ebml_read_sint (ebml, &id, &block_discardpadding);
3392 GST_DEBUG_OBJECT (demux, "DiscardPadding: %" GST_STIME_FORMAT,
3393 GST_STIME_ARGS (block_discardpadding));
3397 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3398 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3399 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3404 case GST_MATROSKA_ID_CODECSTATE:{
3406 guint64 data_len = 0;
3409 gst_ebml_read_binary (ebml, &id, &data,
3410 &data_len)) != GST_FLOW_OK)
3413 if (G_UNLIKELY (stream == NULL)) {
3414 GST_WARNING_OBJECT (demux,
3415 "Unexpected CodecState subelement - ignoring");
3419 g_free (stream->codec_state);
3420 stream->codec_state = data;
3421 stream->codec_state_size = data_len;
3423 /* Decode if necessary */
3424 if (stream->encodings && stream->encodings->len > 0
3425 && stream->codec_state && stream->codec_state_size > 0) {
3426 if (!gst_matroska_decode_data (stream->encodings,
3427 &stream->codec_state, &stream->codec_state_size,
3428 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3429 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3433 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3434 stream->codec_state_size);
3439 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3443 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3444 case GST_MATROSKA_ID_BLOCKADDITIONS:
3445 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3446 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3447 case GST_MATROSKA_ID_SLICES:
3448 GST_DEBUG_OBJECT (demux,
3449 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3450 ret = gst_ebml_read_skip (ebml);
3458 /* reading a number or so could have failed */
3459 if (ret != GST_FLOW_OK)
3462 if (ret == GST_FLOW_OK && readblock) {
3463 gboolean invisible_frame = FALSE;
3464 gboolean delta_unit = FALSE;
3465 guint64 duration = 0;
3466 gint64 lace_time = 0;
3468 stream = g_ptr_array_index (demux->common.src, stream_num);
3470 if (cluster_time != GST_CLOCK_TIME_NONE) {
3471 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3472 * Drop unless the lace contains timestamp 0? */
3473 if (time < 0 && (-time) > cluster_time) {
3476 if (stream->timecodescale == 1.0)
3477 lace_time = (cluster_time + time) * demux->common.time_scale;
3480 gst_util_guint64_to_gdouble ((cluster_time + time) *
3481 demux->common.time_scale) * stream->timecodescale;
3484 lace_time = GST_CLOCK_TIME_NONE;
3487 /* need to refresh segment info ASAP */
3488 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3489 GstSegment *segment = &demux->common.segment;
3491 GstEvent *segment_event;
3493 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3494 demux->stream_start_time = lace_time;
3495 GST_DEBUG_OBJECT (demux,
3496 "Setting stream start time to %" GST_TIME_FORMAT,
3497 GST_TIME_ARGS (lace_time));
3499 clace_time = MAX (lace_time, demux->stream_start_time);
3500 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3501 demux->common.segment.position != 0) {
3502 GST_DEBUG_OBJECT (demux,
3503 "using stored seek position %" GST_TIME_FORMAT,
3504 GST_TIME_ARGS (demux->common.segment.position));
3505 clace_time = demux->common.segment.position + demux->stream_start_time;
3506 segment->position = GST_CLOCK_TIME_NONE;
3508 segment->start = clace_time;
3509 segment->stop = GST_CLOCK_TIME_NONE;
3510 segment->time = segment->start - demux->stream_start_time;
3511 segment->position = segment->start - demux->stream_start_time;
3512 GST_DEBUG_OBJECT (demux,
3513 "generated segment starting at %" GST_TIME_FORMAT ": %"
3514 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3515 /* now convey our segment notion downstream */
3516 segment_event = gst_event_new_segment (segment);
3517 if (demux->segment_seqnum)
3518 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3519 gst_matroska_demux_send_event (demux, segment_event);
3520 demux->need_segment = FALSE;
3521 demux->segment_seqnum = 0;
3524 /* send pending codec data headers for all streams,
3525 * before we perform sync across all streams */
3526 gst_matroska_demux_push_codec_data_all (demux);
3528 if (block_duration != -1) {
3529 if (stream->timecodescale == 1.0)
3530 duration = gst_util_uint64_scale (block_duration,
3531 demux->common.time_scale, 1);
3534 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3535 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3536 1)) * stream->timecodescale);
3537 } else if (stream->default_duration) {
3538 duration = stream->default_duration * laces;
3540 /* else duration is diff between timecode of this and next block */
3542 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3543 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3544 a ReferenceBlock implies that this is not a keyframe. In either
3545 case, it only makes sense for video streams. */
3546 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3548 invisible_frame = ((flags & 0x08)) &&
3549 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3550 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3553 /* If we're doing a keyframe-only trickmode, only push keyframes on video
3557 segment.flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) {
3558 GST_LOG_OBJECT (demux, "Skipping non-keyframe on stream %d",
3565 for (n = 0; n < laces; n++) {
3568 if (G_UNLIKELY (lace_size[n] > size)) {
3569 GST_WARNING_OBJECT (demux, "Invalid lace size");
3573 /* QoS for video track with an index. the assumption is that
3574 index entries point to keyframes, but if that is not true we
3575 will instad skip until the next keyframe. */
3576 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3577 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3578 stream->index_table && demux->common.segment.rate > 0.0) {
3579 GstMatroskaTrackVideoContext *videocontext =
3580 (GstMatroskaTrackVideoContext *) stream;
3581 GstClockTime earliest_time;
3582 GstClockTime earliest_stream_time;
3584 GST_OBJECT_LOCK (demux);
3585 earliest_time = videocontext->earliest_time;
3586 GST_OBJECT_UNLOCK (demux);
3587 earliest_stream_time =
3588 gst_segment_position_from_running_time (&demux->common.segment,
3589 GST_FORMAT_TIME, earliest_time);
3591 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3592 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3593 lace_time <= earliest_stream_time) {
3594 /* find index entry (keyframe) <= earliest_stream_time */
3595 GstMatroskaIndex *entry =
3596 gst_util_array_binary_search (stream->index_table->data,
3597 stream->index_table->len, sizeof (GstMatroskaIndex),
3598 (GCompareDataFunc) gst_matroska_index_seek_find,
3599 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3601 /* if that entry (keyframe) is after the current the current
3602 buffer, we can skip pushing (and thus decoding) all
3603 buffers until that keyframe. */
3604 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3605 entry->time > lace_time) {
3606 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3607 stream->set_discont = TRUE;
3613 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3614 gst_buffer_get_size (buf) - size, lace_size[n]);
3615 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3618 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3620 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3622 if (invisible_frame)
3623 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3625 if (stream->encodings != NULL && stream->encodings->len > 0)
3626 sub = gst_matroska_decode_buffer (stream, sub);
3629 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3633 if (!stream->dts_only) {
3634 GST_BUFFER_PTS (sub) = lace_time;
3636 GST_BUFFER_DTS (sub) = lace_time;
3637 if (stream->intra_only)
3638 GST_BUFFER_PTS (sub) = lace_time;
3641 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
3643 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3644 GstClockTime last_stop_end;
3646 /* Check if this stream is after segment stop */
3647 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3648 lace_time >= demux->common.segment.stop) {
3649 GST_DEBUG_OBJECT (demux,
3650 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3651 GST_TIME_ARGS (demux->common.segment.stop));
3652 gst_buffer_unref (sub);
3655 if (offset >= stream->to_offset
3656 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3657 && lace_time > demux->to_time)) {
3658 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3660 gst_buffer_unref (sub);
3664 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3665 * that landed us with timestamps not quite intended */
3666 GST_OBJECT_LOCK (demux);
3667 if (demux->max_gap_time &&
3668 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3669 demux->common.segment.rate > 0.0) {
3670 GstClockTimeDiff diff;
3672 /* only send segments with increasing start times,
3673 * otherwise if these go back and forth downstream (sinks) increase
3674 * accumulated time and running_time */
3675 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3676 if (diff > 0 && diff > demux->max_gap_time
3677 && lace_time > demux->common.segment.start
3678 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3679 || lace_time < demux->common.segment.stop)) {
3681 GST_DEBUG_OBJECT (demux,
3682 "Gap of %" G_GINT64_FORMAT " ns detected in"
3683 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3684 "Sending updated SEGMENT events", diff,
3685 stream->index, GST_TIME_ARGS (stream->pos),
3686 GST_TIME_ARGS (lace_time));
3688 event = gst_event_new_gap (demux->last_stop_end, diff);
3689 GST_OBJECT_UNLOCK (demux);
3690 gst_pad_push_event (stream->pad, event);
3691 GST_OBJECT_LOCK (demux);
3695 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3696 || demux->common.segment.position < lace_time) {
3697 demux->common.segment.position = lace_time;
3699 GST_OBJECT_UNLOCK (demux);
3701 last_stop_end = lace_time;
3703 GST_BUFFER_DURATION (sub) = duration / laces;
3704 last_stop_end += GST_BUFFER_DURATION (sub);
3707 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3708 demux->last_stop_end < last_stop_end)
3709 demux->last_stop_end = last_stop_end;
3711 GST_OBJECT_LOCK (demux);
3712 if (demux->common.segment.duration == -1 ||
3713 demux->stream_start_time + demux->common.segment.duration <
3715 demux->common.segment.duration =
3716 last_stop_end - demux->stream_start_time;
3717 GST_OBJECT_UNLOCK (demux);
3718 if (!demux->invalid_duration) {
3719 gst_element_post_message (GST_ELEMENT_CAST (demux),
3720 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3721 demux->invalid_duration = TRUE;
3724 GST_OBJECT_UNLOCK (demux);
3728 stream->pos = lace_time;
3730 gst_matroska_demux_sync_streams (demux);
3732 if (stream->set_discont) {
3733 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3734 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3735 stream->set_discont = FALSE;
3737 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3740 /* reverse playback book-keeping */
3741 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3742 stream->from_time = lace_time;
3743 if (stream->from_offset == -1)
3744 stream->from_offset = offset;
3746 GST_DEBUG_OBJECT (demux,
3747 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3748 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3749 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3750 GST_TIME_ARGS (buffer_timestamp),
3751 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3754 if (demux->common.element_index) {
3755 if (stream->index_writer_id == -1)
3756 gst_index_get_writer_id (demux->common.element_index,
3757 GST_OBJECT (stream->pad), &stream->index_writer_id);
3759 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3760 G_GUINT64_FORMAT " for writer id %d",
3761 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
3762 stream->index_writer_id);
3763 gst_index_add_association (demux->common.element_index,
3764 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3765 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3766 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
3771 /* Postprocess the buffers depending on the codec used */
3772 if (stream->postprocess_frame) {
3773 GST_LOG_OBJECT (demux, "running post process");
3774 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3777 /* At this point, we have a sub-buffer pointing at data within a larger
3778 buffer. This data might not be aligned with anything. If the data is
3779 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3780 for 32 bit samples, etc), or bad things will happen downstream as
3781 elements typically assume minimal alignment.
3782 Therefore, create an aligned copy if necessary. */
3783 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3785 if (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
3786 guint64 start_clip = 0, end_clip = 0;
3788 /* Codec delay is part of the timestamps */
3789 if (GST_BUFFER_PTS_IS_VALID (sub) && stream->codec_delay) {
3790 if (GST_BUFFER_PTS (sub) > stream->codec_delay) {
3791 GST_BUFFER_PTS (sub) -= stream->codec_delay;
3793 GST_BUFFER_PTS (sub) = 0;
3795 gst_util_uint64_scale_round (stream->codec_delay, 48000,
3798 if (GST_BUFFER_DURATION_IS_VALID (sub)) {
3799 if (GST_BUFFER_DURATION (sub) > stream->codec_delay)
3800 GST_BUFFER_DURATION (sub) -= stream->codec_delay;
3802 GST_BUFFER_DURATION (sub) = 0;
3807 if (block_discardpadding) {
3809 gst_util_uint64_scale_round (block_discardpadding, 48000,
3813 if (start_clip || end_clip) {
3814 gst_buffer_add_audio_clipping_meta (sub, GST_FORMAT_DEFAULT,
3815 start_clip, end_clip);
3819 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3820 stream->pos = GST_BUFFER_PTS (sub);
3821 if (GST_BUFFER_DURATION_IS_VALID (sub))
3822 stream->pos += GST_BUFFER_DURATION (sub);
3823 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
3824 stream->pos = GST_BUFFER_DTS (sub);
3825 if (GST_BUFFER_DURATION_IS_VALID (sub))
3826 stream->pos += GST_BUFFER_DURATION (sub);
3829 ret = gst_pad_push (stream->pad, sub);
3831 if (demux->common.segment.rate < 0) {
3832 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3833 /* In reverse playback we can get a GST_FLOW_EOS when
3834 * we are at the end of the segment, so we just need to jump
3835 * back to the previous section. */
3836 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3841 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
3845 size -= lace_size[n];
3846 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3847 lace_time += duration / laces;
3849 lace_time = GST_CLOCK_TIME_NONE;
3855 gst_buffer_unmap (buf, &map);
3856 gst_buffer_unref (buf);
3868 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
3874 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3875 /* non-fatal, try next block(group) */
3881 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3882 /* non-fatal, try next block(group) */
3888 /* return FALSE if block(group) should be skipped (due to a seek) */
3889 static inline gboolean
3890 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3892 if (G_UNLIKELY (demux->seek_block)) {
3893 if (!(--demux->seek_block)) {
3896 GST_LOG_OBJECT (demux, "should skip block due to seek");
3904 static GstFlowReturn
3905 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3909 guint64 seek_pos = (guint64) - 1;
3910 guint32 seek_id = 0;
3913 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3915 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3916 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3920 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3921 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3925 case GST_MATROSKA_ID_SEEKID:
3929 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3932 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3937 case GST_MATROSKA_ID_SEEKPOSITION:
3941 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3944 if (t > G_MAXINT64) {
3945 GST_WARNING_OBJECT (demux,
3946 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3950 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3956 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3962 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3965 if (!seek_id || seek_pos == (guint64) - 1) {
3966 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3967 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3972 case GST_MATROSKA_ID_SEEKHEAD:
3975 case GST_MATROSKA_ID_CUES:
3976 case GST_MATROSKA_ID_TAGS:
3977 case GST_MATROSKA_ID_TRACKS:
3978 case GST_MATROSKA_ID_SEGMENTINFO:
3979 case GST_MATROSKA_ID_ATTACHMENTS:
3980 case GST_MATROSKA_ID_CHAPTERS:
3982 guint64 before_pos, length;
3986 length = gst_matroska_read_common_get_length (&demux->common);
3987 before_pos = demux->common.offset;
3989 if (length == (guint64) - 1) {
3990 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3994 /* check for validity */
3995 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3996 GST_WARNING_OBJECT (demux,
3997 "SeekHead reference lies outside file!" " (%"
3998 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3999 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
4004 /* only pick up index location when streaming */
4005 if (demux->streaming) {
4006 if (seek_id == GST_MATROSKA_ID_CUES) {
4007 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
4008 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
4009 demux->index_offset);
4015 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
4018 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4019 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
4023 if (id != seek_id) {
4024 GST_WARNING_OBJECT (demux,
4025 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
4026 seek_id, id, seek_pos + demux->common.ebml_segment_start);
4029 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4034 demux->common.offset = before_pos;
4038 case GST_MATROSKA_ID_CLUSTER:
4040 guint64 pos = seek_pos + demux->common.ebml_segment_start;
4042 GST_LOG_OBJECT (demux, "Cluster position");
4043 if (G_UNLIKELY (!demux->clusters))
4044 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
4045 g_array_append_val (demux->clusters, pos);
4050 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
4053 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4058 static GstFlowReturn
4059 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4061 GstFlowReturn ret = GST_FLOW_OK;
4064 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4066 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4067 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4071 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4072 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4076 case GST_MATROSKA_ID_SEEKENTRY:
4078 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
4079 /* Ignore EOS and errors here */
4080 if (ret != GST_FLOW_OK) {
4081 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4088 ret = gst_matroska_read_common_parse_skip (&demux->common,
4089 ebml, "SeekHead", id);
4094 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4096 /* Sort clusters by position for easier searching */
4097 if (demux->clusters)
4098 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4103 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
4105 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4107 static inline GstFlowReturn
4108 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4110 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4111 /* only a few blocks are expected/allowed to be large,
4112 * and will be recursed into, whereas others will be read and must fit */
4113 if (demux->streaming) {
4114 /* fatal in streaming case, as we can't step over easily */
4115 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4116 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4117 "file might be corrupt.", bytes));
4118 return GST_FLOW_ERROR;
4120 /* indicate higher level to quietly give up */
4121 GST_DEBUG_OBJECT (demux,
4122 "too large block of size %" G_GUINT64_FORMAT, bytes);
4123 return GST_FLOW_ERROR;
4130 /* returns TRUE if we truely are in error state, and should give up */
4131 static inline GstFlowReturn
4132 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4134 if (!demux->streaming && demux->next_cluster_offset > 0) {
4135 /* just repositioning to where next cluster should be and try from there */
4136 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4137 G_GUINT64_FORMAT, demux->next_cluster_offset);
4138 demux->common.offset = demux->next_cluster_offset;
4139 demux->next_cluster_offset = 0;
4145 /* sigh, one last attempt above and beyond call of duty ...;
4146 * search for cluster mark following current pos */
4147 pos = demux->common.offset;
4148 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4149 if ((ret = gst_matroska_demux_search_cluster (demux, &pos)) != GST_FLOW_OK) {
4150 /* did not work, give up */
4153 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4154 /* try that position */
4155 demux->common.offset = pos;
4161 static inline GstFlowReturn
4162 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4164 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4165 demux->common.offset += flush;
4166 if (demux->streaming) {
4169 /* hard to skip large blocks when streaming */
4170 ret = gst_matroska_demux_check_read_size (demux, flush);
4171 if (ret != GST_FLOW_OK)
4173 if (flush <= gst_adapter_available (demux->common.adapter))
4174 gst_adapter_flush (demux->common.adapter, flush);
4176 return GST_FLOW_EOS;
4181 /* initializes @ebml with @bytes from input stream at current offset.
4182 * Returns EOS if insufficient available,
4183 * ERROR if too much was attempted to read. */
4184 static inline GstFlowReturn
4185 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4188 GstBuffer *buffer = NULL;
4189 GstFlowReturn ret = GST_FLOW_OK;
4191 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4193 ret = gst_matroska_demux_check_read_size (demux, bytes);
4194 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4195 if (!demux->streaming) {
4196 /* in pull mode, we can skip */
4197 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4198 ret = GST_FLOW_OVERFLOW;
4200 /* otherwise fatal */
4201 ret = GST_FLOW_ERROR;
4205 if (demux->streaming) {
4206 if (gst_adapter_available (demux->common.adapter) >= bytes)
4207 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4211 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4212 demux->common.offset, bytes, &buffer, NULL);
4213 if (G_LIKELY (buffer)) {
4214 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4215 demux->common.offset);
4216 demux->common.offset += bytes;
4223 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4226 gboolean seekable = FALSE;
4227 gint64 start = -1, stop = -1;
4229 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4230 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4231 GST_DEBUG_OBJECT (demux, "seeking query failed");
4235 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4237 /* try harder to query upstream size if we didn't get it the first time */
4238 if (seekable && stop == -1) {
4239 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4240 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4244 /* if upstream doesn't know the size, it's likely that it's not seekable in
4245 * practice even if it technically may be seekable */
4246 if (seekable && (start != 0 || stop <= start)) {
4247 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4252 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4253 G_GUINT64_FORMAT ")", seekable, start, stop);
4254 demux->seekable = seekable;
4256 gst_query_unref (query);
4259 static GstFlowReturn
4260 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4266 GstFlowReturn ret = GST_FLOW_OK;
4268 GST_WARNING_OBJECT (demux,
4269 "Found Cluster element before Tracks, searching Tracks");
4272 before_pos = demux->common.offset;
4274 /* Search Tracks element */
4276 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4277 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4278 if (ret != GST_FLOW_OK)
4281 if (id != GST_MATROSKA_ID_TRACKS) {
4282 /* we may be skipping large cluster here, so forego size check etc */
4283 /* ... but we can't skip undefined size; force error */
4284 if (length == G_MAXUINT64) {
4285 ret = gst_matroska_demux_check_read_size (demux, length);
4288 demux->common.offset += needed;
4289 demux->common.offset += length;
4294 /* will lead to track parsing ... */
4295 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4300 demux->common.offset = before_pos;
4305 #define GST_READ_CHECK(stmt) \
4307 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4308 if (ret == GST_FLOW_OVERFLOW) { \
4309 ret = GST_FLOW_OK; \
4315 static GstFlowReturn
4316 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4317 guint64 length, guint needed)
4319 GstEbmlRead ebml = { 0, };
4320 GstFlowReturn ret = GST_FLOW_OK;
4323 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4324 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4326 /* if we plan to read and parse this element, we need prefix (id + length)
4327 * and the contents */
4328 /* mind about overflow wrap-around when dealing with undefined size */
4330 if (G_LIKELY (length != G_MAXUINT64))
4333 switch (demux->common.state) {
4334 case GST_MATROSKA_READ_STATE_START:
4336 case GST_EBML_ID_HEADER:
4337 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4338 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4339 if (ret != GST_FLOW_OK)
4341 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4342 gst_matroska_demux_check_seekability (demux);
4345 goto invalid_header;
4349 case GST_MATROSKA_READ_STATE_SEGMENT:
4351 case GST_MATROSKA_ID_SEGMENT:
4352 /* eat segment prefix */
4353 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4354 GST_DEBUG_OBJECT (demux,
4355 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4356 G_GUINT64_FORMAT, demux->common.offset, length);
4357 /* seeks are from the beginning of the segment,
4358 * after the segment ID/length */
4359 demux->common.ebml_segment_start = demux->common.offset;
4361 length = G_MAXUINT64;
4362 demux->common.ebml_segment_length = length;
4363 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4366 GST_WARNING_OBJECT (demux,
4367 "Expected a Segment ID (0x%x), but received 0x%x!",
4368 GST_MATROSKA_ID_SEGMENT, id);
4369 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4373 case GST_MATROSKA_READ_STATE_SCANNING:
4374 if (id != GST_MATROSKA_ID_CLUSTER &&
4375 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4378 case GST_MATROSKA_READ_STATE_HEADER:
4379 case GST_MATROSKA_READ_STATE_DATA:
4380 case GST_MATROSKA_READ_STATE_SEEK:
4382 case GST_MATROSKA_ID_SEGMENTINFO:
4383 if (!demux->common.segmentinfo_parsed) {
4384 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4385 ret = gst_matroska_read_common_parse_info (&demux->common,
4386 GST_ELEMENT_CAST (demux), &ebml);
4387 if (ret == GST_FLOW_OK)
4388 gst_matroska_demux_send_tags (demux);
4390 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4393 case GST_MATROSKA_ID_TRACKS:
4394 if (!demux->tracks_parsed) {
4395 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4396 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4398 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4401 case GST_MATROSKA_ID_CLUSTER:
4402 if (G_UNLIKELY (!demux->tracks_parsed)) {
4403 if (demux->streaming) {
4404 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4405 goto not_streamable;
4407 ret = gst_matroska_demux_find_tracks (demux);
4408 if (!demux->tracks_parsed)
4412 if (G_UNLIKELY (demux->common.state
4413 == GST_MATROSKA_READ_STATE_HEADER)) {
4414 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4415 demux->first_cluster_offset = demux->common.offset;
4416 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4417 gst_element_no_more_pads (GST_ELEMENT (demux));
4418 /* send initial segment - we wait till we know the first
4419 incoming timestamp, so we can properly set the start of
4421 demux->need_segment = TRUE;
4423 demux->cluster_time = GST_CLOCK_TIME_NONE;
4424 demux->cluster_offset = demux->common.offset;
4425 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4426 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4427 " not found in Cluster, trying next Cluster's first block instead",
4429 demux->seek_block = 0;
4431 demux->seek_first = FALSE;
4432 /* record next cluster for recovery */
4433 if (read != G_MAXUINT64)
4434 demux->next_cluster_offset = demux->cluster_offset + read;
4435 /* eat cluster prefix */
4436 gst_matroska_demux_flush (demux, needed);
4438 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4442 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4443 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4445 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4446 demux->cluster_time = num;
4448 if (demux->common.element_index) {
4449 if (demux->common.element_index_writer_id == -1)
4450 gst_index_get_writer_id (demux->common.element_index,
4451 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4452 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4453 G_GUINT64_FORMAT " for writer id %d",
4454 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4455 demux->common.element_index_writer_id);
4456 gst_index_add_association (demux->common.element_index,
4457 demux->common.element_index_writer_id,
4458 GST_ASSOCIATION_FLAG_KEY_UNIT,
4459 GST_FORMAT_TIME, demux->cluster_time,
4460 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4465 case GST_MATROSKA_ID_BLOCKGROUP:
4466 if (!gst_matroska_demux_seek_block (demux))
4468 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4469 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4470 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4471 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4472 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4474 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4476 case GST_MATROSKA_ID_SIMPLEBLOCK:
4477 if (!gst_matroska_demux_seek_block (demux))
4479 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4480 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4481 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4482 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4483 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4485 case GST_MATROSKA_ID_ATTACHMENTS:
4486 if (!demux->common.attachments_parsed) {
4487 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4488 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4489 GST_ELEMENT_CAST (demux), &ebml);
4490 if (ret == GST_FLOW_OK)
4491 gst_matroska_demux_send_tags (demux);
4493 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4496 case GST_MATROSKA_ID_TAGS:
4497 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4498 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4499 GST_ELEMENT_CAST (demux), &ebml);
4500 if (ret == GST_FLOW_OK)
4501 gst_matroska_demux_send_tags (demux);
4503 case GST_MATROSKA_ID_CHAPTERS:
4504 if (!demux->common.chapters_parsed) {
4505 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4507 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4509 if (demux->common.toc) {
4510 gst_matroska_demux_send_event (demux,
4511 gst_event_new_toc (demux->common.toc, FALSE));
4514 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4516 case GST_MATROSKA_ID_SEEKHEAD:
4517 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4518 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4520 case GST_MATROSKA_ID_CUES:
4521 if (demux->common.index_parsed) {
4522 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4525 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4526 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4527 /* only push based; delayed index building */
4528 if (ret == GST_FLOW_OK
4529 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4532 GST_OBJECT_LOCK (demux);
4533 event = demux->seek_event;
4534 demux->seek_event = NULL;
4535 GST_OBJECT_UNLOCK (demux);
4538 /* unlikely to fail, since we managed to seek to this point */
4539 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
4540 gst_event_unref (event);
4543 gst_event_unref (event);
4544 /* resume data handling, main thread clear to seek again */
4545 GST_OBJECT_LOCK (demux);
4546 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4547 GST_OBJECT_UNLOCK (demux);
4550 case GST_MATROSKA_ID_POSITION:
4551 case GST_MATROSKA_ID_PREVSIZE:
4552 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4553 case GST_MATROSKA_ID_SILENTTRACKS:
4554 GST_DEBUG_OBJECT (demux,
4555 "Skipping Cluster subelement 0x%x - ignoring", id);
4559 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4560 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4566 if (ret == GST_FLOW_PARSE)
4570 gst_ebml_read_clear (&ebml);
4576 /* simply exit, maybe not enough data yet */
4577 /* no ebml to clear if read error */
4582 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4583 ("Failed to parse Element 0x%x", id));
4584 ret = GST_FLOW_ERROR;
4589 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4590 ("File layout does not permit streaming"));
4591 ret = GST_FLOW_ERROR;
4596 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4597 ("No Tracks element found"));
4598 ret = GST_FLOW_ERROR;
4603 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4604 ret = GST_FLOW_ERROR;
4609 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4610 ret = GST_FLOW_ERROR;
4616 gst_matroska_demux_loop (GstPad * pad)
4618 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4624 /* If we have to close a segment, send a new segment to do this now */
4625 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4626 if (G_UNLIKELY (demux->new_segment)) {
4627 gst_matroska_demux_send_event (demux, demux->new_segment);
4628 demux->new_segment = NULL;
4632 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4633 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4634 if (ret == GST_FLOW_EOS) {
4636 } else if (ret == GST_FLOW_FLUSHING) {
4638 } else if (ret != GST_FLOW_OK) {
4639 ret = gst_matroska_demux_check_parse_error (demux);
4641 /* Only handle EOS as no error if we're outside the segment already */
4642 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4643 && demux->common.offset >=
4644 demux->common.ebml_segment_start +
4645 demux->common.ebml_segment_length))
4647 else if (ret != GST_FLOW_OK)
4653 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4654 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4657 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4658 if (ret == GST_FLOW_EOS)
4660 if (ret != GST_FLOW_OK)
4663 /* check if we're at the end of a configured segment */
4664 if (G_LIKELY (demux->common.src->len)) {
4667 g_assert (demux->common.num_streams == demux->common.src->len);
4668 for (i = 0; i < demux->common.src->len; i++) {
4669 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4671 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4672 GST_TIME_ARGS (context->pos));
4673 if (context->eos == FALSE)
4677 GST_INFO_OBJECT (demux, "All streams are EOS");
4683 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4684 demux->common.offset >= demux->cached_length)) {
4685 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4686 if (demux->common.offset == demux->cached_length) {
4687 GST_LOG_OBJECT (demux, "Reached end of stream");
4698 if (demux->common.segment.rate < 0.0) {
4699 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4700 if (ret == GST_FLOW_OK)
4707 const gchar *reason = gst_flow_get_name (ret);
4708 gboolean push_eos = FALSE;
4710 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4711 gst_pad_pause_task (demux->common.sinkpad);
4713 if (ret == GST_FLOW_EOS) {
4714 /* perform EOS logic */
4716 /* If we were in the headers, make sure we send no-more-pads.
4717 This will ensure decodebin does not get stuck thinking
4718 the chain is not complete yet, and waiting indefinitely. */
4719 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4720 if (demux->common.src->len == 0) {
4721 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4722 ("No pads created"));
4724 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4725 ("Failed to finish reading headers"));
4727 gst_element_no_more_pads (GST_ELEMENT (demux));
4730 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4733 /* for segment playback we need to post when (in stream time)
4734 * we stopped, this is either stop (when set) or the duration. */
4735 if ((stop = demux->common.segment.stop) == -1)
4736 stop = demux->last_stop_end;
4738 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4739 gst_element_post_message (GST_ELEMENT (demux),
4740 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4742 gst_matroska_demux_send_event (demux,
4743 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4747 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4748 /* for fatal errors we post an error message */
4749 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4750 ("stream stopped, reason %s", reason));
4754 /* send EOS, and prevent hanging if no streams yet */
4755 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4756 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4757 (ret == GST_FLOW_EOS)) {
4758 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4759 (NULL), ("got eos but no streams (yet)"));
4767 * Create and push a flushing seek event upstream
4770 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4776 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4779 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4780 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4781 GST_SEEK_TYPE_NONE, -1);
4782 gst_event_set_seqnum (event, seqnum);
4784 res = gst_pad_push_event (demux->common.sinkpad, event);
4786 /* segment event will update offset */
4790 static GstFlowReturn
4791 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4793 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4795 GstFlowReturn ret = GST_FLOW_OK;
4800 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4801 GST_DEBUG_OBJECT (demux, "got DISCONT");
4802 gst_adapter_clear (demux->common.adapter);
4803 GST_OBJECT_LOCK (demux);
4804 gst_matroska_read_common_reset_streams (&demux->common,
4805 GST_CLOCK_TIME_NONE, FALSE);
4806 GST_OBJECT_UNLOCK (demux);
4809 gst_adapter_push (demux->common.adapter, buffer);
4813 available = gst_adapter_available (demux->common.adapter);
4815 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4816 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4817 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4818 if (demux->common.ebml_segment_length != G_MAXUINT64
4819 && demux->common.offset >=
4820 demux->common.ebml_segment_start + demux->common.ebml_segment_length)
4825 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4826 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4827 demux->common.offset, id, length, needed, available);
4829 if (needed > available)
4832 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4833 if (ret == GST_FLOW_EOS) {
4834 /* need more data */
4836 } else if (ret != GST_FLOW_OK) {
4843 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4846 gboolean res = TRUE;
4847 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4849 GST_DEBUG_OBJECT (demux,
4850 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4852 switch (GST_EVENT_TYPE (event)) {
4853 case GST_EVENT_SEGMENT:
4855 const GstSegment *segment;
4857 /* some debug output */
4858 gst_event_parse_segment (event, &segment);
4859 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4860 GST_DEBUG_OBJECT (demux,
4861 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4864 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4865 GST_DEBUG_OBJECT (demux, "still starting");
4869 /* we only expect a BYTE segment, e.g. following a seek */
4870 if (segment->format != GST_FORMAT_BYTES) {
4871 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4875 GST_DEBUG_OBJECT (demux, "clearing segment state");
4876 GST_OBJECT_LOCK (demux);
4877 /* clear current segment leftover */
4878 gst_adapter_clear (demux->common.adapter);
4879 /* and some streaming setup */
4880 demux->common.offset = segment->start;
4881 /* accumulate base based on current position */
4882 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4883 demux->common.segment.base +=
4884 (MAX (demux->common.segment.position, demux->stream_start_time)
4885 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4886 /* do not know where we are;
4887 * need to come across a cluster and generate segment */
4888 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4889 demux->cluster_time = GST_CLOCK_TIME_NONE;
4890 demux->cluster_offset = 0;
4891 demux->need_segment = TRUE;
4892 demux->segment_seqnum = gst_event_get_seqnum (event);
4893 /* but keep some of the upstream segment */
4894 demux->common.segment.rate = segment->rate;
4895 /* also check if need to keep some of the requested seek position */
4896 if (demux->seek_offset == segment->start) {
4897 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4898 demux->common.segment.position = demux->requested_seek_time;
4900 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4902 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4903 demux->seek_offset = -1;
4904 GST_OBJECT_UNLOCK (demux);
4906 /* chain will send initial segment after pads have been added,
4907 * or otherwise come up with one */
4908 GST_DEBUG_OBJECT (demux, "eating event");
4909 gst_event_unref (event);
4915 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4916 gst_event_unref (event);
4917 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4918 (NULL), ("got eos and didn't receive a complete header object"));
4919 } else if (demux->common.num_streams == 0) {
4920 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4921 (NULL), ("got eos but no streams (yet)"));
4923 gst_matroska_demux_send_event (demux, event);
4927 case GST_EVENT_FLUSH_STOP:
4931 gst_adapter_clear (demux->common.adapter);
4932 GST_OBJECT_LOCK (demux);
4933 gst_matroska_read_common_reset_streams (&demux->common,
4934 GST_CLOCK_TIME_NONE, TRUE);
4935 gst_flow_combiner_reset (demux->flowcombiner);
4936 dur = demux->common.segment.duration;
4937 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4938 demux->common.segment.duration = dur;
4939 demux->cluster_time = GST_CLOCK_TIME_NONE;
4940 demux->cluster_offset = 0;
4941 GST_OBJECT_UNLOCK (demux);
4945 res = gst_pad_event_default (pad, parent, event);
4953 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4955 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4957 gboolean pull_mode = FALSE;
4959 query = gst_query_new_scheduling ();
4961 if (gst_pad_peer_query (sinkpad, query))
4962 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4963 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4965 gst_query_unref (query);
4968 GST_DEBUG ("going to pull mode");
4969 demux->streaming = FALSE;
4970 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4972 GST_DEBUG ("going to push (streaming) mode");
4973 demux->streaming = TRUE;
4974 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4979 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4980 GstPadMode mode, gboolean active)
4983 case GST_PAD_MODE_PULL:
4985 /* if we have a scheduler we can start the task */
4986 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4989 gst_pad_stop_task (sinkpad);
4992 case GST_PAD_MODE_PUSH:
5000 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
5001 videocontext, const gchar * codec_id, guint8 * data, guint size,
5002 gchar ** codec_name, guint32 * riff_fourcc)
5004 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
5005 GstCaps *caps = NULL;
5007 g_assert (videocontext != NULL);
5008 g_assert (codec_name != NULL);
5013 /* TODO: check if we have all codec types from matroska-ids.h
5014 * check if we have to do more special things with codec_private
5017 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
5018 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
5021 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
5022 gst_riff_strf_vids *vids = NULL;
5025 GstBuffer *buf = NULL;
5027 vids = (gst_riff_strf_vids *) data;
5029 /* assure size is big enough */
5031 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
5034 if (size < sizeof (gst_riff_strf_vids)) {
5035 vids = g_new (gst_riff_strf_vids, 1);
5036 memcpy (vids, data, size);
5039 context->dts_only = TRUE; /* VFW files only store DTS */
5041 /* little-endian -> byte-order */
5042 vids->size = GUINT32_FROM_LE (vids->size);
5043 vids->width = GUINT32_FROM_LE (vids->width);
5044 vids->height = GUINT32_FROM_LE (vids->height);
5045 vids->planes = GUINT16_FROM_LE (vids->planes);
5046 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
5047 vids->compression = GUINT32_FROM_LE (vids->compression);
5048 vids->image_size = GUINT32_FROM_LE (vids->image_size);
5049 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
5050 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
5051 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
5052 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
5054 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
5055 gsize offset = sizeof (gst_riff_strf_vids);
5058 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
5059 size - offset), size - offset);
5063 *riff_fourcc = vids->compression;
5065 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
5066 buf, NULL, codec_name);
5069 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
5070 GST_FOURCC_ARGS (vids->compression));
5072 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
5073 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
5074 "video/x-compressed-yuv");
5075 context->intra_only =
5076 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
5080 gst_buffer_unref (buf);
5082 if (vids != (gst_riff_strf_vids *) data)
5085 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
5087 GstVideoFormat format;
5089 gst_video_info_init (&info);
5090 switch (videocontext->fourcc) {
5091 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5092 format = GST_VIDEO_FORMAT_I420;
5094 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5095 format = GST_VIDEO_FORMAT_YUY2;
5097 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5098 format = GST_VIDEO_FORMAT_YV12;
5100 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5101 format = GST_VIDEO_FORMAT_UYVY;
5103 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5104 format = GST_VIDEO_FORMAT_AYUV;
5106 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
5107 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
5108 format = GST_VIDEO_FORMAT_GRAY8;
5110 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
5111 format = GST_VIDEO_FORMAT_RGB;
5113 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
5114 format = GST_VIDEO_FORMAT_BGR;
5117 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5118 GST_FOURCC_ARGS (videocontext->fourcc));
5122 context->intra_only = TRUE;
5124 gst_video_info_set_format (&info, format, videocontext->pixel_width,
5125 videocontext->pixel_height);
5126 caps = gst_video_info_to_caps (&info);
5127 *codec_name = gst_pb_utils_get_codec_description (caps);
5128 context->alignment = 32;
5129 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5130 caps = gst_caps_new_simple ("video/x-divx",
5131 "divxversion", G_TYPE_INT, 4, NULL);
5132 *codec_name = g_strdup ("MPEG-4 simple profile");
5133 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5134 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5135 caps = gst_caps_new_simple ("video/mpeg",
5136 "mpegversion", G_TYPE_INT, 4,
5137 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5141 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5142 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5143 gst_buffer_unref (priv);
5145 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
5147 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5148 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5150 *codec_name = g_strdup ("MPEG-4 advanced profile");
5151 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5153 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5154 "divxversion", G_TYPE_INT, 3, NULL),
5155 gst_structure_new ("video/x-msmpeg",
5156 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5158 caps = gst_caps_new_simple ("video/x-msmpeg",
5159 "msmpegversion", G_TYPE_INT, 43, NULL);
5160 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5161 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5162 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5165 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5170 caps = gst_caps_new_simple ("video/mpeg",
5171 "systemstream", G_TYPE_BOOLEAN, FALSE,
5172 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5173 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5174 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5175 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5176 caps = gst_caps_new_empty_simple ("image/jpeg");
5177 *codec_name = g_strdup ("Motion-JPEG");
5178 context->intra_only = TRUE;
5179 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5180 caps = gst_caps_new_empty_simple ("video/x-h264");
5184 /* First byte is the version, second is the profile indication, and third
5185 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5186 * level indication. */
5187 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5190 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5191 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5192 gst_buffer_unref (priv);
5194 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5195 "alignment", G_TYPE_STRING, "au", NULL);
5197 GST_WARNING ("No codec data found, assuming output is byte-stream");
5198 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5201 *codec_name = g_strdup ("H264");
5202 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
5203 caps = gst_caps_new_empty_simple ("video/x-h265");
5207 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
5210 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5211 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5212 gst_buffer_unref (priv);
5214 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
5215 "alignment", G_TYPE_STRING, "au", NULL);
5217 GST_WARNING ("No codec data found, assuming output is byte-stream");
5218 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5221 *codec_name = g_strdup ("HEVC");
5222 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5223 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5224 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5225 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5226 gint rmversion = -1;
5228 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5230 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5232 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5234 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5237 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5238 "rmversion", G_TYPE_INT, rmversion, NULL);
5239 GST_DEBUG ("data:%p, size:0x%x", data, size);
5240 /* We need to extract the extradata ! */
5241 if (data && (size >= 0x22)) {
5246 subformat = GST_READ_UINT32_BE (data + 0x1a);
5247 rformat = GST_READ_UINT32_BE (data + 0x1e);
5250 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5252 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5253 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5254 gst_buffer_unref (priv);
5257 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5258 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5259 caps = gst_caps_new_empty_simple ("video/x-theora");
5260 context->stream_headers =
5261 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5262 context->codec_priv_size);
5263 /* FIXME: mark stream as broken and skip if there are no stream headers */
5264 context->send_stream_headers = TRUE;
5265 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5266 caps = gst_caps_new_empty_simple ("video/x-dirac");
5267 *codec_name = g_strdup_printf ("Dirac");
5268 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5269 caps = gst_caps_new_empty_simple ("video/x-vp8");
5270 *codec_name = g_strdup_printf ("On2 VP8");
5271 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5272 caps = gst_caps_new_empty_simple ("video/x-vp9");
5273 *codec_name = g_strdup_printf ("On2 VP9");
5274 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
5276 const gchar *variant, *variant_descr = "";
5278 /* Expect a fourcc in the codec private data */
5279 if (!data || size < 4) {
5280 GST_WARNING ("No or too small PRORESS fourcc (%d bytes)", size);
5284 fourcc = GST_STR_FOURCC (data);
5286 case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
5287 variant_descr = " 4:2:2 LT";
5290 case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
5292 variant_descr = " 4:2:2 HQ";
5294 case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
5296 variant_descr = " 4:4:4:4";
5298 case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
5300 variant_descr = " 4:2:2 Proxy";
5302 case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
5304 variant = "standard";
5305 variant_descr = " 4:2:2 SD";
5309 GST_LOG ("Prores video, codec fourcc %" GST_FOURCC_FORMAT,
5310 GST_FOURCC_ARGS (fourcc));
5312 caps = gst_caps_new_simple ("video/x-prores",
5313 "format", G_TYPE_STRING, variant, NULL);
5314 *codec_name = g_strdup_printf ("Apple ProRes%s", variant_descr);
5315 context->postprocess_frame = gst_matroska_demux_add_prores_header;
5317 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5323 GstStructure *structure;
5325 for (i = 0; i < gst_caps_get_size (caps); i++) {
5326 structure = gst_caps_get_structure (caps, i);
5328 /* FIXME: use the real unit here! */
5329 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5330 videocontext->pixel_width,
5331 videocontext->pixel_height,
5332 videocontext->display_width, videocontext->display_height);
5334 /* pixel width and height are the w and h of the video in pixels */
5335 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5336 gint w = videocontext->pixel_width;
5337 gint h = videocontext->pixel_height;
5339 gst_structure_set (structure,
5340 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5343 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5346 if (videocontext->display_width <= 0)
5347 videocontext->display_width = videocontext->pixel_width;
5348 if (videocontext->display_height <= 0)
5349 videocontext->display_height = videocontext->pixel_height;
5351 /* calculate the pixel aspect ratio using the display and pixel w/h */
5352 n = videocontext->display_width * videocontext->pixel_height;
5353 d = videocontext->display_height * videocontext->pixel_width;
5354 GST_DEBUG ("setting PAR to %d/%d", n, d);
5355 gst_structure_set (structure, "pixel-aspect-ratio",
5357 videocontext->display_width * videocontext->pixel_height,
5358 videocontext->display_height * videocontext->pixel_width, NULL);
5361 if (videocontext->default_fps > 0.0) {
5364 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5366 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5368 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5370 } else if (context->default_duration > 0) {
5373 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5375 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5376 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5378 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5379 fps_n, fps_d, NULL);
5381 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5385 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5386 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5389 if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
5390 if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
5391 videocontext->pixel_width, videocontext->pixel_height,
5392 videocontext->display_width * videocontext->pixel_height,
5393 videocontext->display_height * videocontext->pixel_width)) {
5394 videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
5396 gst_caps_set_simple (caps,
5397 "multiview-mode", G_TYPE_STRING,
5398 gst_video_multiview_mode_to_caps_string
5399 (videocontext->multiview_mode), "multiview-flags",
5400 GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
5401 GST_FLAG_SET_MASK_EXACT, NULL);
5404 caps = gst_caps_simplify (caps);
5411 * Some AAC specific code... *sigh*
5412 * FIXME: maybe we should use '15' and code the sample rate explicitly
5413 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5417 aac_rate_idx (gint rate)
5421 else if (75132 <= rate)
5423 else if (55426 <= rate)
5425 else if (46009 <= rate)
5427 else if (37566 <= rate)
5429 else if (27713 <= rate)
5431 else if (23004 <= rate)
5433 else if (18783 <= rate)
5435 else if (13856 <= rate)
5437 else if (11502 <= rate)
5439 else if (9391 <= rate)
5446 aac_profile_idx (const gchar * codec_id)
5450 if (strlen (codec_id) <= 12)
5452 else if (!strncmp (&codec_id[12], "MAIN", 4))
5454 else if (!strncmp (&codec_id[12], "LC", 2))
5456 else if (!strncmp (&codec_id[12], "SSR", 3))
5465 round_up_pow2 (guint n)
5476 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5479 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5480 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5481 gchar ** codec_name, guint16 * riff_audio_fmt)
5483 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5484 GstCaps *caps = NULL;
5486 g_assert (audiocontext != NULL);
5487 g_assert (codec_name != NULL);
5490 *riff_audio_fmt = 0;
5492 /* TODO: check if we have all codec types from matroska-ids.h
5493 * check if we have to do more special things with codec_private
5494 * check if we need bitdepth in different places too
5495 * implement channel position magic
5497 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5498 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5499 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5500 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5503 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5504 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5505 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5508 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5510 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5515 caps = gst_caps_new_simple ("audio/mpeg",
5516 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5517 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5518 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5519 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5522 GstAudioFormat format;
5524 sign = (audiocontext->bitdepth != 8);
5525 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5526 endianness = G_BIG_ENDIAN;
5528 endianness = G_LITTLE_ENDIAN;
5530 format = gst_audio_format_build_integer (sign, endianness,
5531 audiocontext->bitdepth, audiocontext->bitdepth);
5533 /* FIXME: Channel mask and reordering */
5534 caps = gst_caps_new_simple ("audio/x-raw",
5535 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5536 "layout", G_TYPE_STRING, "interleaved",
5537 "channel-mask", GST_TYPE_BITMASK,
5538 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5540 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5541 audiocontext->bitdepth);
5542 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5543 context->alignment = round_up_pow2 (context->alignment);
5544 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5545 const gchar *format;
5546 if (audiocontext->bitdepth == 32)
5550 /* FIXME: Channel mask and reordering */
5551 caps = gst_caps_new_simple ("audio/x-raw",
5552 "format", G_TYPE_STRING, format,
5553 "layout", G_TYPE_STRING, "interleaved",
5554 "channel-mask", GST_TYPE_BITMASK,
5555 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5556 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5557 audiocontext->bitdepth);
5558 context->alignment = audiocontext->bitdepth / 8;
5559 context->alignment = round_up_pow2 (context->alignment);
5560 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5561 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5562 caps = gst_caps_new_simple ("audio/x-ac3",
5563 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5564 *codec_name = g_strdup ("AC-3 audio");
5565 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5566 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5567 caps = gst_caps_new_simple ("audio/x-eac3",
5568 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5569 *codec_name = g_strdup ("E-AC-3 audio");
5570 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5571 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5572 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5573 *codec_name = g_strdup ("Dolby TrueHD");
5574 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5575 caps = gst_caps_new_empty_simple ("audio/x-dts");
5576 *codec_name = g_strdup ("DTS audio");
5577 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5578 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5579 context->stream_headers =
5580 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5581 context->codec_priv_size);
5582 /* FIXME: mark stream as broken and skip if there are no stream headers */
5583 context->send_stream_headers = TRUE;
5584 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5585 caps = gst_caps_new_empty_simple ("audio/x-flac");
5586 context->stream_headers =
5587 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5588 context->codec_priv_size);
5589 /* FIXME: mark stream as broken and skip if there are no stream headers */
5590 context->send_stream_headers = TRUE;
5591 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5592 caps = gst_caps_new_empty_simple ("audio/x-speex");
5593 context->stream_headers =
5594 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5595 context->codec_priv_size);
5596 /* FIXME: mark stream as broken and skip if there are no stream headers */
5597 context->send_stream_headers = TRUE;
5598 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5601 if (context->codec_priv_size >= 19) {
5602 if (audiocontext->samplerate)
5603 GST_WRITE_UINT32_LE ((guint8 *) context->codec_priv + 12,
5604 audiocontext->samplerate);
5605 if (context->codec_delay) {
5607 gst_util_uint64_scale_round (context->codec_delay, 48000,
5609 GST_WRITE_UINT16_LE ((guint8 *) context->codec_priv + 10, delay);
5613 gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5614 context->codec_priv_size), context->codec_priv_size);
5615 caps = gst_codec_utils_opus_create_caps_from_header (tmp, NULL);
5616 gst_buffer_unref (tmp);
5617 *codec_name = g_strdup ("Opus");
5618 } else if (context->codec_priv_size == 0) {
5619 GST_WARNING ("No Opus codec data found, trying to create one");
5620 if (audiocontext->channels >= 0 && audiocontext->channels <= 2) {
5621 guint8 streams, coupled, channels;
5625 audiocontext->samplerate == 0 ? 48000 : audiocontext->samplerate;
5626 channels = audiocontext->channels == 0 ? 2 : audiocontext->channels;
5627 if (channels == 1) {
5636 gst_codec_utils_opus_create_caps (samplerate, channels, 0, streams,
5639 *codec_name = g_strdup ("Opus");
5641 GST_WARNING ("Failed to create Opus caps from audio context");
5644 GST_WARNING ("No Opus codec data, and not enough info to create one");
5647 GST_WARNING ("Invalid Opus codec data size (got %" G_GSIZE_FORMAT
5648 ", expected 19)", context->codec_priv_size);
5650 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5651 gst_riff_strf_auds auds;
5653 if (data && size >= 18) {
5654 GstBuffer *codec_data = NULL;
5656 /* little-endian -> byte-order */
5657 auds.format = GST_READ_UINT16_LE (data);
5658 auds.channels = GST_READ_UINT16_LE (data + 2);
5659 auds.rate = GST_READ_UINT32_LE (data + 4);
5660 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5661 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5662 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5664 /* 18 is the waveformatex size */
5666 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5667 data + 18, size - 18, 0, size - 18, NULL, NULL);
5671 *riff_audio_fmt = auds.format;
5673 /* FIXME: Handle reorder map */
5674 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5675 codec_data, codec_name, NULL);
5677 gst_buffer_unref (codec_data);
5680 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5683 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5685 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5686 GstBuffer *priv = NULL;
5688 gint rate_idx, profile;
5689 guint8 *data = NULL;
5691 /* unspecified AAC profile with opaque private codec data */
5692 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5693 if (context->codec_priv_size >= 2) {
5694 guint obj_type, freq_index, explicit_freq_bytes = 0;
5696 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5698 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5699 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5700 if (freq_index == 15)
5701 explicit_freq_bytes = 3;
5702 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5703 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5704 context->codec_priv_size), context->codec_priv_size);
5705 /* assume SBR if samplerate <= 24kHz */
5706 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5707 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5708 audiocontext->samplerate *= 2;
5711 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5712 /* this is pretty broken;
5713 * maybe we need to make up some default private,
5714 * or maybe ADTS data got dumped in.
5715 * Let's set up some private data now, and check actual data later */
5716 /* just try this and see what happens ... */
5717 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5718 context->postprocess_frame = gst_matroska_demux_check_aac;
5722 /* make up decoder-specific data if it is not supplied */
5726 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5727 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5729 rate_idx = aac_rate_idx (audiocontext->samplerate);
5730 profile = aac_profile_idx (codec_id);
5732 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5733 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5735 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5736 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5738 gst_buffer_unmap (priv, &map);
5739 gst_buffer_set_size (priv, 2);
5740 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5741 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5744 if (g_strrstr (codec_id, "SBR")) {
5745 /* HE-AAC (aka SBR AAC) */
5746 audiocontext->samplerate *= 2;
5747 rate_idx = aac_rate_idx (audiocontext->samplerate);
5748 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5749 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5750 data[4] = (1 << 7) | (rate_idx << 3);
5751 gst_buffer_unmap (priv, &map);
5753 gst_buffer_unmap (priv, &map);
5754 gst_buffer_set_size (priv, 2);
5757 gst_buffer_unmap (priv, &map);
5758 gst_buffer_unref (priv);
5760 GST_ERROR ("Unknown AAC profile and no codec private data");
5765 caps = gst_caps_new_simple ("audio/mpeg",
5766 "mpegversion", G_TYPE_INT, mpegversion,
5767 "framed", G_TYPE_BOOLEAN, TRUE,
5768 "stream-format", G_TYPE_STRING, "raw", NULL);
5769 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5770 if (context->codec_priv && context->codec_priv_size > 0)
5771 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5772 context->codec_priv, context->codec_priv_size);
5773 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5774 gst_buffer_unref (priv);
5776 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5777 caps = gst_caps_new_simple ("audio/x-tta",
5778 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5779 *codec_name = g_strdup ("TTA audio");
5780 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5781 caps = gst_caps_new_simple ("audio/x-wavpack",
5782 "width", G_TYPE_INT, audiocontext->bitdepth,
5783 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5784 *codec_name = g_strdup ("Wavpack audio");
5785 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5786 audiocontext->wvpk_block_index = 0;
5787 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5788 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5789 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5790 gint raversion = -1;
5792 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5794 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5799 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5800 "raversion", G_TYPE_INT, raversion, NULL);
5801 /* Extract extra information from caps, mapping varies based on codec */
5802 if (data && (size >= 0x50)) {
5809 guint extra_data_size;
5811 GST_ERROR ("real audio raversion:%d", raversion);
5812 if (raversion == 8) {
5814 flavor = GST_READ_UINT16_BE (data + 22);
5815 packet_size = GST_READ_UINT32_BE (data + 24);
5816 height = GST_READ_UINT16_BE (data + 40);
5817 leaf_size = GST_READ_UINT16_BE (data + 44);
5818 sample_width = GST_READ_UINT16_BE (data + 58);
5819 extra_data_size = GST_READ_UINT32_BE (data + 74);
5822 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5823 flavor, packet_size, height, leaf_size, sample_width,
5825 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5826 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5827 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5829 if ((size - 78) >= extra_data_size) {
5830 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5832 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5833 gst_buffer_unref (priv);
5838 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5839 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5840 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5841 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5842 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5843 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5844 *codec_name = g_strdup ("Real Audio Lossless");
5845 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5846 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5847 *codec_name = g_strdup ("Sony ATRAC3");
5849 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5854 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5857 for (i = 0; i < gst_caps_get_size (caps); i++) {
5858 gst_structure_set (gst_caps_get_structure (caps, i),
5859 "channels", G_TYPE_INT, audiocontext->channels,
5860 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5864 caps = gst_caps_simplify (caps);
5871 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5872 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5874 GstCaps *caps = NULL;
5875 GstMatroskaTrackContext *context =
5876 (GstMatroskaTrackContext *) subtitlecontext;
5878 /* for backwards compatibility */
5879 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5880 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5881 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5882 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5883 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5884 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5885 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5886 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5888 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5889 * Check if we have to do something with codec_private */
5890 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5891 /* well, plain text simply does not have a lot of markup ... */
5892 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5893 "pango-markup", NULL);
5894 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5895 subtitlecontext->check_markup = TRUE;
5896 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5897 caps = gst_caps_new_empty_simple ("application/x-ssa");
5898 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5899 subtitlecontext->check_markup = FALSE;
5900 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5901 caps = gst_caps_new_empty_simple ("application/x-ass");
5902 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5903 subtitlecontext->check_markup = FALSE;
5904 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5905 caps = gst_caps_new_empty_simple ("application/x-usf");
5906 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5907 subtitlecontext->check_markup = FALSE;
5908 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5909 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5910 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5911 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5912 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5913 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5914 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5915 context->stream_headers =
5916 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5917 context->codec_priv_size);
5918 /* FIXME: mark stream as broken and skip if there are no stream headers */
5919 context->send_stream_headers = TRUE;
5921 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5922 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5925 if (data != NULL && size > 0) {
5928 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5929 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5930 gst_buffer_unref (buf);
5938 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5940 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5942 GST_OBJECT_LOCK (demux);
5943 if (demux->common.element_index)
5944 gst_object_unref (demux->common.element_index);
5945 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5946 GST_OBJECT_UNLOCK (demux);
5947 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5948 demux->common.element_index);
5952 gst_matroska_demux_get_index (GstElement * element)
5954 GstIndex *result = NULL;
5955 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5957 GST_OBJECT_LOCK (demux);
5958 if (demux->common.element_index)
5959 result = gst_object_ref (demux->common.element_index);
5960 GST_OBJECT_UNLOCK (demux);
5962 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5968 static GstStateChangeReturn
5969 gst_matroska_demux_change_state (GstElement * element,
5970 GstStateChange transition)
5972 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5973 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5975 /* handle upwards state changes here */
5976 switch (transition) {
5981 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5983 /* handle downwards state changes */
5984 switch (transition) {
5985 case GST_STATE_CHANGE_PAUSED_TO_READY:
5986 gst_matroska_demux_reset (GST_ELEMENT (demux));
5996 gst_matroska_demux_set_property (GObject * object,
5997 guint prop_id, const GValue * value, GParamSpec * pspec)
5999 GstMatroskaDemux *demux;
6001 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6002 demux = GST_MATROSKA_DEMUX (object);
6005 case PROP_MAX_GAP_TIME:
6006 GST_OBJECT_LOCK (demux);
6007 demux->max_gap_time = g_value_get_uint64 (value);
6008 GST_OBJECT_UNLOCK (demux);
6011 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6017 gst_matroska_demux_get_property (GObject * object,
6018 guint prop_id, GValue * value, GParamSpec * pspec)
6020 GstMatroskaDemux *demux;
6022 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6023 demux = GST_MATROSKA_DEMUX (object);
6026 case PROP_MAX_GAP_TIME:
6027 GST_OBJECT_LOCK (demux);
6028 g_value_set_uint64 (value, demux->max_gap_time);
6029 GST_OBJECT_UNLOCK (demux);
6032 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6038 gst_matroska_demux_plugin_init (GstPlugin * plugin)
6042 /* parser helper separate debug */
6043 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
6044 0, "EBML stream helper class");
6046 /* create an elementfactory for the matroska_demux element */
6047 if (!gst_element_register (plugin, "matroskademux",
6048 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))