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");
2348 if (!demux->streaming)
2349 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2351 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2352 gst_event_unref (event);
2357 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2358 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2359 GstMatroskaTrackVideoContext *videocontext =
2360 (GstMatroskaTrackVideoContext *) context;
2362 GstClockTimeDiff diff;
2363 GstClockTime timestamp;
2365 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2367 GST_OBJECT_LOCK (demux);
2368 videocontext->earliest_time = timestamp + diff;
2369 GST_OBJECT_UNLOCK (demux);
2372 gst_event_unref (event);
2376 case GST_EVENT_TOC_SELECT:
2379 GstTocEntry *entry = NULL;
2380 GstEvent *seek_event;
2383 if (!demux->common.toc) {
2384 GST_DEBUG_OBJECT (demux, "no TOC to select");
2387 gst_event_parse_toc_select (event, &uid);
2389 GST_OBJECT_LOCK (demux);
2390 entry = gst_toc_find_entry (demux->common.toc, uid);
2391 if (entry == NULL) {
2392 GST_OBJECT_UNLOCK (demux);
2393 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2396 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2397 GST_OBJECT_UNLOCK (demux);
2398 seek_event = gst_event_new_seek (1.0,
2400 GST_SEEK_FLAG_FLUSH,
2401 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2402 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2403 gst_event_unref (seek_event);
2407 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2411 gst_event_unref (event);
2415 /* events we don't need to handle */
2416 case GST_EVENT_NAVIGATION:
2417 gst_event_unref (event);
2421 case GST_EVENT_LATENCY:
2423 res = gst_pad_push_event (demux->common.sinkpad, event);
2430 static GstFlowReturn
2431 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2433 GstFlowReturn ret = GST_FLOW_EOS;
2434 gboolean done = TRUE;
2437 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2438 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2441 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2443 if (!demux->seek_entry) {
2444 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2448 for (i = 0; i < demux->common.src->len; i++) {
2449 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2451 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2452 ", stream %d at %" GST_TIME_FORMAT,
2453 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2454 GST_TIME_ARGS (stream->from_time));
2455 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2456 if (stream->from_time > demux->common.segment.start) {
2457 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2461 /* nothing pushed for this stream;
2462 * likely seek entry did not start at keyframe, so all was skipped.
2463 * So we need an earlier entry */
2469 GstMatroskaIndex *entry;
2471 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2472 --demux->seek_entry);
2473 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2483 static GstFlowReturn
2484 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2486 GstFlowReturn ret = GST_FLOW_OK;
2489 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2491 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2492 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2496 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2497 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2501 /* one track within the "all-tracks" header */
2502 case GST_MATROSKA_ID_TRACKENTRY:
2503 ret = gst_matroska_demux_add_stream (demux, ebml);
2507 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2512 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2514 demux->tracks_parsed = TRUE;
2520 * Read signed/unsigned "EBML" numbers.
2521 * Return: number of bytes processed.
2525 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2527 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2535 while (read <= 8 && !(total & len_mask)) {
2542 if ((total &= (len_mask - 1)) == len_mask - 1)
2547 if (data[n] == 0xff)
2549 total = (total << 8) | data[n];
2553 if (read == num_ffs && total != 0)
2562 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2567 /* read as unsigned number first */
2568 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2572 if (unum == G_MAXUINT64)
2575 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2581 * Mostly used for subtitles. We add void filler data for each
2582 * lagging stream to make sure we don't deadlock.
2586 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2588 GstClockTime gap_threshold;
2591 GST_OBJECT_LOCK (demux);
2593 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2594 GST_TIME_ARGS (demux->common.segment.position));
2596 g_assert (demux->common.num_streams == demux->common.src->len);
2597 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2598 GstMatroskaTrackContext *context;
2600 context = g_ptr_array_index (demux->common.src, stream_nr);
2602 GST_LOG_OBJECT (demux,
2603 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2604 GST_TIME_ARGS (context->pos));
2606 /* Only send gap events on non-subtitle streams if lagging way behind.
2607 * The 0.5 second threshold for subtitle streams is also quite random. */
2608 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
2609 gap_threshold = GST_SECOND / 2;
2611 gap_threshold = 3 * GST_SECOND;
2613 /* Lag need only be considered if we have advanced into requested segment */
2614 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2615 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2616 demux->common.segment.position > demux->common.segment.start &&
2617 context->pos + gap_threshold < demux->common.segment.position) {
2620 guint64 start = context->pos;
2621 guint64 stop = demux->common.segment.position - gap_threshold;
2623 GST_DEBUG_OBJECT (demux,
2624 "Synchronizing stream %d with other by advancing time from %"
2625 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2626 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2628 context->pos = stop;
2630 event = gst_event_new_gap (start, stop - start);
2631 GST_OBJECT_UNLOCK (demux);
2632 gst_pad_push_event (context->pad, event);
2633 GST_OBJECT_LOCK (demux);
2637 GST_OBJECT_UNLOCK (demux);
2640 static GstFlowReturn
2641 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2642 GstMatroskaTrackContext * stream)
2644 GstFlowReturn ret = GST_FLOW_OK;
2647 num = gst_buffer_list_length (stream->stream_headers);
2648 for (i = 0; i < num; ++i) {
2651 buf = gst_buffer_list_get (stream->stream_headers, i);
2652 buf = gst_buffer_copy (buf);
2654 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2656 if (stream->set_discont) {
2657 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2658 stream->set_discont = FALSE;
2660 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2663 /* push out all headers in one go and use last flow return */
2664 ret = gst_pad_push (stream->pad, buf);
2667 /* don't need these any longer */
2668 gst_buffer_list_unref (stream->stream_headers);
2669 stream->stream_headers = NULL;
2672 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2678 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2679 GstMatroskaTrackContext * stream)
2683 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2685 if (!stream->codec_priv)
2688 /* ideally, VobSub private data should be parsed and stored more convenient
2689 * elsewhere, but for now, only interested in a small part */
2691 /* make sure we have terminating 0 */
2692 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2694 /* just locate and parse palette part */
2695 start = strstr (buf, "palette:");
2700 guint8 r, g, b, y, u, v;
2703 while (g_ascii_isspace (*start))
2705 for (i = 0; i < 16; i++) {
2706 if (sscanf (start, "%06x", &col) != 1)
2709 while ((*start == ',') || g_ascii_isspace (*start))
2711 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2712 r = (col >> 16) & 0xff;
2713 g = (col >> 8) & 0xff;
2715 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2717 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2718 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2719 clut[i] = (y << 16) | (u << 8) | v;
2722 /* got them all without problems; build and send event */
2726 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2727 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2728 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2729 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2730 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2731 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2732 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2733 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2734 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2735 G_TYPE_INT, clut[15], NULL);
2737 gst_pad_push_event (stream->pad,
2738 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2745 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2749 GST_OBJECT_LOCK (demux);
2751 g_assert (demux->common.num_streams == demux->common.src->len);
2752 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2753 GstMatroskaTrackContext *stream;
2755 stream = g_ptr_array_index (demux->common.src, stream_nr);
2757 if (stream->send_stream_headers) {
2758 if (stream->stream_headers != NULL) {
2759 gst_matroska_demux_push_stream_headers (demux, stream);
2761 /* FIXME: perhaps we can just disable and skip this stream then */
2762 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2763 ("Failed to extract stream headers from codec private data"));
2765 stream->send_stream_headers = FALSE;
2768 if (stream->send_dvd_event) {
2769 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2770 /* FIXME: should we send this event again after (flushing) seek ? */
2771 stream->send_dvd_event = FALSE;
2775 GST_OBJECT_UNLOCK (demux);
2778 static GstFlowReturn
2779 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2780 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2783 guint seq_header_len;
2784 guint32 header, tmp;
2786 if (stream->codec_state) {
2787 seq_header = stream->codec_state;
2788 seq_header_len = stream->codec_state_size;
2789 } else if (stream->codec_priv) {
2790 seq_header = stream->codec_priv;
2791 seq_header_len = stream->codec_priv_size;
2796 /* Sequence header only needed for keyframes */
2797 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2800 if (gst_buffer_get_size (*buf) < 4)
2803 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2804 header = GUINT32_FROM_BE (tmp);
2806 /* Sequence start code, if not found prepend */
2807 if (header != 0x000001b3) {
2810 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2812 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2815 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2816 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2817 gst_buffer_get_size (*buf));
2819 gst_buffer_unref (*buf);
2826 static GstFlowReturn
2827 gst_matroska_demux_add_wvpk_header (GstElement * element,
2828 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2830 GstMatroskaTrackAudioContext *audiocontext =
2831 (GstMatroskaTrackAudioContext *) stream;
2832 GstBuffer *newbuf = NULL;
2833 GstMapInfo map, outmap;
2834 guint8 *buf_data, *data;
2842 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2845 wvh.total_samples = -1;
2846 wvh.block_index = audiocontext->wvpk_block_index;
2848 if (audiocontext->channels <= 2) {
2849 guint32 block_samples, tmp;
2850 gsize size = gst_buffer_get_size (*buf);
2852 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2853 block_samples = GUINT32_FROM_LE (tmp);
2854 /* we need to reconstruct the header of the wavpack block */
2856 /* -20 because ck_size is the size of the wavpack block -8
2857 * and lace_size is the size of the wavpack block + 12
2858 * (the three guint32 of the header that already are in the buffer) */
2859 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2861 /* block_samples, flags and crc are already in the buffer */
2862 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2864 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2870 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2871 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2872 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2873 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2874 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2875 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2876 gst_buffer_unmap (newbuf, &outmap);
2878 /* Append data from buf: */
2879 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2880 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2882 gst_buffer_unref (*buf);
2884 audiocontext->wvpk_block_index += block_samples;
2886 guint8 *outdata = NULL;
2888 gsize buf_size, size, out_size = 0;
2889 guint32 block_samples, flags, crc, blocksize;
2891 gst_buffer_map (*buf, &map, GST_MAP_READ);
2892 buf_data = map.data;
2893 buf_size = map.size;
2896 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2897 gst_buffer_unmap (*buf, &map);
2898 return GST_FLOW_ERROR;
2904 block_samples = GST_READ_UINT32_LE (data);
2909 flags = GST_READ_UINT32_LE (data);
2912 crc = GST_READ_UINT32_LE (data);
2915 blocksize = GST_READ_UINT32_LE (data);
2919 if (blocksize == 0 || size < blocksize)
2922 g_assert ((newbuf == NULL) == (outdata == NULL));
2924 if (newbuf == NULL) {
2925 out_size = sizeof (Wavpack4Header) + blocksize;
2926 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2928 gst_buffer_copy_into (newbuf, *buf,
2929 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2932 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2933 outdata = outmap.data;
2935 gst_buffer_unmap (newbuf, &outmap);
2936 out_size += sizeof (Wavpack4Header) + blocksize;
2937 gst_buffer_set_size (newbuf, out_size);
2938 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2939 outdata = outmap.data;
2942 outdata[outpos] = 'w';
2943 outdata[outpos + 1] = 'v';
2944 outdata[outpos + 2] = 'p';
2945 outdata[outpos + 3] = 'k';
2948 GST_WRITE_UINT32_LE (outdata + outpos,
2949 blocksize + sizeof (Wavpack4Header) - 8);
2950 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2951 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2952 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2953 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2954 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2955 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2956 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2957 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2960 memmove (outdata + outpos, data, blocksize);
2961 outpos += blocksize;
2965 gst_buffer_unmap (*buf, &map);
2966 gst_buffer_unref (*buf);
2969 gst_buffer_unmap (newbuf, &outmap);
2972 audiocontext->wvpk_block_index += block_samples;
2978 static GstFlowReturn
2979 gst_matroska_demux_add_prores_header (GstElement * element,
2980 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2982 GstBuffer *newbuf = gst_buffer_new_allocate (NULL, 8, NULL);
2986 if (!gst_buffer_map (newbuf, &map, GST_MAP_WRITE)) {
2987 GST_ERROR ("Failed to map newly allocated buffer");
2988 return GST_FLOW_ERROR;
2991 frame_size = gst_buffer_get_size (*buf);
2993 GST_WRITE_UINT32_BE (map.data, frame_size);
2999 gst_buffer_unmap (newbuf, &map);
3000 *buf = gst_buffer_append (newbuf, *buf);
3005 /* @text must be null-terminated */
3007 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
3012 g_return_val_if_fail (text != NULL, FALSE);
3014 /* yes, this might all lead to false positives ... */
3015 tag = (gchar *) text;
3016 while ((tag = strchr (tag, '<'))) {
3018 if (*tag != '\0' && *(tag + 1) == '>') {
3019 /* some common convenience ones */
3020 /* maybe any character will do here ? */
3033 if (strstr (text, "<span"))
3039 static GstFlowReturn
3040 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
3041 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3043 GstMatroskaTrackSubtitleContext *sub_stream;
3044 const gchar *encoding;
3049 gboolean needs_unmap = TRUE;
3051 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3053 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
3056 /* The subtitle buffer we push out should not include a NUL terminator as
3057 * part of the data. */
3058 if (map.data[map.size - 1] == '\0') {
3059 gst_buffer_set_size (*buf, map.size - 1);
3060 gst_buffer_unmap (*buf, &map);
3061 gst_buffer_map (*buf, &map, GST_MAP_READ);
3064 if (!sub_stream->invalid_utf8) {
3065 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
3068 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
3069 " is not valid UTF-8, this is broken according to the matroska"
3070 " specification", stream->num);
3071 sub_stream->invalid_utf8 = TRUE;
3074 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3075 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3076 if (encoding == NULL || *encoding == '\0') {
3077 /* if local encoding is UTF-8 and no encoding specified
3078 * via the environment variable, assume ISO-8859-15 */
3079 if (g_get_charset (&encoding)) {
3080 encoding = "ISO-8859-15";
3085 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3086 (char *) "*", NULL, NULL, &err);
3089 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3090 encoding, err->message);
3094 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3095 encoding = "ISO-8859-15";
3097 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3098 encoding, (char *) "*", NULL, NULL, NULL);
3101 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3102 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3105 utf8 = g_strdup ("invalid subtitle");
3107 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3108 gst_buffer_unmap (*buf, &map);
3109 gst_buffer_copy_into (newbuf, *buf,
3110 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3112 gst_buffer_unref (*buf);
3115 gst_buffer_map (*buf, &map, GST_MAP_READ);
3119 if (sub_stream->check_markup) {
3120 /* caps claim markup text, so we need to escape text,
3121 * except if text is already markup and then needs no further escaping */
3122 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3123 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3125 if (!sub_stream->seen_markup_tag) {
3126 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3128 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3129 gst_buffer_unmap (*buf, &map);
3130 gst_buffer_copy_into (newbuf, *buf,
3131 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3132 GST_BUFFER_COPY_META, 0, -1);
3133 gst_buffer_unref (*buf);
3136 needs_unmap = FALSE;
3141 gst_buffer_unmap (*buf, &map);
3146 static GstFlowReturn
3147 gst_matroska_demux_check_aac (GstElement * element,
3148 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3153 gst_buffer_extract (*buf, 0, data, 2);
3154 size = gst_buffer_get_size (*buf);
3156 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3159 /* tss, ADTS data, remove codec_data
3160 * still assume it is at least parsed */
3161 stream->caps = gst_caps_make_writable (stream->caps);
3162 s = gst_caps_get_structure (stream->caps, 0);
3164 gst_structure_remove_field (s, "codec_data");
3165 gst_pad_set_caps (stream->pad, stream->caps);
3166 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3167 "new caps: %" GST_PTR_FORMAT, stream->caps);
3170 /* disable subsequent checking */
3171 stream->postprocess_frame = NULL;
3177 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3178 GstBuffer * buffer, gsize alignment)
3182 gst_buffer_map (buffer, &map, GST_MAP_READ);
3184 if (map.size < sizeof (guintptr)) {
3185 gst_buffer_unmap (buffer, &map);
3189 if (((guintptr) map.data) & (alignment - 1)) {
3190 GstBuffer *new_buffer;
3191 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3193 new_buffer = gst_buffer_new_allocate (NULL,
3194 gst_buffer_get_size (buffer), ¶ms);
3196 /* Copy data "by hand", so ensure alignment is kept: */
3197 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3199 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3200 GST_DEBUG_OBJECT (demux,
3201 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3204 gst_buffer_unmap (buffer, &map);
3205 gst_buffer_unref (buffer);
3210 gst_buffer_unmap (buffer, &map);
3214 static GstFlowReturn
3215 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3216 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3217 gboolean is_simpleblock)
3219 GstMatroskaTrackContext *stream = NULL;
3220 GstFlowReturn ret = GST_FLOW_OK;
3221 gboolean readblock = FALSE;
3223 guint64 block_duration = -1;
3224 gint64 block_discardpadding = 0;
3225 GstBuffer *buf = NULL;
3227 gint stream_num = -1, n, laces = 0;
3229 gint *lace_size = NULL;
3232 gint64 referenceblock = 0;
3234 GstClockTime buffer_timestamp;
3236 offset = gst_ebml_read_get_offset (ebml);
3238 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3239 if (!is_simpleblock) {
3240 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3244 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3248 /* one block inside the group. Note, block parsing is one
3249 * of the harder things, so this code is a bit complicated.
3250 * See http://www.matroska.org/ for documentation. */
3251 case GST_MATROSKA_ID_SIMPLEBLOCK:
3252 case GST_MATROSKA_ID_BLOCK:
3258 gst_buffer_unmap (buf, &map);
3259 gst_buffer_unref (buf);
3262 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3265 gst_buffer_map (buf, &map, GST_MAP_READ);
3269 /* first byte(s): blocknum */
3270 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3275 /* fetch stream from num */
3276 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3278 if (G_UNLIKELY (size < 3)) {
3279 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3280 /* non-fatal, try next block(group) */
3283 } else if (G_UNLIKELY (stream_num < 0 ||
3284 stream_num >= demux->common.num_streams)) {
3285 /* let's not give up on a stray invalid track number */
3286 GST_WARNING_OBJECT (demux,
3287 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3288 "; ignoring block", stream_num, num);
3292 stream = g_ptr_array_index (demux->common.src, stream_num);
3294 /* time (relative to cluster time) */
3295 time = ((gint16) GST_READ_UINT16_BE (data));
3298 flags = GST_READ_UINT8 (data);
3302 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3305 switch ((flags & 0x06) >> 1) {
3306 case 0x0: /* no lacing */
3308 lace_size = g_new (gint, 1);
3309 lace_size[0] = size;
3312 case 0x1: /* xiph lacing */
3313 case 0x2: /* fixed-size lacing */
3314 case 0x3: /* EBML lacing */
3316 goto invalid_lacing;
3317 laces = GST_READ_UINT8 (data) + 1;
3320 lace_size = g_new0 (gint, laces);
3322 switch ((flags & 0x06) >> 1) {
3323 case 0x1: /* xiph lacing */ {
3324 guint temp, total = 0;
3326 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3329 goto invalid_lacing;
3330 temp = GST_READ_UINT8 (data);
3331 lace_size[n] += temp;
3337 total += lace_size[n];
3339 lace_size[n] = size - total;
3343 case 0x2: /* fixed-size lacing */
3344 for (n = 0; n < laces; n++)
3345 lace_size[n] = size / laces;
3348 case 0x3: /* EBML lacing */ {
3351 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3355 total = lace_size[0] = num;
3356 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3360 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3364 lace_size[n] = lace_size[n - 1] + snum;
3365 total += lace_size[n];
3368 lace_size[n] = size - total;
3375 if (ret != GST_FLOW_OK)
3382 case GST_MATROSKA_ID_BLOCKDURATION:{
3383 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3384 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3389 case GST_MATROSKA_ID_DISCARDPADDING:{
3390 ret = gst_ebml_read_sint (ebml, &id, &block_discardpadding);
3391 GST_DEBUG_OBJECT (demux, "DiscardPadding: %" GST_STIME_FORMAT,
3392 GST_STIME_ARGS (block_discardpadding));
3396 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3397 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3398 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3403 case GST_MATROSKA_ID_CODECSTATE:{
3405 guint64 data_len = 0;
3408 gst_ebml_read_binary (ebml, &id, &data,
3409 &data_len)) != GST_FLOW_OK)
3412 if (G_UNLIKELY (stream == NULL)) {
3413 GST_WARNING_OBJECT (demux,
3414 "Unexpected CodecState subelement - ignoring");
3418 g_free (stream->codec_state);
3419 stream->codec_state = data;
3420 stream->codec_state_size = data_len;
3422 /* Decode if necessary */
3423 if (stream->encodings && stream->encodings->len > 0
3424 && stream->codec_state && stream->codec_state_size > 0) {
3425 if (!gst_matroska_decode_data (stream->encodings,
3426 &stream->codec_state, &stream->codec_state_size,
3427 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3428 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3432 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3433 stream->codec_state_size);
3438 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3442 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3443 case GST_MATROSKA_ID_BLOCKADDITIONS:
3444 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3445 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3446 case GST_MATROSKA_ID_SLICES:
3447 GST_DEBUG_OBJECT (demux,
3448 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3449 ret = gst_ebml_read_skip (ebml);
3457 /* reading a number or so could have failed */
3458 if (ret != GST_FLOW_OK)
3461 if (ret == GST_FLOW_OK && readblock) {
3462 gboolean invisible_frame = FALSE;
3463 gboolean delta_unit = FALSE;
3464 guint64 duration = 0;
3465 gint64 lace_time = 0;
3467 stream = g_ptr_array_index (demux->common.src, stream_num);
3469 if (cluster_time != GST_CLOCK_TIME_NONE) {
3470 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3471 * Drop unless the lace contains timestamp 0? */
3472 if (time < 0 && (-time) > cluster_time) {
3475 if (stream->timecodescale == 1.0)
3476 lace_time = (cluster_time + time) * demux->common.time_scale;
3479 gst_util_guint64_to_gdouble ((cluster_time + time) *
3480 demux->common.time_scale) * stream->timecodescale;
3483 lace_time = GST_CLOCK_TIME_NONE;
3486 /* need to refresh segment info ASAP */
3487 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3488 GstSegment *segment = &demux->common.segment;
3490 GstEvent *segment_event;
3492 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3493 demux->stream_start_time = lace_time;
3494 GST_DEBUG_OBJECT (demux,
3495 "Setting stream start time to %" GST_TIME_FORMAT,
3496 GST_TIME_ARGS (lace_time));
3498 clace_time = MAX (lace_time, demux->stream_start_time);
3499 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3500 demux->common.segment.position != 0) {
3501 GST_DEBUG_OBJECT (demux,
3502 "using stored seek position %" GST_TIME_FORMAT,
3503 GST_TIME_ARGS (demux->common.segment.position));
3504 clace_time = demux->common.segment.position + demux->stream_start_time;
3505 segment->position = GST_CLOCK_TIME_NONE;
3507 segment->start = clace_time;
3508 segment->stop = GST_CLOCK_TIME_NONE;
3509 segment->time = segment->start - demux->stream_start_time;
3510 segment->position = segment->start - demux->stream_start_time;
3511 GST_DEBUG_OBJECT (demux,
3512 "generated segment starting at %" GST_TIME_FORMAT ": %"
3513 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3514 /* now convey our segment notion downstream */
3515 segment_event = gst_event_new_segment (segment);
3516 if (demux->segment_seqnum)
3517 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3518 gst_matroska_demux_send_event (demux, segment_event);
3519 demux->need_segment = FALSE;
3520 demux->segment_seqnum = 0;
3523 /* send pending codec data headers for all streams,
3524 * before we perform sync across all streams */
3525 gst_matroska_demux_push_codec_data_all (demux);
3527 if (block_duration != -1) {
3528 if (stream->timecodescale == 1.0)
3529 duration = gst_util_uint64_scale (block_duration,
3530 demux->common.time_scale, 1);
3533 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3534 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3535 1)) * stream->timecodescale);
3536 } else if (stream->default_duration) {
3537 duration = stream->default_duration * laces;
3539 /* else duration is diff between timecode of this and next block */
3541 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3542 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3543 a ReferenceBlock implies that this is not a keyframe. In either
3544 case, it only makes sense for video streams. */
3545 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3547 invisible_frame = ((flags & 0x08)) &&
3548 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3549 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3552 /* If we're doing a keyframe-only trickmode, only push keyframes on video
3556 segment.flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) {
3557 GST_LOG_OBJECT (demux, "Skipping non-keyframe on stream %d",
3564 for (n = 0; n < laces; n++) {
3567 if (G_UNLIKELY (lace_size[n] > size)) {
3568 GST_WARNING_OBJECT (demux, "Invalid lace size");
3572 /* QoS for video track with an index. the assumption is that
3573 index entries point to keyframes, but if that is not true we
3574 will instad skip until the next keyframe. */
3575 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3576 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3577 stream->index_table && demux->common.segment.rate > 0.0) {
3578 GstMatroskaTrackVideoContext *videocontext =
3579 (GstMatroskaTrackVideoContext *) stream;
3580 GstClockTime earliest_time;
3581 GstClockTime earliest_stream_time;
3583 GST_OBJECT_LOCK (demux);
3584 earliest_time = videocontext->earliest_time;
3585 GST_OBJECT_UNLOCK (demux);
3586 earliest_stream_time =
3587 gst_segment_position_from_running_time (&demux->common.segment,
3588 GST_FORMAT_TIME, earliest_time);
3590 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3591 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3592 lace_time <= earliest_stream_time) {
3593 /* find index entry (keyframe) <= earliest_stream_time */
3594 GstMatroskaIndex *entry =
3595 gst_util_array_binary_search (stream->index_table->data,
3596 stream->index_table->len, sizeof (GstMatroskaIndex),
3597 (GCompareDataFunc) gst_matroska_index_seek_find,
3598 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3600 /* if that entry (keyframe) is after the current the current
3601 buffer, we can skip pushing (and thus decoding) all
3602 buffers until that keyframe. */
3603 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3604 entry->time > lace_time) {
3605 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3606 stream->set_discont = TRUE;
3612 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3613 gst_buffer_get_size (buf) - size, lace_size[n]);
3614 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3617 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3619 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3621 if (invisible_frame)
3622 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3624 if (stream->encodings != NULL && stream->encodings->len > 0)
3625 sub = gst_matroska_decode_buffer (stream, sub);
3628 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3632 if (!stream->dts_only) {
3633 GST_BUFFER_PTS (sub) = lace_time;
3635 GST_BUFFER_DTS (sub) = lace_time;
3636 if (stream->intra_only)
3637 GST_BUFFER_PTS (sub) = lace_time;
3640 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
3642 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3643 GstClockTime last_stop_end;
3645 /* Check if this stream is after segment stop */
3646 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3647 lace_time >= demux->common.segment.stop) {
3648 GST_DEBUG_OBJECT (demux,
3649 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3650 GST_TIME_ARGS (demux->common.segment.stop));
3651 gst_buffer_unref (sub);
3654 if (offset >= stream->to_offset
3655 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3656 && lace_time > demux->to_time)) {
3657 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3659 gst_buffer_unref (sub);
3663 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3664 * that landed us with timestamps not quite intended */
3665 GST_OBJECT_LOCK (demux);
3666 if (demux->max_gap_time &&
3667 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3668 demux->common.segment.rate > 0.0) {
3669 GstClockTimeDiff diff;
3671 /* only send segments with increasing start times,
3672 * otherwise if these go back and forth downstream (sinks) increase
3673 * accumulated time and running_time */
3674 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3675 if (diff > 0 && diff > demux->max_gap_time
3676 && lace_time > demux->common.segment.start
3677 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3678 || lace_time < demux->common.segment.stop)) {
3680 GST_DEBUG_OBJECT (demux,
3681 "Gap of %" G_GINT64_FORMAT " ns detected in"
3682 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3683 "Sending updated SEGMENT events", diff,
3684 stream->index, GST_TIME_ARGS (stream->pos),
3685 GST_TIME_ARGS (lace_time));
3687 event = gst_event_new_gap (demux->last_stop_end, diff);
3688 GST_OBJECT_UNLOCK (demux);
3689 gst_pad_push_event (stream->pad, event);
3690 GST_OBJECT_LOCK (demux);
3694 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3695 || demux->common.segment.position < lace_time) {
3696 demux->common.segment.position = lace_time;
3698 GST_OBJECT_UNLOCK (demux);
3700 last_stop_end = lace_time;
3702 GST_BUFFER_DURATION (sub) = duration / laces;
3703 last_stop_end += GST_BUFFER_DURATION (sub);
3706 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3707 demux->last_stop_end < last_stop_end)
3708 demux->last_stop_end = last_stop_end;
3710 GST_OBJECT_LOCK (demux);
3711 if (demux->common.segment.duration == -1 ||
3712 demux->stream_start_time + demux->common.segment.duration <
3714 demux->common.segment.duration =
3715 last_stop_end - demux->stream_start_time;
3716 GST_OBJECT_UNLOCK (demux);
3717 if (!demux->invalid_duration) {
3718 gst_element_post_message (GST_ELEMENT_CAST (demux),
3719 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3720 demux->invalid_duration = TRUE;
3723 GST_OBJECT_UNLOCK (demux);
3727 stream->pos = lace_time;
3729 gst_matroska_demux_sync_streams (demux);
3731 if (stream->set_discont) {
3732 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3733 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3734 stream->set_discont = FALSE;
3736 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3739 /* reverse playback book-keeping */
3740 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3741 stream->from_time = lace_time;
3742 if (stream->from_offset == -1)
3743 stream->from_offset = offset;
3745 GST_DEBUG_OBJECT (demux,
3746 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3747 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3748 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3749 GST_TIME_ARGS (buffer_timestamp),
3750 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3753 if (demux->common.element_index) {
3754 if (stream->index_writer_id == -1)
3755 gst_index_get_writer_id (demux->common.element_index,
3756 GST_OBJECT (stream->pad), &stream->index_writer_id);
3758 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3759 G_GUINT64_FORMAT " for writer id %d",
3760 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
3761 stream->index_writer_id);
3762 gst_index_add_association (demux->common.element_index,
3763 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3764 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3765 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
3770 /* Postprocess the buffers depending on the codec used */
3771 if (stream->postprocess_frame) {
3772 GST_LOG_OBJECT (demux, "running post process");
3773 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3776 /* At this point, we have a sub-buffer pointing at data within a larger
3777 buffer. This data might not be aligned with anything. If the data is
3778 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3779 for 32 bit samples, etc), or bad things will happen downstream as
3780 elements typically assume minimal alignment.
3781 Therefore, create an aligned copy if necessary. */
3782 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3784 if (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
3785 guint64 start_clip = 0, end_clip = 0;
3787 /* Codec delay is part of the timestamps */
3788 if (GST_BUFFER_PTS_IS_VALID (sub) && stream->codec_delay) {
3789 if (GST_BUFFER_PTS (sub) > stream->codec_delay) {
3790 GST_BUFFER_PTS (sub) -= stream->codec_delay;
3792 GST_BUFFER_PTS (sub) = 0;
3794 gst_util_uint64_scale_round (stream->codec_delay, 48000,
3797 if (GST_BUFFER_DURATION_IS_VALID (sub)) {
3798 if (GST_BUFFER_DURATION (sub) > stream->codec_delay)
3799 GST_BUFFER_DURATION (sub) -= stream->codec_delay;
3801 GST_BUFFER_DURATION (sub) = 0;
3806 if (block_discardpadding) {
3808 gst_util_uint64_scale_round (block_discardpadding, 48000,
3812 if (start_clip || end_clip) {
3813 gst_buffer_add_audio_clipping_meta (sub, GST_FORMAT_DEFAULT,
3814 start_clip, end_clip);
3818 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3819 stream->pos = GST_BUFFER_PTS (sub);
3820 if (GST_BUFFER_DURATION_IS_VALID (sub))
3821 stream->pos += GST_BUFFER_DURATION (sub);
3822 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
3823 stream->pos = GST_BUFFER_DTS (sub);
3824 if (GST_BUFFER_DURATION_IS_VALID (sub))
3825 stream->pos += GST_BUFFER_DURATION (sub);
3828 ret = gst_pad_push (stream->pad, sub);
3830 if (demux->common.segment.rate < 0) {
3831 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3832 /* In reverse playback we can get a GST_FLOW_EOS when
3833 * we are at the end of the segment, so we just need to jump
3834 * back to the previous section. */
3835 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3840 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
3844 size -= lace_size[n];
3845 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3846 lace_time += duration / laces;
3848 lace_time = GST_CLOCK_TIME_NONE;
3854 gst_buffer_unmap (buf, &map);
3855 gst_buffer_unref (buf);
3867 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
3873 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3874 /* non-fatal, try next block(group) */
3880 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3881 /* non-fatal, try next block(group) */
3887 /* return FALSE if block(group) should be skipped (due to a seek) */
3888 static inline gboolean
3889 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3891 if (G_UNLIKELY (demux->seek_block)) {
3892 if (!(--demux->seek_block)) {
3895 GST_LOG_OBJECT (demux, "should skip block due to seek");
3903 static GstFlowReturn
3904 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3908 guint64 seek_pos = (guint64) - 1;
3909 guint32 seek_id = 0;
3912 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3914 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3915 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3919 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3920 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3924 case GST_MATROSKA_ID_SEEKID:
3928 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3931 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3936 case GST_MATROSKA_ID_SEEKPOSITION:
3940 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3943 if (t > G_MAXINT64) {
3944 GST_WARNING_OBJECT (demux,
3945 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3949 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3955 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3961 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3964 if (!seek_id || seek_pos == (guint64) - 1) {
3965 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3966 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3971 case GST_MATROSKA_ID_SEEKHEAD:
3974 case GST_MATROSKA_ID_CUES:
3975 case GST_MATROSKA_ID_TAGS:
3976 case GST_MATROSKA_ID_TRACKS:
3977 case GST_MATROSKA_ID_SEGMENTINFO:
3978 case GST_MATROSKA_ID_ATTACHMENTS:
3979 case GST_MATROSKA_ID_CHAPTERS:
3981 guint64 before_pos, length;
3985 length = gst_matroska_read_common_get_length (&demux->common);
3986 before_pos = demux->common.offset;
3988 if (length == (guint64) - 1) {
3989 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3993 /* check for validity */
3994 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3995 GST_WARNING_OBJECT (demux,
3996 "SeekHead reference lies outside file!" " (%"
3997 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3998 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
4003 /* only pick up index location when streaming */
4004 if (demux->streaming) {
4005 if (seek_id == GST_MATROSKA_ID_CUES) {
4006 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
4007 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
4008 demux->index_offset);
4014 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
4017 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4018 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
4022 if (id != seek_id) {
4023 GST_WARNING_OBJECT (demux,
4024 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
4025 seek_id, id, seek_pos + demux->common.ebml_segment_start);
4028 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4033 demux->common.offset = before_pos;
4037 case GST_MATROSKA_ID_CLUSTER:
4039 guint64 pos = seek_pos + demux->common.ebml_segment_start;
4041 GST_LOG_OBJECT (demux, "Cluster position");
4042 if (G_UNLIKELY (!demux->clusters))
4043 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
4044 g_array_append_val (demux->clusters, pos);
4049 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
4052 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4057 static GstFlowReturn
4058 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4060 GstFlowReturn ret = GST_FLOW_OK;
4063 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4065 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4066 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4070 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4071 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4075 case GST_MATROSKA_ID_SEEKENTRY:
4077 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
4078 /* Ignore EOS and errors here */
4079 if (ret != GST_FLOW_OK) {
4080 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4087 ret = gst_matroska_read_common_parse_skip (&demux->common,
4088 ebml, "SeekHead", id);
4093 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4095 /* Sort clusters by position for easier searching */
4096 if (demux->clusters)
4097 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4102 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
4104 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4106 static inline GstFlowReturn
4107 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4109 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4110 /* only a few blocks are expected/allowed to be large,
4111 * and will be recursed into, whereas others will be read and must fit */
4112 if (demux->streaming) {
4113 /* fatal in streaming case, as we can't step over easily */
4114 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4115 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4116 "file might be corrupt.", bytes));
4117 return GST_FLOW_ERROR;
4119 /* indicate higher level to quietly give up */
4120 GST_DEBUG_OBJECT (demux,
4121 "too large block of size %" G_GUINT64_FORMAT, bytes);
4122 return GST_FLOW_ERROR;
4129 /* returns TRUE if we truely are in error state, and should give up */
4130 static inline GstFlowReturn
4131 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4133 if (!demux->streaming && demux->next_cluster_offset > 0) {
4134 /* just repositioning to where next cluster should be and try from there */
4135 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4136 G_GUINT64_FORMAT, demux->next_cluster_offset);
4137 demux->common.offset = demux->next_cluster_offset;
4138 demux->next_cluster_offset = 0;
4144 /* sigh, one last attempt above and beyond call of duty ...;
4145 * search for cluster mark following current pos */
4146 pos = demux->common.offset;
4147 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4148 if ((ret = gst_matroska_demux_search_cluster (demux, &pos)) != GST_FLOW_OK) {
4149 /* did not work, give up */
4152 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4153 /* try that position */
4154 demux->common.offset = pos;
4160 static inline GstFlowReturn
4161 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4163 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4164 demux->common.offset += flush;
4165 if (demux->streaming) {
4168 /* hard to skip large blocks when streaming */
4169 ret = gst_matroska_demux_check_read_size (demux, flush);
4170 if (ret != GST_FLOW_OK)
4172 if (flush <= gst_adapter_available (demux->common.adapter))
4173 gst_adapter_flush (demux->common.adapter, flush);
4175 return GST_FLOW_EOS;
4180 /* initializes @ebml with @bytes from input stream at current offset.
4181 * Returns EOS if insufficient available,
4182 * ERROR if too much was attempted to read. */
4183 static inline GstFlowReturn
4184 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4187 GstBuffer *buffer = NULL;
4188 GstFlowReturn ret = GST_FLOW_OK;
4190 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4192 ret = gst_matroska_demux_check_read_size (demux, bytes);
4193 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4194 if (!demux->streaming) {
4195 /* in pull mode, we can skip */
4196 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4197 ret = GST_FLOW_OVERFLOW;
4199 /* otherwise fatal */
4200 ret = GST_FLOW_ERROR;
4204 if (demux->streaming) {
4205 if (gst_adapter_available (demux->common.adapter) >= bytes)
4206 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4210 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4211 demux->common.offset, bytes, &buffer, NULL);
4212 if (G_LIKELY (buffer)) {
4213 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4214 demux->common.offset);
4215 demux->common.offset += bytes;
4222 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4225 gboolean seekable = FALSE;
4226 gint64 start = -1, stop = -1;
4228 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4229 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4230 GST_DEBUG_OBJECT (demux, "seeking query failed");
4234 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4236 /* try harder to query upstream size if we didn't get it the first time */
4237 if (seekable && stop == -1) {
4238 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4239 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4243 /* if upstream doesn't know the size, it's likely that it's not seekable in
4244 * practice even if it technically may be seekable */
4245 if (seekable && (start != 0 || stop <= start)) {
4246 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4251 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4252 G_GUINT64_FORMAT ")", seekable, start, stop);
4253 demux->seekable = seekable;
4255 gst_query_unref (query);
4258 static GstFlowReturn
4259 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4265 GstFlowReturn ret = GST_FLOW_OK;
4267 GST_WARNING_OBJECT (demux,
4268 "Found Cluster element before Tracks, searching Tracks");
4271 before_pos = demux->common.offset;
4273 /* Search Tracks element */
4275 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4276 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4277 if (ret != GST_FLOW_OK)
4280 if (id != GST_MATROSKA_ID_TRACKS) {
4281 /* we may be skipping large cluster here, so forego size check etc */
4282 /* ... but we can't skip undefined size; force error */
4283 if (length == G_MAXUINT64) {
4284 ret = gst_matroska_demux_check_read_size (demux, length);
4287 demux->common.offset += needed;
4288 demux->common.offset += length;
4293 /* will lead to track parsing ... */
4294 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4299 demux->common.offset = before_pos;
4304 #define GST_READ_CHECK(stmt) \
4306 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4307 if (ret == GST_FLOW_OVERFLOW) { \
4308 ret = GST_FLOW_OK; \
4314 static GstFlowReturn
4315 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4316 guint64 length, guint needed)
4318 GstEbmlRead ebml = { 0, };
4319 GstFlowReturn ret = GST_FLOW_OK;
4322 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4323 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4325 /* if we plan to read and parse this element, we need prefix (id + length)
4326 * and the contents */
4327 /* mind about overflow wrap-around when dealing with undefined size */
4329 if (G_LIKELY (length != G_MAXUINT64))
4332 switch (demux->common.state) {
4333 case GST_MATROSKA_READ_STATE_START:
4335 case GST_EBML_ID_HEADER:
4336 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4337 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4338 if (ret != GST_FLOW_OK)
4340 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4341 gst_matroska_demux_check_seekability (demux);
4344 goto invalid_header;
4348 case GST_MATROSKA_READ_STATE_SEGMENT:
4350 case GST_MATROSKA_ID_SEGMENT:
4351 /* eat segment prefix */
4352 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4353 GST_DEBUG_OBJECT (demux,
4354 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4355 G_GUINT64_FORMAT, demux->common.offset, length);
4356 /* seeks are from the beginning of the segment,
4357 * after the segment ID/length */
4358 demux->common.ebml_segment_start = demux->common.offset;
4360 length = G_MAXUINT64;
4361 demux->common.ebml_segment_length = length;
4362 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4365 GST_WARNING_OBJECT (demux,
4366 "Expected a Segment ID (0x%x), but received 0x%x!",
4367 GST_MATROSKA_ID_SEGMENT, id);
4368 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4372 case GST_MATROSKA_READ_STATE_SCANNING:
4373 if (id != GST_MATROSKA_ID_CLUSTER &&
4374 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4377 case GST_MATROSKA_READ_STATE_HEADER:
4378 case GST_MATROSKA_READ_STATE_DATA:
4379 case GST_MATROSKA_READ_STATE_SEEK:
4381 case GST_MATROSKA_ID_SEGMENTINFO:
4382 if (!demux->common.segmentinfo_parsed) {
4383 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4384 ret = gst_matroska_read_common_parse_info (&demux->common,
4385 GST_ELEMENT_CAST (demux), &ebml);
4386 if (ret == GST_FLOW_OK)
4387 gst_matroska_demux_send_tags (demux);
4389 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4392 case GST_MATROSKA_ID_TRACKS:
4393 if (!demux->tracks_parsed) {
4394 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4395 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4397 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4400 case GST_MATROSKA_ID_CLUSTER:
4401 if (G_UNLIKELY (!demux->tracks_parsed)) {
4402 if (demux->streaming) {
4403 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4404 goto not_streamable;
4406 ret = gst_matroska_demux_find_tracks (demux);
4407 if (!demux->tracks_parsed)
4411 if (G_UNLIKELY (demux->common.state
4412 == GST_MATROSKA_READ_STATE_HEADER)) {
4413 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4414 demux->first_cluster_offset = demux->common.offset;
4415 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4416 gst_element_no_more_pads (GST_ELEMENT (demux));
4417 /* send initial segment - we wait till we know the first
4418 incoming timestamp, so we can properly set the start of
4420 demux->need_segment = TRUE;
4422 demux->cluster_time = GST_CLOCK_TIME_NONE;
4423 demux->cluster_offset = demux->common.offset;
4424 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4425 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4426 " not found in Cluster, trying next Cluster's first block instead",
4428 demux->seek_block = 0;
4430 demux->seek_first = FALSE;
4431 /* record next cluster for recovery */
4432 if (read != G_MAXUINT64)
4433 demux->next_cluster_offset = demux->cluster_offset + read;
4434 /* eat cluster prefix */
4435 gst_matroska_demux_flush (demux, needed);
4437 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4441 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4442 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4444 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4445 demux->cluster_time = num;
4447 if (demux->common.element_index) {
4448 if (demux->common.element_index_writer_id == -1)
4449 gst_index_get_writer_id (demux->common.element_index,
4450 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4451 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4452 G_GUINT64_FORMAT " for writer id %d",
4453 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4454 demux->common.element_index_writer_id);
4455 gst_index_add_association (demux->common.element_index,
4456 demux->common.element_index_writer_id,
4457 GST_ASSOCIATION_FLAG_KEY_UNIT,
4458 GST_FORMAT_TIME, demux->cluster_time,
4459 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4464 case GST_MATROSKA_ID_BLOCKGROUP:
4465 if (!gst_matroska_demux_seek_block (demux))
4467 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4468 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4469 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4470 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4471 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4473 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4475 case GST_MATROSKA_ID_SIMPLEBLOCK:
4476 if (!gst_matroska_demux_seek_block (demux))
4478 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4479 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4480 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4481 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4482 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4484 case GST_MATROSKA_ID_ATTACHMENTS:
4485 if (!demux->common.attachments_parsed) {
4486 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4487 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4488 GST_ELEMENT_CAST (demux), &ebml);
4489 if (ret == GST_FLOW_OK)
4490 gst_matroska_demux_send_tags (demux);
4492 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4495 case GST_MATROSKA_ID_TAGS:
4496 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4497 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4498 GST_ELEMENT_CAST (demux), &ebml);
4499 if (ret == GST_FLOW_OK)
4500 gst_matroska_demux_send_tags (demux);
4502 case GST_MATROSKA_ID_CHAPTERS:
4503 if (!demux->common.chapters_parsed) {
4504 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4506 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4508 if (demux->common.toc) {
4509 gst_matroska_demux_send_event (demux,
4510 gst_event_new_toc (demux->common.toc, FALSE));
4513 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4515 case GST_MATROSKA_ID_SEEKHEAD:
4516 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4517 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4519 case GST_MATROSKA_ID_CUES:
4520 if (demux->common.index_parsed) {
4521 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4524 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4525 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4526 /* only push based; delayed index building */
4527 if (ret == GST_FLOW_OK
4528 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4531 GST_OBJECT_LOCK (demux);
4532 event = demux->seek_event;
4533 demux->seek_event = NULL;
4534 GST_OBJECT_UNLOCK (demux);
4537 /* unlikely to fail, since we managed to seek to this point */
4538 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
4539 gst_event_unref (event);
4542 gst_event_unref (event);
4543 /* resume data handling, main thread clear to seek again */
4544 GST_OBJECT_LOCK (demux);
4545 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4546 GST_OBJECT_UNLOCK (demux);
4549 case GST_MATROSKA_ID_POSITION:
4550 case GST_MATROSKA_ID_PREVSIZE:
4551 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4552 case GST_MATROSKA_ID_SILENTTRACKS:
4553 GST_DEBUG_OBJECT (demux,
4554 "Skipping Cluster subelement 0x%x - ignoring", id);
4558 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4559 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4565 if (ret == GST_FLOW_PARSE)
4569 gst_ebml_read_clear (&ebml);
4575 /* simply exit, maybe not enough data yet */
4576 /* no ebml to clear if read error */
4581 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4582 ("Failed to parse Element 0x%x", id));
4583 ret = GST_FLOW_ERROR;
4588 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4589 ("File layout does not permit streaming"));
4590 ret = GST_FLOW_ERROR;
4595 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4596 ("No Tracks element found"));
4597 ret = GST_FLOW_ERROR;
4602 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4603 ret = GST_FLOW_ERROR;
4608 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4609 ret = GST_FLOW_ERROR;
4615 gst_matroska_demux_loop (GstPad * pad)
4617 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4623 /* If we have to close a segment, send a new segment to do this now */
4624 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4625 if (G_UNLIKELY (demux->new_segment)) {
4626 gst_matroska_demux_send_event (demux, demux->new_segment);
4627 demux->new_segment = NULL;
4631 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4632 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4633 if (ret == GST_FLOW_EOS) {
4635 } else if (ret == GST_FLOW_FLUSHING) {
4637 } else if (ret != GST_FLOW_OK) {
4638 ret = gst_matroska_demux_check_parse_error (demux);
4640 /* Only handle EOS as no error if we're outside the segment already */
4641 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4642 && demux->common.offset >=
4643 demux->common.ebml_segment_start +
4644 demux->common.ebml_segment_length))
4646 else if (ret != GST_FLOW_OK)
4652 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4653 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4656 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4657 if (ret == GST_FLOW_EOS)
4659 if (ret != GST_FLOW_OK)
4662 /* check if we're at the end of a configured segment */
4663 if (G_LIKELY (demux->common.src->len)) {
4666 g_assert (demux->common.num_streams == demux->common.src->len);
4667 for (i = 0; i < demux->common.src->len; i++) {
4668 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4670 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4671 GST_TIME_ARGS (context->pos));
4672 if (context->eos == FALSE)
4676 GST_INFO_OBJECT (demux, "All streams are EOS");
4682 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4683 demux->common.offset >= demux->cached_length)) {
4684 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4685 if (demux->common.offset == demux->cached_length) {
4686 GST_LOG_OBJECT (demux, "Reached end of stream");
4697 if (demux->common.segment.rate < 0.0) {
4698 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4699 if (ret == GST_FLOW_OK)
4706 const gchar *reason = gst_flow_get_name (ret);
4707 gboolean push_eos = FALSE;
4709 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4710 gst_pad_pause_task (demux->common.sinkpad);
4712 if (ret == GST_FLOW_EOS) {
4713 /* perform EOS logic */
4715 /* If we were in the headers, make sure we send no-more-pads.
4716 This will ensure decodebin does not get stuck thinking
4717 the chain is not complete yet, and waiting indefinitely. */
4718 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4719 if (demux->common.src->len == 0) {
4720 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4721 ("No pads created"));
4723 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4724 ("Failed to finish reading headers"));
4726 gst_element_no_more_pads (GST_ELEMENT (demux));
4729 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4732 /* for segment playback we need to post when (in stream time)
4733 * we stopped, this is either stop (when set) or the duration. */
4734 if ((stop = demux->common.segment.stop) == -1)
4735 stop = demux->last_stop_end;
4737 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4738 gst_element_post_message (GST_ELEMENT (demux),
4739 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4741 gst_matroska_demux_send_event (demux,
4742 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4746 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4747 /* for fatal errors we post an error message */
4748 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4749 ("stream stopped, reason %s", reason));
4753 /* send EOS, and prevent hanging if no streams yet */
4754 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4755 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4756 (ret == GST_FLOW_EOS)) {
4757 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4758 (NULL), ("got eos but no streams (yet)"));
4766 * Create and push a flushing seek event upstream
4769 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4775 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4778 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4779 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4780 GST_SEEK_TYPE_NONE, -1);
4781 gst_event_set_seqnum (event, seqnum);
4783 res = gst_pad_push_event (demux->common.sinkpad, event);
4785 /* segment event will update offset */
4789 static GstFlowReturn
4790 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4792 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4794 GstFlowReturn ret = GST_FLOW_OK;
4799 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4800 GST_DEBUG_OBJECT (demux, "got DISCONT");
4801 gst_adapter_clear (demux->common.adapter);
4802 GST_OBJECT_LOCK (demux);
4803 gst_matroska_read_common_reset_streams (&demux->common,
4804 GST_CLOCK_TIME_NONE, FALSE);
4805 GST_OBJECT_UNLOCK (demux);
4808 gst_adapter_push (demux->common.adapter, buffer);
4812 available = gst_adapter_available (demux->common.adapter);
4814 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4815 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4816 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4817 if (demux->common.ebml_segment_length != G_MAXUINT64
4818 && demux->common.offset >=
4819 demux->common.ebml_segment_start + demux->common.ebml_segment_length)
4824 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4825 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4826 demux->common.offset, id, length, needed, available);
4828 if (needed > available)
4831 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4832 if (ret == GST_FLOW_EOS) {
4833 /* need more data */
4835 } else if (ret != GST_FLOW_OK) {
4842 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4845 gboolean res = TRUE;
4846 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4848 GST_DEBUG_OBJECT (demux,
4849 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4851 switch (GST_EVENT_TYPE (event)) {
4852 case GST_EVENT_SEGMENT:
4854 const GstSegment *segment;
4856 /* some debug output */
4857 gst_event_parse_segment (event, &segment);
4858 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4859 GST_DEBUG_OBJECT (demux,
4860 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4863 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4864 GST_DEBUG_OBJECT (demux, "still starting");
4868 /* we only expect a BYTE segment, e.g. following a seek */
4869 if (segment->format != GST_FORMAT_BYTES) {
4870 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4874 GST_DEBUG_OBJECT (demux, "clearing segment state");
4875 GST_OBJECT_LOCK (demux);
4876 /* clear current segment leftover */
4877 gst_adapter_clear (demux->common.adapter);
4878 /* and some streaming setup */
4879 demux->common.offset = segment->start;
4880 /* accumulate base based on current position */
4881 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4882 demux->common.segment.base +=
4883 (MAX (demux->common.segment.position, demux->stream_start_time)
4884 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4885 /* do not know where we are;
4886 * need to come across a cluster and generate segment */
4887 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4888 demux->cluster_time = GST_CLOCK_TIME_NONE;
4889 demux->cluster_offset = 0;
4890 demux->need_segment = TRUE;
4891 demux->segment_seqnum = gst_event_get_seqnum (event);
4892 /* but keep some of the upstream segment */
4893 demux->common.segment.rate = segment->rate;
4894 /* also check if need to keep some of the requested seek position */
4895 if (demux->seek_offset == segment->start) {
4896 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4897 demux->common.segment.position = demux->requested_seek_time;
4899 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4901 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4902 demux->seek_offset = -1;
4903 GST_OBJECT_UNLOCK (demux);
4905 /* chain will send initial segment after pads have been added,
4906 * or otherwise come up with one */
4907 GST_DEBUG_OBJECT (demux, "eating event");
4908 gst_event_unref (event);
4914 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4915 gst_event_unref (event);
4916 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4917 (NULL), ("got eos and didn't receive a complete header object"));
4918 } else if (demux->common.num_streams == 0) {
4919 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4920 (NULL), ("got eos but no streams (yet)"));
4922 gst_matroska_demux_send_event (demux, event);
4926 case GST_EVENT_FLUSH_STOP:
4930 gst_adapter_clear (demux->common.adapter);
4931 GST_OBJECT_LOCK (demux);
4932 gst_matroska_read_common_reset_streams (&demux->common,
4933 GST_CLOCK_TIME_NONE, TRUE);
4934 gst_flow_combiner_reset (demux->flowcombiner);
4935 dur = demux->common.segment.duration;
4936 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4937 demux->common.segment.duration = dur;
4938 demux->cluster_time = GST_CLOCK_TIME_NONE;
4939 demux->cluster_offset = 0;
4940 GST_OBJECT_UNLOCK (demux);
4944 res = gst_pad_event_default (pad, parent, event);
4952 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4954 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4956 gboolean pull_mode = FALSE;
4958 query = gst_query_new_scheduling ();
4960 if (gst_pad_peer_query (sinkpad, query))
4961 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4962 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4964 gst_query_unref (query);
4967 GST_DEBUG ("going to pull mode");
4968 demux->streaming = FALSE;
4969 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4971 GST_DEBUG ("going to push (streaming) mode");
4972 demux->streaming = TRUE;
4973 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4978 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4979 GstPadMode mode, gboolean active)
4982 case GST_PAD_MODE_PULL:
4984 /* if we have a scheduler we can start the task */
4985 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4988 gst_pad_stop_task (sinkpad);
4991 case GST_PAD_MODE_PUSH:
4999 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
5000 videocontext, const gchar * codec_id, guint8 * data, guint size,
5001 gchar ** codec_name, guint32 * riff_fourcc)
5003 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
5004 GstCaps *caps = NULL;
5006 g_assert (videocontext != NULL);
5007 g_assert (codec_name != NULL);
5012 /* TODO: check if we have all codec types from matroska-ids.h
5013 * check if we have to do more special things with codec_private
5016 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
5017 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
5020 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
5021 gst_riff_strf_vids *vids = NULL;
5024 GstBuffer *buf = NULL;
5026 vids = (gst_riff_strf_vids *) data;
5028 /* assure size is big enough */
5030 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
5033 if (size < sizeof (gst_riff_strf_vids)) {
5034 vids = g_new (gst_riff_strf_vids, 1);
5035 memcpy (vids, data, size);
5038 context->dts_only = TRUE; /* VFW files only store DTS */
5040 /* little-endian -> byte-order */
5041 vids->size = GUINT32_FROM_LE (vids->size);
5042 vids->width = GUINT32_FROM_LE (vids->width);
5043 vids->height = GUINT32_FROM_LE (vids->height);
5044 vids->planes = GUINT16_FROM_LE (vids->planes);
5045 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
5046 vids->compression = GUINT32_FROM_LE (vids->compression);
5047 vids->image_size = GUINT32_FROM_LE (vids->image_size);
5048 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
5049 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
5050 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
5051 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
5053 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
5054 gsize offset = sizeof (gst_riff_strf_vids);
5057 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
5058 size - offset), size - offset);
5062 *riff_fourcc = vids->compression;
5064 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
5065 buf, NULL, codec_name);
5068 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
5069 GST_FOURCC_ARGS (vids->compression));
5071 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
5072 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
5073 "video/x-compressed-yuv");
5074 context->intra_only =
5075 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
5079 gst_buffer_unref (buf);
5081 if (vids != (gst_riff_strf_vids *) data)
5084 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
5086 GstVideoFormat format;
5088 gst_video_info_init (&info);
5089 switch (videocontext->fourcc) {
5090 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5091 format = GST_VIDEO_FORMAT_I420;
5093 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5094 format = GST_VIDEO_FORMAT_YUY2;
5096 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5097 format = GST_VIDEO_FORMAT_YV12;
5099 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5100 format = GST_VIDEO_FORMAT_UYVY;
5102 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5103 format = GST_VIDEO_FORMAT_AYUV;
5105 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
5106 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
5107 format = GST_VIDEO_FORMAT_GRAY8;
5109 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
5110 format = GST_VIDEO_FORMAT_RGB;
5112 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
5113 format = GST_VIDEO_FORMAT_BGR;
5116 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5117 GST_FOURCC_ARGS (videocontext->fourcc));
5121 context->intra_only = TRUE;
5123 gst_video_info_set_format (&info, format, videocontext->pixel_width,
5124 videocontext->pixel_height);
5125 caps = gst_video_info_to_caps (&info);
5126 *codec_name = gst_pb_utils_get_codec_description (caps);
5127 context->alignment = 32;
5128 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5129 caps = gst_caps_new_simple ("video/x-divx",
5130 "divxversion", G_TYPE_INT, 4, NULL);
5131 *codec_name = g_strdup ("MPEG-4 simple profile");
5132 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5133 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5134 caps = gst_caps_new_simple ("video/mpeg",
5135 "mpegversion", G_TYPE_INT, 4,
5136 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5140 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5141 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5142 gst_buffer_unref (priv);
5144 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
5146 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5147 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5149 *codec_name = g_strdup ("MPEG-4 advanced profile");
5150 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5152 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5153 "divxversion", G_TYPE_INT, 3, NULL),
5154 gst_structure_new ("video/x-msmpeg",
5155 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5157 caps = gst_caps_new_simple ("video/x-msmpeg",
5158 "msmpegversion", G_TYPE_INT, 43, NULL);
5159 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5160 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5161 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5164 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5169 caps = gst_caps_new_simple ("video/mpeg",
5170 "systemstream", G_TYPE_BOOLEAN, FALSE,
5171 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5172 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5173 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5174 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5175 caps = gst_caps_new_empty_simple ("image/jpeg");
5176 *codec_name = g_strdup ("Motion-JPEG");
5177 context->intra_only = TRUE;
5178 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5179 caps = gst_caps_new_empty_simple ("video/x-h264");
5183 /* First byte is the version, second is the profile indication, and third
5184 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5185 * level indication. */
5186 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5189 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5190 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5191 gst_buffer_unref (priv);
5193 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5194 "alignment", G_TYPE_STRING, "au", NULL);
5196 GST_WARNING ("No codec data found, assuming output is byte-stream");
5197 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5200 *codec_name = g_strdup ("H264");
5201 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
5202 caps = gst_caps_new_empty_simple ("video/x-h265");
5206 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
5209 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5210 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5211 gst_buffer_unref (priv);
5213 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
5214 "alignment", G_TYPE_STRING, "au", NULL);
5216 GST_WARNING ("No codec data found, assuming output is byte-stream");
5217 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5220 *codec_name = g_strdup ("HEVC");
5221 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5222 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5223 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5224 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5225 gint rmversion = -1;
5227 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5229 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5231 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5233 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5236 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5237 "rmversion", G_TYPE_INT, rmversion, NULL);
5238 GST_DEBUG ("data:%p, size:0x%x", data, size);
5239 /* We need to extract the extradata ! */
5240 if (data && (size >= 0x22)) {
5245 subformat = GST_READ_UINT32_BE (data + 0x1a);
5246 rformat = GST_READ_UINT32_BE (data + 0x1e);
5249 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5251 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5252 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5253 gst_buffer_unref (priv);
5256 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5257 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5258 caps = gst_caps_new_empty_simple ("video/x-theora");
5259 context->stream_headers =
5260 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5261 context->codec_priv_size);
5262 /* FIXME: mark stream as broken and skip if there are no stream headers */
5263 context->send_stream_headers = TRUE;
5264 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5265 caps = gst_caps_new_empty_simple ("video/x-dirac");
5266 *codec_name = g_strdup_printf ("Dirac");
5267 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5268 caps = gst_caps_new_empty_simple ("video/x-vp8");
5269 *codec_name = g_strdup_printf ("On2 VP8");
5270 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5271 caps = gst_caps_new_empty_simple ("video/x-vp9");
5272 *codec_name = g_strdup_printf ("On2 VP9");
5273 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
5275 const gchar *variant, *variant_descr = "";
5277 /* Expect a fourcc in the codec private data */
5278 if (!data || size < 4) {
5279 GST_WARNING ("No or too small PRORESS fourcc (%d bytes)", size);
5283 fourcc = GST_STR_FOURCC (data);
5285 case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
5286 variant_descr = " 4:2:2 LT";
5289 case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
5291 variant_descr = " 4:2:2 HQ";
5293 case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
5295 variant_descr = " 4:4:4:4";
5297 case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
5299 variant_descr = " 4:2:2 Proxy";
5301 case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
5303 variant = "standard";
5304 variant_descr = " 4:2:2 SD";
5308 GST_LOG ("Prores video, codec fourcc %" GST_FOURCC_FORMAT,
5309 GST_FOURCC_ARGS (fourcc));
5311 caps = gst_caps_new_simple ("video/x-prores",
5312 "format", G_TYPE_STRING, variant, NULL);
5313 *codec_name = g_strdup_printf ("Apple ProRes%s", variant_descr);
5314 context->postprocess_frame = gst_matroska_demux_add_prores_header;
5316 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5322 GstStructure *structure;
5324 for (i = 0; i < gst_caps_get_size (caps); i++) {
5325 structure = gst_caps_get_structure (caps, i);
5327 /* FIXME: use the real unit here! */
5328 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5329 videocontext->pixel_width,
5330 videocontext->pixel_height,
5331 videocontext->display_width, videocontext->display_height);
5333 /* pixel width and height are the w and h of the video in pixels */
5334 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5335 gint w = videocontext->pixel_width;
5336 gint h = videocontext->pixel_height;
5338 gst_structure_set (structure,
5339 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5342 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5345 if (videocontext->display_width <= 0)
5346 videocontext->display_width = videocontext->pixel_width;
5347 if (videocontext->display_height <= 0)
5348 videocontext->display_height = videocontext->pixel_height;
5350 /* calculate the pixel aspect ratio using the display and pixel w/h */
5351 n = videocontext->display_width * videocontext->pixel_height;
5352 d = videocontext->display_height * videocontext->pixel_width;
5353 GST_DEBUG ("setting PAR to %d/%d", n, d);
5354 gst_structure_set (structure, "pixel-aspect-ratio",
5356 videocontext->display_width * videocontext->pixel_height,
5357 videocontext->display_height * videocontext->pixel_width, NULL);
5360 if (videocontext->default_fps > 0.0) {
5363 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5365 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5367 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5369 } else if (context->default_duration > 0) {
5372 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5374 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5375 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5377 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5378 fps_n, fps_d, NULL);
5380 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5384 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5385 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5388 if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
5389 if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
5390 videocontext->pixel_width, videocontext->pixel_height,
5391 videocontext->display_width * videocontext->pixel_height,
5392 videocontext->display_height * videocontext->pixel_width)) {
5393 videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
5395 gst_caps_set_simple (caps,
5396 "multiview-mode", G_TYPE_STRING,
5397 gst_video_multiview_mode_to_caps_string
5398 (videocontext->multiview_mode), "multiview-flags",
5399 GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
5400 GST_FLAG_SET_MASK_EXACT, NULL);
5403 caps = gst_caps_simplify (caps);
5410 * Some AAC specific code... *sigh*
5411 * FIXME: maybe we should use '15' and code the sample rate explicitly
5412 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5416 aac_rate_idx (gint rate)
5420 else if (75132 <= rate)
5422 else if (55426 <= rate)
5424 else if (46009 <= rate)
5426 else if (37566 <= rate)
5428 else if (27713 <= rate)
5430 else if (23004 <= rate)
5432 else if (18783 <= rate)
5434 else if (13856 <= rate)
5436 else if (11502 <= rate)
5438 else if (9391 <= rate)
5445 aac_profile_idx (const gchar * codec_id)
5449 if (strlen (codec_id) <= 12)
5451 else if (!strncmp (&codec_id[12], "MAIN", 4))
5453 else if (!strncmp (&codec_id[12], "LC", 2))
5455 else if (!strncmp (&codec_id[12], "SSR", 3))
5464 round_up_pow2 (guint n)
5475 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5478 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5479 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5480 gchar ** codec_name, guint16 * riff_audio_fmt)
5482 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5483 GstCaps *caps = NULL;
5485 g_assert (audiocontext != NULL);
5486 g_assert (codec_name != NULL);
5489 *riff_audio_fmt = 0;
5491 /* TODO: check if we have all codec types from matroska-ids.h
5492 * check if we have to do more special things with codec_private
5493 * check if we need bitdepth in different places too
5494 * implement channel position magic
5496 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5497 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5498 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5499 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5502 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5503 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5504 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5507 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5509 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5514 caps = gst_caps_new_simple ("audio/mpeg",
5515 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5516 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5517 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5518 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5521 GstAudioFormat format;
5523 sign = (audiocontext->bitdepth != 8);
5524 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5525 endianness = G_BIG_ENDIAN;
5527 endianness = G_LITTLE_ENDIAN;
5529 format = gst_audio_format_build_integer (sign, endianness,
5530 audiocontext->bitdepth, audiocontext->bitdepth);
5532 /* FIXME: Channel mask and reordering */
5533 caps = gst_caps_new_simple ("audio/x-raw",
5534 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5535 "layout", G_TYPE_STRING, "interleaved",
5536 "channel-mask", GST_TYPE_BITMASK,
5537 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5539 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5540 audiocontext->bitdepth);
5541 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5542 context->alignment = round_up_pow2 (context->alignment);
5543 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5544 const gchar *format;
5545 if (audiocontext->bitdepth == 32)
5549 /* FIXME: Channel mask and reordering */
5550 caps = gst_caps_new_simple ("audio/x-raw",
5551 "format", G_TYPE_STRING, format,
5552 "layout", G_TYPE_STRING, "interleaved",
5553 "channel-mask", GST_TYPE_BITMASK,
5554 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5555 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5556 audiocontext->bitdepth);
5557 context->alignment = audiocontext->bitdepth / 8;
5558 context->alignment = round_up_pow2 (context->alignment);
5559 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5560 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5561 caps = gst_caps_new_simple ("audio/x-ac3",
5562 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5563 *codec_name = g_strdup ("AC-3 audio");
5564 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5565 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5566 caps = gst_caps_new_simple ("audio/x-eac3",
5567 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5568 *codec_name = g_strdup ("E-AC-3 audio");
5569 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5570 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5571 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5572 *codec_name = g_strdup ("Dolby TrueHD");
5573 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5574 caps = gst_caps_new_empty_simple ("audio/x-dts");
5575 *codec_name = g_strdup ("DTS audio");
5576 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5577 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5578 context->stream_headers =
5579 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5580 context->codec_priv_size);
5581 /* FIXME: mark stream as broken and skip if there are no stream headers */
5582 context->send_stream_headers = TRUE;
5583 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5584 caps = gst_caps_new_empty_simple ("audio/x-flac");
5585 context->stream_headers =
5586 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5587 context->codec_priv_size);
5588 /* FIXME: mark stream as broken and skip if there are no stream headers */
5589 context->send_stream_headers = TRUE;
5590 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5591 caps = gst_caps_new_empty_simple ("audio/x-speex");
5592 context->stream_headers =
5593 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5594 context->codec_priv_size);
5595 /* FIXME: mark stream as broken and skip if there are no stream headers */
5596 context->send_stream_headers = TRUE;
5597 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5600 if (context->codec_priv_size >= 19) {
5601 if (audiocontext->samplerate)
5602 GST_WRITE_UINT32_LE ((guint8 *) context->codec_priv + 12,
5603 audiocontext->samplerate);
5604 if (context->codec_delay) {
5606 gst_util_uint64_scale_round (context->codec_delay, 48000,
5608 GST_WRITE_UINT16_LE ((guint8 *) context->codec_priv + 10, delay);
5612 gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5613 context->codec_priv_size), context->codec_priv_size);
5614 caps = gst_codec_utils_opus_create_caps_from_header (tmp, NULL);
5615 gst_buffer_unref (tmp);
5616 *codec_name = g_strdup ("Opus");
5617 } else if (context->codec_priv_size == 0) {
5618 GST_WARNING ("No Opus codec data found, trying to create one");
5619 if (audiocontext->channels >= 0 && audiocontext->channels <= 2) {
5620 guint8 streams, coupled, channels;
5624 audiocontext->samplerate == 0 ? 48000 : audiocontext->samplerate;
5625 channels = audiocontext->channels == 0 ? 2 : audiocontext->channels;
5626 if (channels == 1) {
5635 gst_codec_utils_opus_create_caps (samplerate, channels, 0, streams,
5638 *codec_name = g_strdup ("Opus");
5640 GST_WARNING ("Failed to create Opus caps from audio context");
5643 GST_WARNING ("No Opus codec data, and not enough info to create one");
5646 GST_WARNING ("Invalid Opus codec data size (got %" G_GSIZE_FORMAT
5647 ", expected 19)", context->codec_priv_size);
5649 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5650 gst_riff_strf_auds auds;
5652 if (data && size >= 18) {
5653 GstBuffer *codec_data = NULL;
5655 /* little-endian -> byte-order */
5656 auds.format = GST_READ_UINT16_LE (data);
5657 auds.channels = GST_READ_UINT16_LE (data + 2);
5658 auds.rate = GST_READ_UINT32_LE (data + 4);
5659 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5660 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5661 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5663 /* 18 is the waveformatex size */
5665 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5666 data + 18, size - 18, 0, size - 18, NULL, NULL);
5670 *riff_audio_fmt = auds.format;
5672 /* FIXME: Handle reorder map */
5673 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5674 codec_data, codec_name, NULL);
5676 gst_buffer_unref (codec_data);
5679 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5682 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5684 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5685 GstBuffer *priv = NULL;
5687 gint rate_idx, profile;
5688 guint8 *data = NULL;
5690 /* unspecified AAC profile with opaque private codec data */
5691 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5692 if (context->codec_priv_size >= 2) {
5693 guint obj_type, freq_index, explicit_freq_bytes = 0;
5695 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5697 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5698 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5699 if (freq_index == 15)
5700 explicit_freq_bytes = 3;
5701 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5702 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5703 context->codec_priv_size), context->codec_priv_size);
5704 /* assume SBR if samplerate <= 24kHz */
5705 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5706 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5707 audiocontext->samplerate *= 2;
5710 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5711 /* this is pretty broken;
5712 * maybe we need to make up some default private,
5713 * or maybe ADTS data got dumped in.
5714 * Let's set up some private data now, and check actual data later */
5715 /* just try this and see what happens ... */
5716 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5717 context->postprocess_frame = gst_matroska_demux_check_aac;
5721 /* make up decoder-specific data if it is not supplied */
5725 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5726 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5728 rate_idx = aac_rate_idx (audiocontext->samplerate);
5729 profile = aac_profile_idx (codec_id);
5731 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5732 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5734 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5735 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5737 gst_buffer_unmap (priv, &map);
5738 gst_buffer_set_size (priv, 2);
5739 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5740 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5743 if (g_strrstr (codec_id, "SBR")) {
5744 /* HE-AAC (aka SBR AAC) */
5745 audiocontext->samplerate *= 2;
5746 rate_idx = aac_rate_idx (audiocontext->samplerate);
5747 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5748 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5749 data[4] = (1 << 7) | (rate_idx << 3);
5750 gst_buffer_unmap (priv, &map);
5752 gst_buffer_unmap (priv, &map);
5753 gst_buffer_set_size (priv, 2);
5756 gst_buffer_unmap (priv, &map);
5757 gst_buffer_unref (priv);
5759 GST_ERROR ("Unknown AAC profile and no codec private data");
5764 caps = gst_caps_new_simple ("audio/mpeg",
5765 "mpegversion", G_TYPE_INT, mpegversion,
5766 "framed", G_TYPE_BOOLEAN, TRUE,
5767 "stream-format", G_TYPE_STRING, "raw", NULL);
5768 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5769 if (context->codec_priv && context->codec_priv_size > 0)
5770 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5771 context->codec_priv, context->codec_priv_size);
5772 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5773 gst_buffer_unref (priv);
5775 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5776 caps = gst_caps_new_simple ("audio/x-tta",
5777 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5778 *codec_name = g_strdup ("TTA audio");
5779 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5780 caps = gst_caps_new_simple ("audio/x-wavpack",
5781 "width", G_TYPE_INT, audiocontext->bitdepth,
5782 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5783 *codec_name = g_strdup ("Wavpack audio");
5784 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5785 audiocontext->wvpk_block_index = 0;
5786 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5787 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5788 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5789 gint raversion = -1;
5791 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5793 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5798 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5799 "raversion", G_TYPE_INT, raversion, NULL);
5800 /* Extract extra information from caps, mapping varies based on codec */
5801 if (data && (size >= 0x50)) {
5808 guint extra_data_size;
5810 GST_ERROR ("real audio raversion:%d", raversion);
5811 if (raversion == 8) {
5813 flavor = GST_READ_UINT16_BE (data + 22);
5814 packet_size = GST_READ_UINT32_BE (data + 24);
5815 height = GST_READ_UINT16_BE (data + 40);
5816 leaf_size = GST_READ_UINT16_BE (data + 44);
5817 sample_width = GST_READ_UINT16_BE (data + 58);
5818 extra_data_size = GST_READ_UINT32_BE (data + 74);
5821 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5822 flavor, packet_size, height, leaf_size, sample_width,
5824 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5825 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5826 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5828 if ((size - 78) >= extra_data_size) {
5829 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5831 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5832 gst_buffer_unref (priv);
5837 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5838 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5839 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5840 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5841 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5842 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5843 *codec_name = g_strdup ("Real Audio Lossless");
5844 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5845 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5846 *codec_name = g_strdup ("Sony ATRAC3");
5848 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5853 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5856 for (i = 0; i < gst_caps_get_size (caps); i++) {
5857 gst_structure_set (gst_caps_get_structure (caps, i),
5858 "channels", G_TYPE_INT, audiocontext->channels,
5859 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5863 caps = gst_caps_simplify (caps);
5870 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5871 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5873 GstCaps *caps = NULL;
5874 GstMatroskaTrackContext *context =
5875 (GstMatroskaTrackContext *) subtitlecontext;
5877 /* for backwards compatibility */
5878 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5879 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5880 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5881 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5882 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5883 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5884 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5885 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5887 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5888 * Check if we have to do something with codec_private */
5889 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5890 /* well, plain text simply does not have a lot of markup ... */
5891 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5892 "pango-markup", NULL);
5893 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5894 subtitlecontext->check_markup = TRUE;
5895 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5896 caps = gst_caps_new_empty_simple ("application/x-ssa");
5897 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5898 subtitlecontext->check_markup = FALSE;
5899 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5900 caps = gst_caps_new_empty_simple ("application/x-ass");
5901 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5902 subtitlecontext->check_markup = FALSE;
5903 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5904 caps = gst_caps_new_empty_simple ("application/x-usf");
5905 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5906 subtitlecontext->check_markup = FALSE;
5907 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5908 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5909 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5910 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5911 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5912 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5913 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5914 context->stream_headers =
5915 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5916 context->codec_priv_size);
5917 /* FIXME: mark stream as broken and skip if there are no stream headers */
5918 context->send_stream_headers = TRUE;
5920 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5921 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5924 if (data != NULL && size > 0) {
5927 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5928 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5929 gst_buffer_unref (buf);
5937 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5939 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5941 GST_OBJECT_LOCK (demux);
5942 if (demux->common.element_index)
5943 gst_object_unref (demux->common.element_index);
5944 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5945 GST_OBJECT_UNLOCK (demux);
5946 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5947 demux->common.element_index);
5951 gst_matroska_demux_get_index (GstElement * element)
5953 GstIndex *result = NULL;
5954 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5956 GST_OBJECT_LOCK (demux);
5957 if (demux->common.element_index)
5958 result = gst_object_ref (demux->common.element_index);
5959 GST_OBJECT_UNLOCK (demux);
5961 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5967 static GstStateChangeReturn
5968 gst_matroska_demux_change_state (GstElement * element,
5969 GstStateChange transition)
5971 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5972 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5974 /* handle upwards state changes here */
5975 switch (transition) {
5980 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5982 /* handle downwards state changes */
5983 switch (transition) {
5984 case GST_STATE_CHANGE_PAUSED_TO_READY:
5985 gst_matroska_demux_reset (GST_ELEMENT (demux));
5995 gst_matroska_demux_set_property (GObject * object,
5996 guint prop_id, const GValue * value, GParamSpec * pspec)
5998 GstMatroskaDemux *demux;
6000 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6001 demux = GST_MATROSKA_DEMUX (object);
6004 case PROP_MAX_GAP_TIME:
6005 GST_OBJECT_LOCK (demux);
6006 demux->max_gap_time = g_value_get_uint64 (value);
6007 GST_OBJECT_UNLOCK (demux);
6010 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6016 gst_matroska_demux_get_property (GObject * object,
6017 guint prop_id, GValue * value, GParamSpec * pspec)
6019 GstMatroskaDemux *demux;
6021 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6022 demux = GST_MATROSKA_DEMUX (object);
6025 case PROP_MAX_GAP_TIME:
6026 GST_OBJECT_LOCK (demux);
6027 g_value_set_uint64 (value, demux->max_gap_time);
6028 GST_OBJECT_UNLOCK (demux);
6031 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6037 gst_matroska_demux_plugin_init (GstPlugin * plugin)
6041 /* parser helper separate debug */
6042 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
6043 0, "EBML stream helper class");
6045 /* create an elementfactory for the matroska_demux element */
6046 if (!gst_element_register (plugin, "matroskademux",
6047 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))