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;
943 /* name of this track */
944 case GST_MATROSKA_ID_TRACKNAME:{
947 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
950 context->name = text;
951 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
955 /* language (matters for audio/subtitles, mostly) */
956 case GST_MATROSKA_ID_TRACKLANGUAGE:{
959 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
963 context->language = text;
966 if (strlen (context->language) >= 4 && context->language[3] == '-')
967 context->language[3] = '\0';
969 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
970 GST_STR_NULL (context->language));
974 /* whether this is actually used */
975 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
978 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
982 context->flags |= GST_MATROSKA_TRACK_ENABLED;
984 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
986 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
987 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
991 /* whether it's the default for this track type */
992 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
995 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
999 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1001 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1003 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1004 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
1008 /* whether the track must be used during playback */
1009 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1012 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1016 context->flags |= GST_MATROSKA_TRACK_FORCED;
1018 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1020 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1021 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
1025 /* lacing (like MPEG, where blocks don't end/start on frame
1027 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1030 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1034 context->flags |= GST_MATROSKA_TRACK_LACING;
1036 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1038 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1039 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
1043 /* default length (in time) of one data block in this track */
1044 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1047 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1052 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1056 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1058 context->default_duration = num;
1062 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1063 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1068 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1071 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1075 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1079 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1080 context->timecodescale = num;
1085 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1088 /* we ignore these because they're nothing useful (i.e. crap)
1089 * or simply not implemented yet. */
1090 case GST_MATROSKA_ID_TRACKMINCACHE:
1091 case GST_MATROSKA_ID_TRACKMAXCACHE:
1092 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1093 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1094 case GST_MATROSKA_ID_TRACKOVERLAY:
1095 case GST_MATROSKA_ID_TRACKTRANSLATE:
1096 case GST_MATROSKA_ID_TRACKOFFSET:
1097 case GST_MATROSKA_ID_CODECSETTINGS:
1098 case GST_MATROSKA_ID_CODECINFOURL:
1099 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1100 case GST_MATROSKA_ID_CODECDECODEALL:
1101 ret = gst_ebml_read_skip (ebml);
1106 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1108 /* Decode codec private data if necessary */
1109 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1110 && context->codec_priv_size > 0) {
1111 if (!gst_matroska_decode_data (context->encodings,
1112 &context->codec_priv, &context->codec_priv_size,
1113 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1114 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1115 ret = GST_FLOW_ERROR;
1119 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1120 && ret != GST_FLOW_EOS)) {
1121 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1122 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1124 demux->common.num_streams--;
1125 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1126 g_assert (demux->common.src->len == demux->common.num_streams);
1127 gst_matroska_track_free (context);
1132 /* check for a cached track taglist */
1134 (GstTagList *) g_hash_table_lookup (demux->common.cached_track_taglists,
1135 GUINT_TO_POINTER (context->uid));
1137 gst_tag_list_insert (context->tags, cached_taglist, GST_TAG_MERGE_APPEND);
1139 /* now create the GStreamer connectivity */
1140 switch (context->type) {
1141 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1142 GstMatroskaTrackVideoContext *videocontext =
1143 (GstMatroskaTrackVideoContext *) context;
1145 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1146 templ = gst_element_class_get_pad_template (klass, "video_%u");
1147 caps = gst_matroska_demux_video_caps (videocontext,
1148 context->codec_id, context->codec_priv,
1149 context->codec_priv_size, &codec, &riff_fourcc);
1152 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1153 GST_TAG_VIDEO_CODEC, codec, NULL);
1154 context->tags_changed = TRUE;
1160 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1161 GstMatroskaTrackAudioContext *audiocontext =
1162 (GstMatroskaTrackAudioContext *) context;
1164 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1165 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1166 caps = gst_matroska_demux_audio_caps (audiocontext,
1167 context->codec_id, context->codec_priv, context->codec_priv_size,
1168 &codec, &riff_audio_fmt);
1171 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1172 GST_TAG_AUDIO_CODEC, codec, NULL);
1173 context->tags_changed = TRUE;
1179 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1180 GstMatroskaTrackSubtitleContext *subtitlecontext =
1181 (GstMatroskaTrackSubtitleContext *) context;
1183 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1184 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1185 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1186 context->codec_id, context->codec_priv, context->codec_priv_size);
1190 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1191 case GST_MATROSKA_TRACK_TYPE_LOGO:
1192 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1193 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1195 /* we should already have quit by now */
1196 g_assert_not_reached ();
1199 if ((context->language == NULL || *context->language == '\0') &&
1200 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1201 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1202 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1203 context->language = g_strdup ("eng");
1206 if (context->language) {
1209 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1210 lang = gst_tag_get_language_code (context->language);
1211 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1212 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1213 context->tags_changed = TRUE;
1217 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1218 "codec_id='%s'", context->codec_id);
1219 switch (context->type) {
1220 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1221 caps = gst_caps_new_empty_simple ("video/x-unknown");
1223 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1224 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1226 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1227 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1229 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1231 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1234 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1237 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1238 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1239 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1240 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1241 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1242 GST_FOURCC_ARGS (riff_fourcc));
1243 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1246 } else if (context->stream_headers != NULL) {
1247 gst_matroska_demux_add_stream_headers_to_caps (demux,
1248 context->stream_headers, caps);
1251 /* the pad in here */
1252 context->pad = gst_pad_new_from_template (templ, padname);
1253 context->caps = caps;
1255 gst_pad_set_event_function (context->pad,
1256 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1257 gst_pad_set_query_function (context->pad,
1258 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1260 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1263 gst_pad_set_element_private (context->pad, context);
1265 gst_pad_use_fixed_caps (context->pad);
1266 gst_pad_set_active (context->pad, TRUE);
1269 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1270 "%03" G_GUINT64_FORMAT, context->uid);
1272 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1275 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1276 demux->have_group_id = TRUE;
1278 demux->have_group_id = FALSE;
1279 gst_event_unref (stream_start);
1280 } else if (!demux->have_group_id) {
1281 demux->have_group_id = TRUE;
1282 demux->group_id = gst_util_group_id_next ();
1285 stream_start = gst_event_new_stream_start (stream_id);
1287 if (demux->have_group_id)
1288 gst_event_set_group_id (stream_start, demux->group_id);
1289 stream_flags = GST_STREAM_FLAG_NONE;
1290 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1291 stream_flags |= GST_STREAM_FLAG_SPARSE;
1292 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1293 stream_flags |= GST_STREAM_FLAG_SELECT;
1294 gst_event_set_stream_flags (stream_start, stream_flags);
1295 gst_pad_push_event (context->pad, stream_start);
1296 gst_pad_set_caps (context->pad, context->caps);
1299 if (demux->common.global_tags) {
1300 GstEvent *tag_event;
1302 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1303 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1304 GST_DEBUG_OBJECT (context->pad, "Sending global_tags %p: %" GST_PTR_FORMAT,
1305 demux->common.global_tags, demux->common.global_tags);
1308 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1310 gst_pad_push_event (context->pad, tag_event);
1313 if (G_UNLIKELY (context->tags_changed)) {
1314 GST_DEBUG_OBJECT (context->pad, "Sending tags %p: %"
1315 GST_PTR_FORMAT, context->tags, context->tags);
1316 gst_pad_push_event (context->pad,
1317 gst_event_new_tag (gst_tag_list_copy (context->tags)));
1318 context->tags_changed = FALSE;
1321 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1322 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1331 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1334 gboolean res = FALSE;
1335 GstMatroskaTrackContext *context = NULL;
1338 context = gst_pad_get_element_private (pad);
1341 switch (GST_QUERY_TYPE (query)) {
1342 case GST_QUERY_POSITION:
1346 gst_query_parse_position (query, &format, NULL);
1349 if (format == GST_FORMAT_TIME) {
1350 GST_OBJECT_LOCK (demux);
1352 gst_query_set_position (query, GST_FORMAT_TIME,
1353 MAX (context->pos, demux->stream_start_time) -
1354 demux->stream_start_time);
1356 gst_query_set_position (query, GST_FORMAT_TIME,
1357 MAX (demux->common.segment.position, demux->stream_start_time) -
1358 demux->stream_start_time);
1359 GST_OBJECT_UNLOCK (demux);
1360 } else if (format == GST_FORMAT_DEFAULT && context
1361 && context->default_duration) {
1362 GST_OBJECT_LOCK (demux);
1363 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1364 context->pos / context->default_duration);
1365 GST_OBJECT_UNLOCK (demux);
1367 GST_DEBUG_OBJECT (demux,
1368 "only position query in TIME and DEFAULT format is supported");
1374 case GST_QUERY_DURATION:
1378 gst_query_parse_duration (query, &format, NULL);
1381 if (format == GST_FORMAT_TIME) {
1382 GST_OBJECT_LOCK (demux);
1383 gst_query_set_duration (query, GST_FORMAT_TIME,
1384 demux->common.segment.duration);
1385 GST_OBJECT_UNLOCK (demux);
1386 } else if (format == GST_FORMAT_DEFAULT && context
1387 && context->default_duration) {
1388 GST_OBJECT_LOCK (demux);
1389 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1390 demux->common.segment.duration / context->default_duration);
1391 GST_OBJECT_UNLOCK (demux);
1393 GST_DEBUG_OBJECT (demux,
1394 "only duration query in TIME and DEFAULT format is supported");
1400 case GST_QUERY_SEEKING:
1404 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1405 GST_OBJECT_LOCK (demux);
1406 if (fmt == GST_FORMAT_TIME) {
1409 if (demux->streaming) {
1410 /* assuming we'll be able to get an index ... */
1411 seekable = demux->seekable;
1416 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1417 0, demux->common.segment.duration);
1420 GST_OBJECT_UNLOCK (demux);
1423 case GST_QUERY_SEGMENT:
1428 format = demux->common.segment.format;
1431 gst_segment_to_stream_time (&demux->common.segment, format,
1432 demux->common.segment.start);
1433 if ((stop = demux->common.segment.stop) == -1)
1434 stop = demux->common.segment.duration;
1437 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1439 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1446 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1449 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1458 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1460 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1464 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1467 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1469 return gst_matroska_demux_query (demux, pad, query);
1472 /* returns FALSE if there are no pads to deliver event to,
1473 * otherwise TRUE (whatever the outcome of event sending),
1474 * takes ownership of the passed event! */
1476 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1478 gboolean ret = FALSE;
1481 g_return_val_if_fail (event != NULL, FALSE);
1483 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1484 GST_EVENT_TYPE_NAME (event));
1486 g_assert (demux->common.src->len == demux->common.num_streams);
1487 for (i = 0; i < demux->common.src->len; i++) {
1488 GstMatroskaTrackContext *stream;
1490 stream = g_ptr_array_index (demux->common.src, i);
1491 gst_event_ref (event);
1492 gst_pad_push_event (stream->pad, event);
1496 gst_event_unref (event);
1501 gst_matroska_demux_send_tags (GstMatroskaDemux * demux)
1505 if (G_UNLIKELY (demux->common.global_tags_changed)) {
1506 GstEvent *tag_event;
1507 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1508 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1509 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1510 demux->common.global_tags, demux->common.global_tags);
1513 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1515 for (i = 0; i < demux->common.src->len; i++) {
1516 GstMatroskaTrackContext *stream;
1518 stream = g_ptr_array_index (demux->common.src, i);
1519 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1522 gst_event_unref (tag_event);
1523 demux->common.global_tags_changed = FALSE;
1526 g_assert (demux->common.src->len == demux->common.num_streams);
1527 for (i = 0; i < demux->common.src->len; i++) {
1528 GstMatroskaTrackContext *stream;
1530 stream = g_ptr_array_index (demux->common.src, i);
1532 if (G_UNLIKELY (stream->tags_changed)) {
1533 GST_DEBUG_OBJECT (demux, "Sending tags %p for pad %s:%s : %"
1534 GST_PTR_FORMAT, stream->tags,
1535 GST_DEBUG_PAD_NAME (stream->pad), stream->tags);
1536 gst_pad_push_event (stream->pad,
1537 gst_event_new_tag (gst_tag_list_copy (stream->tags)));
1538 stream->tags_changed = FALSE;
1544 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1546 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1549 g_return_val_if_fail (event != NULL, FALSE);
1551 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1552 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1554 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1555 GST_EVENT_TYPE_NAME (event));
1558 gst_event_unref (event);
1563 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1564 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1568 GST_OBJECT_LOCK (demux);
1571 /* seek (relative to matroska segment) */
1572 /* position might be invalid; will error when streaming resumes ... */
1573 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1574 demux->next_cluster_offset = 0;
1576 GST_DEBUG_OBJECT (demux,
1577 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1578 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1579 entry->block, GST_TIME_ARGS (entry->time));
1581 /* update the time */
1582 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1583 gst_flow_combiner_reset (demux->flowcombiner);
1584 demux->common.segment.position = entry->time;
1585 demux->seek_block = entry->block;
1586 demux->seek_first = TRUE;
1587 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1590 for (i = 0; i < demux->common.src->len; i++) {
1591 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1594 stream->to_offset = G_MAXINT64;
1596 if (stream->from_offset != -1)
1597 stream->to_offset = stream->from_offset;
1599 stream->from_offset = -1;
1600 stream->from_time = GST_CLOCK_TIME_NONE;
1603 GST_OBJECT_UNLOCK (demux);
1609 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1619 /* searches for a cluster start from @pos,
1620 * return GST_FLOW_OK and cluster position in @pos if found */
1621 static GstFlowReturn
1622 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1624 gint64 newpos = *pos;
1626 GstFlowReturn ret = GST_FLOW_OK;
1627 const guint chunk = 64 * 1024;
1628 GstBuffer *buf = NULL;
1630 gpointer data = NULL;
1635 gint64 oldpos, oldlength;
1637 orig_offset = demux->common.offset;
1639 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1642 if (demux->clusters) {
1645 cpos = gst_util_array_binary_search (demux->clusters->data,
1646 demux->clusters->len, sizeof (gint64),
1647 (GCompareDataFunc) gst_matroska_cluster_compare,
1648 GST_SEARCH_MODE_AFTER, pos, NULL);
1651 GST_DEBUG_OBJECT (demux,
1652 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1653 demux->common.offset = *cpos;
1654 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1655 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1656 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1663 /* read in at newpos and scan for ebml cluster id */
1664 oldpos = oldlength = -1;
1666 GstByteReader reader;
1670 gst_buffer_unmap (buf, &map);
1671 gst_buffer_unref (buf);
1674 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1675 if (ret != GST_FLOW_OK)
1677 GST_DEBUG_OBJECT (demux,
1678 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1679 gst_buffer_get_size (buf), newpos);
1680 gst_buffer_map (buf, &map, GST_MAP_READ);
1683 if (oldpos == newpos && oldlength == map.size) {
1684 GST_ERROR_OBJECT (demux, "Stuck at same position");
1685 ret = GST_FLOW_ERROR;
1689 oldlength = map.size;
1692 gst_byte_reader_init (&reader, data, size);
1694 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1695 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1696 if (cluster_pos >= 0) {
1697 newpos += cluster_pos;
1698 /* prepare resuming at next byte */
1699 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1700 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1703 GST_DEBUG_OBJECT (demux,
1704 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1705 /* extra checks whether we really sync'ed to a cluster:
1706 * - either it is the first and only cluster
1707 * - either there is a cluster after this one
1708 * - either cluster length is undefined
1710 /* ok if first cluster (there may not a subsequent one) */
1711 if (newpos == demux->first_cluster_offset) {
1712 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1715 demux->common.offset = newpos;
1716 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1717 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1718 if (ret != GST_FLOW_OK) {
1719 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1722 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1723 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1725 /* ok if undefined length or first cluster */
1726 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1727 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1731 demux->common.offset += length + needed;
1732 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1733 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1734 if (ret != GST_FLOW_OK)
1736 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1737 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1738 if (id == GST_MATROSKA_ID_CLUSTER)
1740 /* not ok, resume */
1743 /* partial cluster id may have been in tail of buffer */
1744 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1749 gst_buffer_unmap (buf, &map);
1750 gst_buffer_unref (buf);
1755 demux->common.offset = orig_offset;
1760 /* bisect and scan through file for cluster starting before @time,
1761 * returns fake index entry with corresponding info on cluster */
1762 static GstMatroskaIndex *
1763 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1765 GstMatroskaIndex *entry = NULL;
1766 GstMatroskaReadState current_state;
1767 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1768 gint64 opos, newpos, startpos = 0, current_offset;
1769 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1770 const guint chunk = 64 * 1024;
1776 /* (under)estimate new position, resync using cluster ebml id,
1777 * and scan forward to appropriate cluster
1778 * (and re-estimate if need to go backward) */
1780 prev_cluster_time = GST_CLOCK_TIME_NONE;
1782 /* store some current state */
1783 current_state = demux->common.state;
1784 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1786 current_cluster_offset = demux->cluster_offset;
1787 current_cluster_time = demux->cluster_time;
1788 current_offset = demux->common.offset;
1790 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1792 /* estimate using start and current position */
1793 GST_OBJECT_LOCK (demux);
1794 opos = demux->common.offset - demux->common.ebml_segment_start;
1795 otime = demux->common.segment.position;
1796 GST_OBJECT_UNLOCK (demux);
1799 time = MAX (time, demux->stream_start_time);
1801 /* avoid division by zero in first estimation below */
1802 if (otime <= demux->stream_start_time)
1806 GST_LOG_OBJECT (demux,
1807 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1808 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1809 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1810 GST_TIME_ARGS (otime - demux->stream_start_time),
1811 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1813 if (otime <= demux->stream_start_time) {
1817 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1818 time - demux->stream_start_time,
1819 otime - demux->stream_start_time) - chunk;
1823 /* favour undershoot */
1824 newpos = newpos * 90 / 100;
1825 newpos += demux->common.ebml_segment_start;
1827 GST_DEBUG_OBJECT (demux,
1828 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1829 GST_TIME_ARGS (time), newpos);
1831 /* and at least start scanning before previous scan start to avoid looping */
1832 startpos = startpos * 90 / 100;
1833 if (startpos && startpos < newpos)
1836 /* read in at newpos and scan for ebml cluster id */
1840 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1841 if (ret == GST_FLOW_EOS) {
1842 /* heuristic HACK */
1843 newpos = startpos * 80 / 100;
1844 GST_DEBUG_OBJECT (demux, "EOS; "
1845 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1846 GST_TIME_ARGS (time), newpos);
1849 } else if (ret != GST_FLOW_OK) {
1856 /* then start scanning and parsing for cluster time,
1857 * re-estimate if overshoot, otherwise next cluster and so on */
1858 demux->common.offset = newpos;
1859 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1861 guint64 cluster_size = 0;
1863 /* peek and parse some elements */
1864 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1865 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1866 if (ret != GST_FLOW_OK)
1868 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1869 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1871 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1872 if (ret != GST_FLOW_OK)
1875 if (id == GST_MATROSKA_ID_CLUSTER) {
1876 cluster_time = GST_CLOCK_TIME_NONE;
1877 if (length == G_MAXUINT64)
1880 cluster_size = length + needed;
1882 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1883 cluster_time == GST_CLOCK_TIME_NONE) {
1884 cluster_time = demux->cluster_time * demux->common.time_scale;
1885 cluster_offset = demux->cluster_offset;
1886 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1887 " with time %" GST_TIME_FORMAT, cluster_offset,
1888 GST_TIME_ARGS (cluster_time));
1889 if (cluster_time > time) {
1890 GST_DEBUG_OBJECT (demux, "overshot target");
1891 /* cluster overshoots */
1892 if (cluster_offset == demux->first_cluster_offset) {
1893 /* but no prev one */
1894 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1895 prev_cluster_time = cluster_time;
1896 prev_cluster_offset = cluster_offset;
1899 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1900 /* prev cluster did not overshoot, so prev cluster is target */
1903 /* re-estimate using this new position info */
1904 opos = cluster_offset;
1905 otime = cluster_time;
1909 /* cluster undershoots, goto next one */
1910 prev_cluster_time = cluster_time;
1911 prev_cluster_offset = cluster_offset;
1912 /* skip cluster if length is defined,
1913 * otherwise will be skippingly parsed into */
1915 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1916 demux->common.offset = cluster_offset + cluster_size;
1917 demux->cluster_time = GST_CLOCK_TIME_NONE;
1919 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1926 if (ret == GST_FLOW_EOS) {
1927 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1933 entry = g_new0 (GstMatroskaIndex, 1);
1934 entry->time = prev_cluster_time;
1935 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1936 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1937 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1941 /* restore some state */
1942 demux->cluster_offset = current_cluster_offset;
1943 demux->cluster_time = current_cluster_time;
1944 demux->common.offset = current_offset;
1945 demux->common.state = current_state;
1951 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1952 GstPad * pad, GstEvent * event)
1954 GstMatroskaIndex *entry = NULL;
1955 GstMatroskaIndex scan_entry;
1957 GstSeekType cur_type, stop_type;
1959 gboolean flush, keyunit, before, after, snap_next;
1962 GstMatroskaTrackContext *track = NULL;
1963 GstSegment seeksegment = { 0, };
1964 gboolean update = TRUE;
1965 gboolean pad_locked = FALSE;
1967 GstSearchMode snap_dir;
1969 g_return_val_if_fail (event != NULL, FALSE);
1972 track = gst_pad_get_element_private (pad);
1974 GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
1976 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1978 seqnum = gst_event_get_seqnum (event);
1980 /* we can only seek on time */
1981 if (format != GST_FORMAT_TIME) {
1982 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
1986 /* copy segment, we need this because we still need the old
1987 * segment when we close the current segment. */
1988 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
1990 /* pull mode without index means that the actual duration is not known,
1991 * we might be playing a file that's still being recorded
1992 * so, invalidate our current duration, which is only a moving target,
1993 * and should not be used to clamp anything */
1994 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
1995 seeksegment.duration = GST_CLOCK_TIME_NONE;
1998 GST_DEBUG_OBJECT (demux, "configuring seek");
1999 /* Subtract stream_start_time so we always seek on a segment
2001 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2002 seeksegment.start -= demux->stream_start_time;
2003 seeksegment.position -= demux->stream_start_time;
2004 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2005 seeksegment.stop -= demux->stream_start_time;
2007 seeksegment.stop = seeksegment.duration;
2010 gst_segment_do_seek (&seeksegment, rate, format, flags,
2011 cur_type, cur, stop_type, stop, &update);
2013 /* Restore the clip timestamp offset */
2014 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2015 seeksegment.position += demux->stream_start_time;
2016 seeksegment.start += demux->stream_start_time;
2017 if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2018 seeksegment.stop = seeksegment.duration;
2019 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2020 seeksegment.stop += demux->stream_start_time;
2023 /* restore segment duration (if any effect),
2024 * would be determined again when parsing, but anyway ... */
2025 seeksegment.duration = demux->common.segment.duration;
2027 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2028 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2029 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
2030 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
2032 /* always do full update if flushing,
2033 * otherwise problems might arise downstream with missing keyframes etc */
2034 update = update || flush;
2036 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2038 /* check sanity before we start flushing and all that */
2039 snap_next = after && !before;
2040 if (seeksegment.rate < 0)
2041 snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
2043 snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
2045 GST_OBJECT_LOCK (demux);
2046 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2047 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2048 seeksegment.position, &demux->seek_index, &demux->seek_entry,
2049 snap_dir)) == NULL) {
2050 /* pull mode without index can scan later on */
2051 if (demux->streaming) {
2052 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2053 GST_OBJECT_UNLOCK (demux);
2055 } else if (rate < 0.0) {
2056 /* FIXME: We should build an index during playback or when scanning
2057 * that can be used here. The reverse playback code requires seek_index
2058 * and seek_entry to be set!
2060 GST_DEBUG_OBJECT (demux,
2061 "No matching seek entry in index, needed for reverse playback");
2062 GST_OBJECT_UNLOCK (demux);
2066 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2067 GST_OBJECT_UNLOCK (demux);
2070 /* only have to update some segment,
2071 * but also still have to honour flush and so on */
2072 GST_DEBUG_OBJECT (demux, "... no update");
2073 /* bad goto, bad ... */
2077 if (demux->streaming)
2082 GstEvent *flush_event = gst_event_new_flush_start ();
2083 gst_event_set_seqnum (flush_event, seqnum);
2084 GST_DEBUG_OBJECT (demux, "Starting flush");
2085 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2086 gst_matroska_demux_send_event (demux, flush_event);
2088 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2089 gst_pad_pause_task (demux->common.sinkpad);
2093 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2098 /* now grab the stream lock so that streaming cannot continue, for
2099 * non flushing seeks when the element is in PAUSED this could block
2101 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2102 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2105 /* pull mode without index can do some scanning */
2106 if (!demux->streaming && !entry) {
2107 GstEvent *flush_event;
2109 /* need to stop flushing upstream as we need it next */
2111 flush_event = gst_event_new_flush_stop (TRUE);
2112 gst_event_set_seqnum (flush_event, seqnum);
2113 gst_pad_push_event (demux->common.sinkpad, flush_event);
2115 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2116 /* keep local copy */
2118 scan_entry = *entry;
2120 entry = &scan_entry;
2122 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2124 flush_event = gst_event_new_flush_stop (TRUE);
2125 gst_event_set_seqnum (flush_event, seqnum);
2126 gst_matroska_demux_send_event (demux, flush_event);
2134 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2135 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2136 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2137 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2138 seeksegment.position = seeksegment.start;
2139 seeksegment.time = seeksegment.start - demux->stream_start_time;
2142 if (demux->streaming) {
2143 GST_OBJECT_LOCK (demux);
2144 /* track real position we should start at */
2145 GST_DEBUG_OBJECT (demux, "storing segment start");
2146 demux->requested_seek_time = seeksegment.position;
2147 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2148 GST_OBJECT_UNLOCK (demux);
2149 /* need to seek to cluster start to pick up cluster time */
2150 /* upstream takes care of flushing and all that
2151 * ... and newsegment event handling takes care of the rest */
2152 return perform_seek_to_offset (demux, rate,
2153 entry->pos + demux->common.ebml_segment_start, seqnum);
2158 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2159 gst_event_set_seqnum (flush_event, seqnum);
2160 GST_DEBUG_OBJECT (demux, "Stopping flush");
2161 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2162 gst_matroska_demux_send_event (demux, flush_event);
2165 GST_OBJECT_LOCK (demux);
2166 /* now update the real segment info */
2167 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2168 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2169 GST_OBJECT_UNLOCK (demux);
2171 /* update some (segment) state */
2172 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2175 /* notify start of new segment */
2176 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2179 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2180 GST_FORMAT_TIME, demux->common.segment.start);
2181 gst_message_set_seqnum (msg, seqnum);
2182 gst_element_post_message (GST_ELEMENT (demux), msg);
2185 GST_OBJECT_LOCK (demux);
2186 if (demux->new_segment)
2187 gst_event_unref (demux->new_segment);
2189 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2190 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2191 gst_event_set_seqnum (demux->new_segment, seqnum);
2192 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2193 demux->to_time = demux->common.segment.position;
2195 demux->to_time = GST_CLOCK_TIME_NONE;
2196 GST_OBJECT_UNLOCK (demux);
2198 /* restart our task since it might have been stopped when we did the
2200 gst_pad_start_task (demux->common.sinkpad,
2201 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2203 /* streaming can continue now */
2205 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2213 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2215 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2221 * Handle whether we can perform the seek event or if we have to let the chain
2222 * function handle seeks to build the seek indexes first.
2225 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2229 GstSeekType cur_type, stop_type;
2234 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2239 /* we can only seek on time */
2240 if (format != GST_FORMAT_TIME) {
2241 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2245 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2246 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2250 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2251 GST_DEBUG_OBJECT (demux,
2252 "Non-flushing seek not supported in streaming mode");
2256 if (flags & GST_SEEK_FLAG_SEGMENT) {
2257 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2261 /* check for having parsed index already */
2262 if (!demux->common.index_parsed) {
2263 gboolean building_index;
2266 if (!demux->index_offset) {
2267 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2271 GST_OBJECT_LOCK (demux);
2272 /* handle the seek event in the chain function */
2273 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2274 /* no more seek can be issued until state reset to _DATA */
2276 /* copy the event */
2277 if (demux->seek_event)
2278 gst_event_unref (demux->seek_event);
2279 demux->seek_event = gst_event_ref (event);
2281 /* set the building_index flag so that only one thread can setup the
2282 * structures for index seeking. */
2283 building_index = demux->building_index;
2284 if (!building_index) {
2285 demux->building_index = TRUE;
2286 offset = demux->index_offset;
2288 GST_OBJECT_UNLOCK (demux);
2290 if (!building_index) {
2291 /* seek to the first subindex or legacy index */
2292 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2293 return perform_seek_to_offset (demux, rate, offset,
2294 gst_event_get_seqnum (event));
2297 /* well, we are handling it already */
2301 /* delegate to tweaked regular seek */
2302 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2306 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2309 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2310 gboolean res = TRUE;
2312 switch (GST_EVENT_TYPE (event)) {
2313 case GST_EVENT_SEEK:
2314 /* no seeking until we are (safely) ready */
2315 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2316 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2319 if (!demux->streaming)
2320 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2322 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2323 gst_event_unref (event);
2328 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2329 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2330 GstMatroskaTrackVideoContext *videocontext =
2331 (GstMatroskaTrackVideoContext *) context;
2333 GstClockTimeDiff diff;
2334 GstClockTime timestamp;
2336 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2338 GST_OBJECT_LOCK (demux);
2339 videocontext->earliest_time = timestamp + diff;
2340 GST_OBJECT_UNLOCK (demux);
2343 gst_event_unref (event);
2347 case GST_EVENT_TOC_SELECT:
2350 GstTocEntry *entry = NULL;
2351 GstEvent *seek_event;
2354 if (!demux->common.toc) {
2355 GST_DEBUG_OBJECT (demux, "no TOC to select");
2358 gst_event_parse_toc_select (event, &uid);
2360 GST_OBJECT_LOCK (demux);
2361 entry = gst_toc_find_entry (demux->common.toc, uid);
2362 if (entry == NULL) {
2363 GST_OBJECT_UNLOCK (demux);
2364 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2367 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2368 GST_OBJECT_UNLOCK (demux);
2369 seek_event = gst_event_new_seek (1.0,
2371 GST_SEEK_FLAG_FLUSH,
2372 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2373 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2374 gst_event_unref (seek_event);
2378 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2382 gst_event_unref (event);
2386 /* events we don't need to handle */
2387 case GST_EVENT_NAVIGATION:
2388 gst_event_unref (event);
2392 case GST_EVENT_LATENCY:
2394 res = gst_pad_push_event (demux->common.sinkpad, event);
2401 static GstFlowReturn
2402 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2404 GstFlowReturn ret = GST_FLOW_EOS;
2405 gboolean done = TRUE;
2408 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2409 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2412 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2414 if (!demux->seek_entry) {
2415 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2419 for (i = 0; i < demux->common.src->len; i++) {
2420 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2422 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2423 ", stream %d at %" GST_TIME_FORMAT,
2424 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2425 GST_TIME_ARGS (stream->from_time));
2426 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2427 if (stream->from_time > demux->common.segment.start) {
2428 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2432 /* nothing pushed for this stream;
2433 * likely seek entry did not start at keyframe, so all was skipped.
2434 * So we need an earlier entry */
2440 GstMatroskaIndex *entry;
2442 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2443 --demux->seek_entry);
2444 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2454 static GstFlowReturn
2455 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2457 GstFlowReturn ret = GST_FLOW_OK;
2460 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2462 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2463 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2467 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2468 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2472 /* one track within the "all-tracks" header */
2473 case GST_MATROSKA_ID_TRACKENTRY:
2474 ret = gst_matroska_demux_add_stream (demux, ebml);
2478 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2483 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2485 demux->tracks_parsed = TRUE;
2491 * Read signed/unsigned "EBML" numbers.
2492 * Return: number of bytes processed.
2496 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2498 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2506 while (read <= 8 && !(total & len_mask)) {
2513 if ((total &= (len_mask - 1)) == len_mask - 1)
2518 if (data[n] == 0xff)
2520 total = (total << 8) | data[n];
2524 if (read == num_ffs && total != 0)
2533 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2538 /* read as unsigned number first */
2539 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2543 if (unum == G_MAXUINT64)
2546 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2552 * Mostly used for subtitles. We add void filler data for each
2553 * lagging stream to make sure we don't deadlock.
2557 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2561 GST_OBJECT_LOCK (demux);
2563 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2564 GST_TIME_ARGS (demux->common.segment.position));
2566 g_assert (demux->common.num_streams == demux->common.src->len);
2567 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2568 GstMatroskaTrackContext *context;
2570 context = g_ptr_array_index (demux->common.src, stream_nr);
2572 GST_LOG_OBJECT (demux,
2573 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2574 GST_TIME_ARGS (context->pos));
2576 if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
2577 GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
2581 /* does it lag? 0.5 seconds is a random threshold...
2582 * lag need only be considered if we have advanced into requested segment */
2583 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2584 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2585 demux->common.segment.position > demux->common.segment.start &&
2586 context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
2589 guint64 start = context->pos;
2590 guint64 stop = demux->common.segment.position - (GST_SECOND / 2);
2592 GST_DEBUG_OBJECT (demux,
2593 "Synchronizing stream %d with other by advancing time from %"
2594 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2595 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2597 context->pos = stop;
2599 event = gst_event_new_gap (start, stop - start);
2600 GST_OBJECT_UNLOCK (demux);
2601 gst_pad_push_event (context->pad, event);
2602 GST_OBJECT_LOCK (demux);
2606 GST_OBJECT_UNLOCK (demux);
2609 static GstFlowReturn
2610 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2611 GstMatroskaTrackContext * stream)
2613 GstFlowReturn ret = GST_FLOW_OK;
2616 num = gst_buffer_list_length (stream->stream_headers);
2617 for (i = 0; i < num; ++i) {
2620 buf = gst_buffer_list_get (stream->stream_headers, i);
2621 buf = gst_buffer_copy (buf);
2623 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2625 if (stream->set_discont) {
2626 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2627 stream->set_discont = FALSE;
2629 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2632 /* push out all headers in one go and use last flow return */
2633 ret = gst_pad_push (stream->pad, buf);
2636 /* don't need these any longer */
2637 gst_buffer_list_unref (stream->stream_headers);
2638 stream->stream_headers = NULL;
2641 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2647 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2648 GstMatroskaTrackContext * stream)
2652 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2654 if (!stream->codec_priv)
2657 /* ideally, VobSub private data should be parsed and stored more convenient
2658 * elsewhere, but for now, only interested in a small part */
2660 /* make sure we have terminating 0 */
2661 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2663 /* just locate and parse palette part */
2664 start = strstr (buf, "palette:");
2669 guint8 r, g, b, y, u, v;
2672 while (g_ascii_isspace (*start))
2674 for (i = 0; i < 16; i++) {
2675 if (sscanf (start, "%06x", &col) != 1)
2678 while ((*start == ',') || g_ascii_isspace (*start))
2680 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2681 r = (col >> 16) & 0xff;
2682 g = (col >> 8) & 0xff;
2684 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2686 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2687 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2688 clut[i] = (y << 16) | (u << 8) | v;
2691 /* got them all without problems; build and send event */
2695 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2696 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2697 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2698 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2699 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2700 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2701 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2702 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2703 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2704 G_TYPE_INT, clut[15], NULL);
2706 gst_pad_push_event (stream->pad,
2707 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2714 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2718 GST_OBJECT_LOCK (demux);
2720 g_assert (demux->common.num_streams == demux->common.src->len);
2721 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2722 GstMatroskaTrackContext *stream;
2724 stream = g_ptr_array_index (demux->common.src, stream_nr);
2726 if (stream->send_stream_headers) {
2727 if (stream->stream_headers != NULL) {
2728 gst_matroska_demux_push_stream_headers (demux, stream);
2730 /* FIXME: perhaps we can just disable and skip this stream then */
2731 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2732 ("Failed to extract stream headers from codec private data"));
2734 stream->send_stream_headers = FALSE;
2737 if (stream->send_dvd_event) {
2738 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2739 /* FIXME: should we send this event again after (flushing) seek ? */
2740 stream->send_dvd_event = FALSE;
2744 GST_OBJECT_UNLOCK (demux);
2747 static GstFlowReturn
2748 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2749 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2752 guint seq_header_len;
2753 guint32 header, tmp;
2755 if (stream->codec_state) {
2756 seq_header = stream->codec_state;
2757 seq_header_len = stream->codec_state_size;
2758 } else if (stream->codec_priv) {
2759 seq_header = stream->codec_priv;
2760 seq_header_len = stream->codec_priv_size;
2765 /* Sequence header only needed for keyframes */
2766 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2769 if (gst_buffer_get_size (*buf) < 4)
2772 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2773 header = GUINT32_FROM_BE (tmp);
2775 /* Sequence start code, if not found prepend */
2776 if (header != 0x000001b3) {
2779 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2781 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2784 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2785 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2786 gst_buffer_get_size (*buf));
2788 gst_buffer_unref (*buf);
2795 static GstFlowReturn
2796 gst_matroska_demux_add_wvpk_header (GstElement * element,
2797 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2799 GstMatroskaTrackAudioContext *audiocontext =
2800 (GstMatroskaTrackAudioContext *) stream;
2801 GstBuffer *newbuf = NULL;
2802 GstMapInfo map, outmap;
2803 guint8 *buf_data, *data;
2811 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2814 wvh.total_samples = -1;
2815 wvh.block_index = audiocontext->wvpk_block_index;
2817 if (audiocontext->channels <= 2) {
2818 guint32 block_samples, tmp;
2819 gsize size = gst_buffer_get_size (*buf);
2821 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2822 block_samples = GUINT32_FROM_LE (tmp);
2823 /* we need to reconstruct the header of the wavpack block */
2825 /* -20 because ck_size is the size of the wavpack block -8
2826 * and lace_size is the size of the wavpack block + 12
2827 * (the three guint32 of the header that already are in the buffer) */
2828 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2830 /* block_samples, flags and crc are already in the buffer */
2831 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2833 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2839 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2840 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2841 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2842 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2843 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2844 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2846 /* Append data from buf: */
2847 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2848 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2850 gst_buffer_unref (*buf);
2852 audiocontext->wvpk_block_index += block_samples;
2854 guint8 *outdata = NULL;
2856 gsize buf_size, size, out_size = 0;
2857 guint32 block_samples, flags, crc, blocksize;
2859 gst_buffer_map (*buf, &map, GST_MAP_READ);
2860 buf_data = map.data;
2861 buf_size = map.size;
2864 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2865 gst_buffer_unmap (*buf, &map);
2866 return GST_FLOW_ERROR;
2872 block_samples = GST_READ_UINT32_LE (data);
2877 flags = GST_READ_UINT32_LE (data);
2880 crc = GST_READ_UINT32_LE (data);
2883 blocksize = GST_READ_UINT32_LE (data);
2887 if (blocksize == 0 || size < blocksize)
2890 g_assert ((newbuf == NULL) == (outdata == NULL));
2892 if (newbuf == NULL) {
2893 out_size = sizeof (Wavpack4Header) + blocksize;
2894 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2896 gst_buffer_copy_into (newbuf, *buf,
2897 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2900 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2901 outdata = outmap.data;
2903 gst_buffer_unmap (newbuf, &outmap);
2904 out_size += sizeof (Wavpack4Header) + blocksize;
2905 gst_buffer_set_size (newbuf, out_size);
2906 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2907 outdata = outmap.data;
2910 outdata[outpos] = 'w';
2911 outdata[outpos + 1] = 'v';
2912 outdata[outpos + 2] = 'p';
2913 outdata[outpos + 3] = 'k';
2916 GST_WRITE_UINT32_LE (outdata + outpos,
2917 blocksize + sizeof (Wavpack4Header) - 8);
2918 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2919 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2920 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2921 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2922 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2923 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2924 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2925 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2928 memmove (outdata + outpos, data, blocksize);
2929 outpos += blocksize;
2933 gst_buffer_unmap (*buf, &map);
2934 gst_buffer_unref (*buf);
2937 gst_buffer_unmap (newbuf, &outmap);
2940 audiocontext->wvpk_block_index += block_samples;
2946 /* @text must be null-terminated */
2948 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
2953 g_return_val_if_fail (text != NULL, FALSE);
2955 /* yes, this might all lead to false positives ... */
2956 tag = (gchar *) text;
2957 while ((tag = strchr (tag, '<'))) {
2959 if (*tag != '\0' && *(tag + 1) == '>') {
2960 /* some common convenience ones */
2961 /* maybe any character will do here ? */
2974 if (strstr (text, "<span"))
2980 static GstFlowReturn
2981 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
2982 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2984 GstMatroskaTrackSubtitleContext *sub_stream;
2985 const gchar *encoding;
2990 gboolean needs_unmap = TRUE;
2992 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
2994 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
2997 /* The subtitle buffer we push out should not include a NUL terminator as
2998 * part of the data. */
2999 if (map.data[map.size - 1] == '\0') {
3000 gst_buffer_set_size (*buf, map.size - 1);
3001 gst_buffer_unmap (*buf, &map);
3002 gst_buffer_map (*buf, &map, GST_MAP_READ);
3005 if (!sub_stream->invalid_utf8) {
3006 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
3009 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
3010 " is not valid UTF-8, this is broken according to the matroska"
3011 " specification", stream->num);
3012 sub_stream->invalid_utf8 = TRUE;
3015 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3016 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3017 if (encoding == NULL || *encoding == '\0') {
3018 /* if local encoding is UTF-8 and no encoding specified
3019 * via the environment variable, assume ISO-8859-15 */
3020 if (g_get_charset (&encoding)) {
3021 encoding = "ISO-8859-15";
3026 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3027 (char *) "*", NULL, NULL, &err);
3030 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3031 encoding, err->message);
3035 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3036 encoding = "ISO-8859-15";
3038 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3039 encoding, (char *) "*", NULL, NULL, NULL);
3042 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3043 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3046 utf8 = g_strdup ("invalid subtitle");
3048 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3049 gst_buffer_unmap (*buf, &map);
3050 gst_buffer_copy_into (newbuf, *buf,
3051 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3053 gst_buffer_unref (*buf);
3056 gst_buffer_map (*buf, &map, GST_MAP_READ);
3060 if (sub_stream->check_markup) {
3061 /* caps claim markup text, so we need to escape text,
3062 * except if text is already markup and then needs no further escaping */
3063 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3064 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3066 if (!sub_stream->seen_markup_tag) {
3067 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3069 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3070 gst_buffer_unmap (*buf, &map);
3071 gst_buffer_copy_into (newbuf, *buf,
3072 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3073 GST_BUFFER_COPY_META, 0, -1);
3074 gst_buffer_unref (*buf);
3077 needs_unmap = FALSE;
3082 gst_buffer_unmap (*buf, &map);
3087 static GstFlowReturn
3088 gst_matroska_demux_check_aac (GstElement * element,
3089 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3094 gst_buffer_extract (*buf, 0, data, 2);
3095 size = gst_buffer_get_size (*buf);
3097 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3100 /* tss, ADTS data, remove codec_data
3101 * still assume it is at least parsed */
3102 stream->caps = gst_caps_make_writable (stream->caps);
3103 s = gst_caps_get_structure (stream->caps, 0);
3105 gst_structure_remove_field (s, "codec_data");
3106 gst_pad_set_caps (stream->pad, stream->caps);
3107 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3108 "new caps: %" GST_PTR_FORMAT, stream->caps);
3111 /* disable subsequent checking */
3112 stream->postprocess_frame = NULL;
3118 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3119 GstBuffer * buffer, gsize alignment)
3123 gst_buffer_map (buffer, &map, GST_MAP_READ);
3125 if (map.size < sizeof (guintptr)) {
3126 gst_buffer_unmap (buffer, &map);
3130 if (((guintptr) map.data) & (alignment - 1)) {
3131 GstBuffer *new_buffer;
3132 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3134 new_buffer = gst_buffer_new_allocate (NULL,
3135 gst_buffer_get_size (buffer), ¶ms);
3137 /* Copy data "by hand", so ensure alignment is kept: */
3138 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3140 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3141 GST_DEBUG_OBJECT (demux,
3142 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3145 gst_buffer_unmap (buffer, &map);
3146 gst_buffer_unref (buffer);
3151 gst_buffer_unmap (buffer, &map);
3155 static GstFlowReturn
3156 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3157 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3158 gboolean is_simpleblock)
3160 GstMatroskaTrackContext *stream = NULL;
3161 GstFlowReturn ret = GST_FLOW_OK;
3162 gboolean readblock = FALSE;
3164 guint64 block_duration = -1;
3165 GstBuffer *buf = NULL;
3167 gint stream_num = -1, n, laces = 0;
3169 gint *lace_size = NULL;
3172 gint64 referenceblock = 0;
3174 GstClockTime buffer_timestamp;
3176 offset = gst_ebml_read_get_offset (ebml);
3178 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3179 if (!is_simpleblock) {
3180 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3184 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3188 /* one block inside the group. Note, block parsing is one
3189 * of the harder things, so this code is a bit complicated.
3190 * See http://www.matroska.org/ for documentation. */
3191 case GST_MATROSKA_ID_SIMPLEBLOCK:
3192 case GST_MATROSKA_ID_BLOCK:
3198 gst_buffer_unmap (buf, &map);
3199 gst_buffer_unref (buf);
3202 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3205 gst_buffer_map (buf, &map, GST_MAP_READ);
3209 /* first byte(s): blocknum */
3210 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3215 /* fetch stream from num */
3216 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3218 if (G_UNLIKELY (size < 3)) {
3219 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3220 /* non-fatal, try next block(group) */
3223 } else if (G_UNLIKELY (stream_num < 0 ||
3224 stream_num >= demux->common.num_streams)) {
3225 /* let's not give up on a stray invalid track number */
3226 GST_WARNING_OBJECT (demux,
3227 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3228 "; ignoring block", stream_num, num);
3232 stream = g_ptr_array_index (demux->common.src, stream_num);
3234 /* time (relative to cluster time) */
3235 time = ((gint16) GST_READ_UINT16_BE (data));
3238 flags = GST_READ_UINT8 (data);
3242 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3245 switch ((flags & 0x06) >> 1) {
3246 case 0x0: /* no lacing */
3248 lace_size = g_new (gint, 1);
3249 lace_size[0] = size;
3252 case 0x1: /* xiph lacing */
3253 case 0x2: /* fixed-size lacing */
3254 case 0x3: /* EBML lacing */
3256 goto invalid_lacing;
3257 laces = GST_READ_UINT8 (data) + 1;
3260 lace_size = g_new0 (gint, laces);
3262 switch ((flags & 0x06) >> 1) {
3263 case 0x1: /* xiph lacing */ {
3264 guint temp, total = 0;
3266 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3269 goto invalid_lacing;
3270 temp = GST_READ_UINT8 (data);
3271 lace_size[n] += temp;
3277 total += lace_size[n];
3279 lace_size[n] = size - total;
3283 case 0x2: /* fixed-size lacing */
3284 for (n = 0; n < laces; n++)
3285 lace_size[n] = size / laces;
3288 case 0x3: /* EBML lacing */ {
3291 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3295 total = lace_size[0] = num;
3296 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3300 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3304 lace_size[n] = lace_size[n - 1] + snum;
3305 total += lace_size[n];
3308 lace_size[n] = size - total;
3315 if (ret != GST_FLOW_OK)
3322 case GST_MATROSKA_ID_BLOCKDURATION:{
3323 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3324 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3329 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3330 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3331 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3336 case GST_MATROSKA_ID_CODECSTATE:{
3338 guint64 data_len = 0;
3341 gst_ebml_read_binary (ebml, &id, &data,
3342 &data_len)) != GST_FLOW_OK)
3345 if (G_UNLIKELY (stream == NULL)) {
3346 GST_WARNING_OBJECT (demux,
3347 "Unexpected CodecState subelement - ignoring");
3351 g_free (stream->codec_state);
3352 stream->codec_state = data;
3353 stream->codec_state_size = data_len;
3355 /* Decode if necessary */
3356 if (stream->encodings && stream->encodings->len > 0
3357 && stream->codec_state && stream->codec_state_size > 0) {
3358 if (!gst_matroska_decode_data (stream->encodings,
3359 &stream->codec_state, &stream->codec_state_size,
3360 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3361 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3365 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3366 stream->codec_state_size);
3371 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3375 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3376 case GST_MATROSKA_ID_BLOCKADDITIONS:
3377 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3378 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3379 case GST_MATROSKA_ID_SLICES:
3380 GST_DEBUG_OBJECT (demux,
3381 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3382 ret = gst_ebml_read_skip (ebml);
3390 /* reading a number or so could have failed */
3391 if (ret != GST_FLOW_OK)
3394 if (ret == GST_FLOW_OK && readblock) {
3395 gboolean invisible_frame = FALSE;
3396 gboolean delta_unit = FALSE;
3397 guint64 duration = 0;
3398 gint64 lace_time = 0;
3400 stream = g_ptr_array_index (demux->common.src, stream_num);
3402 if (cluster_time != GST_CLOCK_TIME_NONE) {
3403 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3404 * Drop unless the lace contains timestamp 0? */
3405 if (time < 0 && (-time) > cluster_time) {
3408 if (stream->timecodescale == 1.0)
3409 lace_time = (cluster_time + time) * demux->common.time_scale;
3412 gst_util_guint64_to_gdouble ((cluster_time + time) *
3413 demux->common.time_scale) * stream->timecodescale;
3416 lace_time = GST_CLOCK_TIME_NONE;
3419 /* need to refresh segment info ASAP */
3420 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3421 GstSegment *segment = &demux->common.segment;
3423 GstEvent *segment_event;
3425 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3426 demux->stream_start_time = lace_time;
3427 GST_DEBUG_OBJECT (demux,
3428 "Setting stream start time to %" GST_TIME_FORMAT,
3429 GST_TIME_ARGS (lace_time));
3431 clace_time = MAX (lace_time, demux->stream_start_time);
3432 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3433 demux->common.segment.position != 0) {
3434 GST_DEBUG_OBJECT (demux,
3435 "using stored seek position %" GST_TIME_FORMAT,
3436 GST_TIME_ARGS (demux->common.segment.position));
3437 clace_time = demux->common.segment.position + demux->stream_start_time;
3438 segment->position = GST_CLOCK_TIME_NONE;
3440 segment->start = clace_time;
3441 segment->stop = GST_CLOCK_TIME_NONE;
3442 segment->time = segment->start - demux->stream_start_time;
3443 segment->position = segment->start - demux->stream_start_time;
3444 GST_DEBUG_OBJECT (demux,
3445 "generated segment starting at %" GST_TIME_FORMAT ": %"
3446 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3447 /* now convey our segment notion downstream */
3448 segment_event = gst_event_new_segment (segment);
3449 if (demux->segment_seqnum)
3450 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3451 gst_matroska_demux_send_event (demux, segment_event);
3452 demux->need_segment = FALSE;
3453 demux->segment_seqnum = 0;
3456 /* send pending codec data headers for all streams,
3457 * before we perform sync across all streams */
3458 gst_matroska_demux_push_codec_data_all (demux);
3460 if (block_duration != -1) {
3461 if (stream->timecodescale == 1.0)
3462 duration = gst_util_uint64_scale (block_duration,
3463 demux->common.time_scale, 1);
3466 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3467 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3468 1)) * stream->timecodescale);
3469 } else if (stream->default_duration) {
3470 duration = stream->default_duration * laces;
3472 /* else duration is diff between timecode of this and next block */
3474 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3475 a ReferenceBlock implies that this is not a keyframe. In either
3476 case, it only makes sense for video streams. */
3477 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3478 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3480 invisible_frame = ((flags & 0x08)) &&
3481 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3482 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3486 for (n = 0; n < laces; n++) {
3489 if (G_UNLIKELY (lace_size[n] > size)) {
3490 GST_WARNING_OBJECT (demux, "Invalid lace size");
3494 /* QoS for video track with an index. the assumption is that
3495 index entries point to keyframes, but if that is not true we
3496 will instad skip until the next keyframe. */
3497 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3498 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3499 stream->index_table && demux->common.segment.rate > 0.0) {
3500 GstMatroskaTrackVideoContext *videocontext =
3501 (GstMatroskaTrackVideoContext *) stream;
3502 GstClockTime earliest_time;
3503 GstClockTime earliest_stream_time;
3505 GST_OBJECT_LOCK (demux);
3506 earliest_time = videocontext->earliest_time;
3507 GST_OBJECT_UNLOCK (demux);
3508 earliest_stream_time =
3509 gst_segment_position_from_running_time (&demux->common.segment,
3510 GST_FORMAT_TIME, earliest_time);
3512 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3513 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3514 lace_time <= earliest_stream_time) {
3515 /* find index entry (keyframe) <= earliest_stream_time */
3516 GstMatroskaIndex *entry =
3517 gst_util_array_binary_search (stream->index_table->data,
3518 stream->index_table->len, sizeof (GstMatroskaIndex),
3519 (GCompareDataFunc) gst_matroska_index_seek_find,
3520 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3522 /* if that entry (keyframe) is after the current the current
3523 buffer, we can skip pushing (and thus decoding) all
3524 buffers until that keyframe. */
3525 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3526 entry->time > lace_time) {
3527 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3528 stream->set_discont = TRUE;
3534 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3535 gst_buffer_get_size (buf) - size, lace_size[n]);
3536 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3539 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3541 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3543 if (invisible_frame)
3544 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3546 if (stream->encodings != NULL && stream->encodings->len > 0)
3547 sub = gst_matroska_decode_buffer (stream, sub);
3550 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3554 if (!stream->dts_only) {
3555 GST_BUFFER_PTS (sub) = lace_time;
3557 GST_BUFFER_DTS (sub) = lace_time;
3558 if (stream->intra_only)
3559 GST_BUFFER_PTS (sub) = lace_time;
3562 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
3564 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3565 GstClockTime last_stop_end;
3567 /* Check if this stream is after segment stop */
3568 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3569 lace_time >= demux->common.segment.stop) {
3570 GST_DEBUG_OBJECT (demux,
3571 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3572 GST_TIME_ARGS (demux->common.segment.stop));
3573 gst_buffer_unref (sub);
3576 if (offset >= stream->to_offset
3577 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3578 && lace_time > demux->to_time)) {
3579 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3581 gst_buffer_unref (sub);
3585 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3586 * that landed us with timestamps not quite intended */
3587 GST_OBJECT_LOCK (demux);
3588 if (demux->max_gap_time &&
3589 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3590 demux->common.segment.rate > 0.0) {
3591 GstClockTimeDiff diff;
3593 /* only send segments with increasing start times,
3594 * otherwise if these go back and forth downstream (sinks) increase
3595 * accumulated time and running_time */
3596 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3597 if (diff > 0 && diff > demux->max_gap_time
3598 && lace_time > demux->common.segment.start
3599 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3600 || lace_time < demux->common.segment.stop)) {
3602 GST_DEBUG_OBJECT (demux,
3603 "Gap of %" G_GINT64_FORMAT " ns detected in"
3604 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3605 "Sending updated SEGMENT events", diff,
3606 stream->index, GST_TIME_ARGS (stream->pos),
3607 GST_TIME_ARGS (lace_time));
3609 event = gst_event_new_gap (demux->last_stop_end, diff);
3610 GST_OBJECT_UNLOCK (demux);
3611 gst_pad_push_event (stream->pad, event);
3612 GST_OBJECT_LOCK (demux);
3616 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3617 || demux->common.segment.position < lace_time) {
3618 demux->common.segment.position = lace_time;
3620 GST_OBJECT_UNLOCK (demux);
3622 last_stop_end = lace_time;
3624 GST_BUFFER_DURATION (sub) = duration / laces;
3625 last_stop_end += GST_BUFFER_DURATION (sub);
3628 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3629 demux->last_stop_end < last_stop_end)
3630 demux->last_stop_end = last_stop_end;
3632 GST_OBJECT_LOCK (demux);
3633 if (demux->common.segment.duration == -1 ||
3634 demux->stream_start_time + demux->common.segment.duration <
3636 demux->common.segment.duration =
3637 last_stop_end - demux->stream_start_time;
3638 GST_OBJECT_UNLOCK (demux);
3639 if (!demux->invalid_duration) {
3640 gst_element_post_message (GST_ELEMENT_CAST (demux),
3641 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3642 demux->invalid_duration = TRUE;
3645 GST_OBJECT_UNLOCK (demux);
3649 stream->pos = lace_time;
3651 gst_matroska_demux_sync_streams (demux);
3653 if (stream->set_discont) {
3654 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3655 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3656 stream->set_discont = FALSE;
3658 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3661 /* reverse playback book-keeping */
3662 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3663 stream->from_time = lace_time;
3664 if (stream->from_offset == -1)
3665 stream->from_offset = offset;
3667 GST_DEBUG_OBJECT (demux,
3668 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3669 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3670 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3671 GST_TIME_ARGS (buffer_timestamp),
3672 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3675 if (demux->common.element_index) {
3676 if (stream->index_writer_id == -1)
3677 gst_index_get_writer_id (demux->common.element_index,
3678 GST_OBJECT (stream->pad), &stream->index_writer_id);
3680 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3681 G_GUINT64_FORMAT " for writer id %d",
3682 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
3683 stream->index_writer_id);
3684 gst_index_add_association (demux->common.element_index,
3685 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3686 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3687 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
3692 /* Postprocess the buffers depending on the codec used */
3693 if (stream->postprocess_frame) {
3694 GST_LOG_OBJECT (demux, "running post process");
3695 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3698 /* At this point, we have a sub-buffer pointing at data within a larger
3699 buffer. This data might not be aligned with anything. If the data is
3700 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3701 for 32 bit samples, etc), or bad things will happen downstream as
3702 elements typically assume minimal alignment.
3703 Therefore, create an aligned copy if necessary. */
3704 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3706 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3707 stream->pos = GST_BUFFER_PTS (sub);
3708 if (GST_BUFFER_DURATION_IS_VALID (sub))
3709 stream->pos += GST_BUFFER_DURATION (sub);
3710 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
3711 stream->pos = GST_BUFFER_DTS (sub);
3712 if (GST_BUFFER_DURATION_IS_VALID (sub))
3713 stream->pos += GST_BUFFER_DURATION (sub);
3716 ret = gst_pad_push (stream->pad, sub);
3718 if (demux->common.segment.rate < 0) {
3719 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3720 /* In reverse playback we can get a GST_FLOW_EOS when
3721 * we are at the end of the segment, so we just need to jump
3722 * back to the previous section. */
3723 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3728 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
3732 size -= lace_size[n];
3733 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3734 lace_time += duration / laces;
3736 lace_time = GST_CLOCK_TIME_NONE;
3742 gst_buffer_unmap (buf, &map);
3743 gst_buffer_unref (buf);
3755 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
3761 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3762 /* non-fatal, try next block(group) */
3768 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3769 /* non-fatal, try next block(group) */
3775 /* return FALSE if block(group) should be skipped (due to a seek) */
3776 static inline gboolean
3777 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3779 if (G_UNLIKELY (demux->seek_block)) {
3780 if (!(--demux->seek_block)) {
3783 GST_LOG_OBJECT (demux, "should skip block due to seek");
3791 static GstFlowReturn
3792 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3796 guint64 seek_pos = (guint64) - 1;
3797 guint32 seek_id = 0;
3800 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3802 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3803 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3807 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3808 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3812 case GST_MATROSKA_ID_SEEKID:
3816 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3819 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3824 case GST_MATROSKA_ID_SEEKPOSITION:
3828 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3831 if (t > G_MAXINT64) {
3832 GST_WARNING_OBJECT (demux,
3833 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3837 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3843 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3849 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3852 if (!seek_id || seek_pos == (guint64) - 1) {
3853 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3854 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3859 case GST_MATROSKA_ID_SEEKHEAD:
3862 case GST_MATROSKA_ID_CUES:
3863 case GST_MATROSKA_ID_TAGS:
3864 case GST_MATROSKA_ID_TRACKS:
3865 case GST_MATROSKA_ID_SEGMENTINFO:
3866 case GST_MATROSKA_ID_ATTACHMENTS:
3867 case GST_MATROSKA_ID_CHAPTERS:
3869 guint64 before_pos, length;
3873 length = gst_matroska_read_common_get_length (&demux->common);
3874 before_pos = demux->common.offset;
3876 if (length == (guint64) - 1) {
3877 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3881 /* check for validity */
3882 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3883 GST_WARNING_OBJECT (demux,
3884 "SeekHead reference lies outside file!" " (%"
3885 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
3886 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
3891 /* only pick up index location when streaming */
3892 if (demux->streaming) {
3893 if (seek_id == GST_MATROSKA_ID_CUES) {
3894 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
3895 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
3896 demux->index_offset);
3902 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
3905 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
3906 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
3910 if (id != seek_id) {
3911 GST_WARNING_OBJECT (demux,
3912 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
3913 seek_id, id, seek_pos + demux->common.ebml_segment_start);
3916 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
3921 demux->common.offset = before_pos;
3925 case GST_MATROSKA_ID_CLUSTER:
3927 guint64 pos = seek_pos + demux->common.ebml_segment_start;
3929 GST_LOG_OBJECT (demux, "Cluster position");
3930 if (G_UNLIKELY (!demux->clusters))
3931 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
3932 g_array_append_val (demux->clusters, pos);
3937 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
3940 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3945 static GstFlowReturn
3946 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3948 GstFlowReturn ret = GST_FLOW_OK;
3951 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
3953 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3954 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3958 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3959 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3963 case GST_MATROSKA_ID_SEEKENTRY:
3965 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
3966 /* Ignore EOS and errors here */
3967 if (ret != GST_FLOW_OK) {
3968 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
3975 ret = gst_matroska_read_common_parse_skip (&demux->common,
3976 ebml, "SeekHead", id);
3981 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
3983 /* Sort clusters by position for easier searching */
3984 if (demux->clusters)
3985 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
3990 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
3992 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
3994 static inline GstFlowReturn
3995 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
3997 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
3998 /* only a few blocks are expected/allowed to be large,
3999 * and will be recursed into, whereas others will be read and must fit */
4000 if (demux->streaming) {
4001 /* fatal in streaming case, as we can't step over easily */
4002 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4003 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4004 "file might be corrupt.", bytes));
4005 return GST_FLOW_ERROR;
4007 /* indicate higher level to quietly give up */
4008 GST_DEBUG_OBJECT (demux,
4009 "too large block of size %" G_GUINT64_FORMAT, bytes);
4010 return GST_FLOW_ERROR;
4017 /* returns TRUE if we truely are in error state, and should give up */
4018 static inline GstFlowReturn
4019 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4021 if (!demux->streaming && demux->next_cluster_offset > 0) {
4022 /* just repositioning to where next cluster should be and try from there */
4023 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4024 G_GUINT64_FORMAT, demux->next_cluster_offset);
4025 demux->common.offset = demux->next_cluster_offset;
4026 demux->next_cluster_offset = 0;
4032 /* sigh, one last attempt above and beyond call of duty ...;
4033 * search for cluster mark following current pos */
4034 pos = demux->common.offset;
4035 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4036 if ((ret = gst_matroska_demux_search_cluster (demux, &pos)) != GST_FLOW_OK) {
4037 /* did not work, give up */
4040 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4041 /* try that position */
4042 demux->common.offset = pos;
4048 static inline GstFlowReturn
4049 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4051 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4052 demux->common.offset += flush;
4053 if (demux->streaming) {
4056 /* hard to skip large blocks when streaming */
4057 ret = gst_matroska_demux_check_read_size (demux, flush);
4058 if (ret != GST_FLOW_OK)
4060 if (flush <= gst_adapter_available (demux->common.adapter))
4061 gst_adapter_flush (demux->common.adapter, flush);
4063 return GST_FLOW_EOS;
4068 /* initializes @ebml with @bytes from input stream at current offset.
4069 * Returns EOS if insufficient available,
4070 * ERROR if too much was attempted to read. */
4071 static inline GstFlowReturn
4072 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4075 GstBuffer *buffer = NULL;
4076 GstFlowReturn ret = GST_FLOW_OK;
4078 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4080 ret = gst_matroska_demux_check_read_size (demux, bytes);
4081 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4082 if (!demux->streaming) {
4083 /* in pull mode, we can skip */
4084 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4085 ret = GST_FLOW_OVERFLOW;
4087 /* otherwise fatal */
4088 ret = GST_FLOW_ERROR;
4092 if (demux->streaming) {
4093 if (gst_adapter_available (demux->common.adapter) >= bytes)
4094 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4098 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4099 demux->common.offset, bytes, &buffer, NULL);
4100 if (G_LIKELY (buffer)) {
4101 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4102 demux->common.offset);
4103 demux->common.offset += bytes;
4110 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4113 gboolean seekable = FALSE;
4114 gint64 start = -1, stop = -1;
4116 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4117 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4118 GST_DEBUG_OBJECT (demux, "seeking query failed");
4122 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4124 /* try harder to query upstream size if we didn't get it the first time */
4125 if (seekable && stop == -1) {
4126 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4127 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4131 /* if upstream doesn't know the size, it's likely that it's not seekable in
4132 * practice even if it technically may be seekable */
4133 if (seekable && (start != 0 || stop <= start)) {
4134 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4139 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4140 G_GUINT64_FORMAT ")", seekable, start, stop);
4141 demux->seekable = seekable;
4143 gst_query_unref (query);
4146 static GstFlowReturn
4147 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4153 GstFlowReturn ret = GST_FLOW_OK;
4155 GST_WARNING_OBJECT (demux,
4156 "Found Cluster element before Tracks, searching Tracks");
4159 before_pos = demux->common.offset;
4161 /* Search Tracks element */
4163 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4164 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4165 if (ret != GST_FLOW_OK)
4168 if (id != GST_MATROSKA_ID_TRACKS) {
4169 /* we may be skipping large cluster here, so forego size check etc */
4170 /* ... but we can't skip undefined size; force error */
4171 if (length == G_MAXUINT64) {
4172 ret = gst_matroska_demux_check_read_size (demux, length);
4175 demux->common.offset += needed;
4176 demux->common.offset += length;
4181 /* will lead to track parsing ... */
4182 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4187 demux->common.offset = before_pos;
4192 #define GST_READ_CHECK(stmt) \
4194 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4195 if (ret == GST_FLOW_OVERFLOW) { \
4196 ret = GST_FLOW_OK; \
4202 static GstFlowReturn
4203 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4204 guint64 length, guint needed)
4206 GstEbmlRead ebml = { 0, };
4207 GstFlowReturn ret = GST_FLOW_OK;
4210 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4211 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4213 /* if we plan to read and parse this element, we need prefix (id + length)
4214 * and the contents */
4215 /* mind about overflow wrap-around when dealing with undefined size */
4217 if (G_LIKELY (length != G_MAXUINT64))
4220 switch (demux->common.state) {
4221 case GST_MATROSKA_READ_STATE_START:
4223 case GST_EBML_ID_HEADER:
4224 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4225 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4226 if (ret != GST_FLOW_OK)
4228 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4229 gst_matroska_demux_check_seekability (demux);
4232 goto invalid_header;
4236 case GST_MATROSKA_READ_STATE_SEGMENT:
4238 case GST_MATROSKA_ID_SEGMENT:
4239 /* eat segment prefix */
4240 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4241 GST_DEBUG_OBJECT (demux,
4242 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4243 G_GUINT64_FORMAT, demux->common.offset, length);
4244 /* seeks are from the beginning of the segment,
4245 * after the segment ID/length */
4246 demux->common.ebml_segment_start = demux->common.offset;
4248 length = G_MAXUINT64;
4249 demux->common.ebml_segment_length = length;
4250 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4253 GST_WARNING_OBJECT (demux,
4254 "Expected a Segment ID (0x%x), but received 0x%x!",
4255 GST_MATROSKA_ID_SEGMENT, id);
4256 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4260 case GST_MATROSKA_READ_STATE_SCANNING:
4261 if (id != GST_MATROSKA_ID_CLUSTER &&
4262 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4265 case GST_MATROSKA_READ_STATE_HEADER:
4266 case GST_MATROSKA_READ_STATE_DATA:
4267 case GST_MATROSKA_READ_STATE_SEEK:
4269 case GST_MATROSKA_ID_SEGMENTINFO:
4270 if (!demux->common.segmentinfo_parsed) {
4271 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4272 ret = gst_matroska_read_common_parse_info (&demux->common,
4273 GST_ELEMENT_CAST (demux), &ebml);
4274 if (ret == GST_FLOW_OK)
4275 gst_matroska_demux_send_tags (demux);
4277 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4280 case GST_MATROSKA_ID_TRACKS:
4281 if (!demux->tracks_parsed) {
4282 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4283 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4285 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4288 case GST_MATROSKA_ID_CLUSTER:
4289 if (G_UNLIKELY (!demux->tracks_parsed)) {
4290 if (demux->streaming) {
4291 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4292 goto not_streamable;
4294 ret = gst_matroska_demux_find_tracks (demux);
4295 if (!demux->tracks_parsed)
4299 if (G_UNLIKELY (demux->common.state
4300 == GST_MATROSKA_READ_STATE_HEADER)) {
4301 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4302 demux->first_cluster_offset = demux->common.offset;
4303 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4304 gst_element_no_more_pads (GST_ELEMENT (demux));
4305 /* send initial segment - we wait till we know the first
4306 incoming timestamp, so we can properly set the start of
4308 demux->need_segment = TRUE;
4310 demux->cluster_time = GST_CLOCK_TIME_NONE;
4311 demux->cluster_offset = demux->common.offset;
4312 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4313 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4314 " not found in Cluster, trying next Cluster's first block instead",
4316 demux->seek_block = 0;
4318 demux->seek_first = FALSE;
4319 /* record next cluster for recovery */
4320 if (read != G_MAXUINT64)
4321 demux->next_cluster_offset = demux->cluster_offset + read;
4322 /* eat cluster prefix */
4323 gst_matroska_demux_flush (demux, needed);
4325 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4329 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4330 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4332 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4333 demux->cluster_time = num;
4335 if (demux->common.element_index) {
4336 if (demux->common.element_index_writer_id == -1)
4337 gst_index_get_writer_id (demux->common.element_index,
4338 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4339 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4340 G_GUINT64_FORMAT " for writer id %d",
4341 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4342 demux->common.element_index_writer_id);
4343 gst_index_add_association (demux->common.element_index,
4344 demux->common.element_index_writer_id,
4345 GST_ASSOCIATION_FLAG_KEY_UNIT,
4346 GST_FORMAT_TIME, demux->cluster_time,
4347 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4352 case GST_MATROSKA_ID_BLOCKGROUP:
4353 if (!gst_matroska_demux_seek_block (demux))
4355 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4356 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4357 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4358 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4359 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4361 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4363 case GST_MATROSKA_ID_SIMPLEBLOCK:
4364 if (!gst_matroska_demux_seek_block (demux))
4366 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4367 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4368 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4369 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4370 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4372 case GST_MATROSKA_ID_ATTACHMENTS:
4373 if (!demux->common.attachments_parsed) {
4374 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4375 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4376 GST_ELEMENT_CAST (demux), &ebml);
4377 if (ret == GST_FLOW_OK)
4378 gst_matroska_demux_send_tags (demux);
4380 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4383 case GST_MATROSKA_ID_TAGS:
4384 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4385 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4386 GST_ELEMENT_CAST (demux), &ebml);
4387 if (ret == GST_FLOW_OK)
4388 gst_matroska_demux_send_tags (demux);
4390 case GST_MATROSKA_ID_CHAPTERS:
4391 if (!demux->common.chapters_parsed) {
4392 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4394 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4396 if (demux->common.toc) {
4397 gst_matroska_demux_send_event (demux,
4398 gst_event_new_toc (demux->common.toc, FALSE));
4401 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4403 case GST_MATROSKA_ID_SEEKHEAD:
4404 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4405 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4407 case GST_MATROSKA_ID_CUES:
4408 if (demux->common.index_parsed) {
4409 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4412 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4413 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4414 /* only push based; delayed index building */
4415 if (ret == GST_FLOW_OK
4416 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4419 GST_OBJECT_LOCK (demux);
4420 event = demux->seek_event;
4421 demux->seek_event = NULL;
4422 GST_OBJECT_UNLOCK (demux);
4425 /* unlikely to fail, since we managed to seek to this point */
4426 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
4427 gst_event_unref (event);
4430 gst_event_unref (event);
4431 /* resume data handling, main thread clear to seek again */
4432 GST_OBJECT_LOCK (demux);
4433 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4434 GST_OBJECT_UNLOCK (demux);
4437 case GST_MATROSKA_ID_POSITION:
4438 case GST_MATROSKA_ID_PREVSIZE:
4439 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4440 case GST_MATROSKA_ID_SILENTTRACKS:
4441 GST_DEBUG_OBJECT (demux,
4442 "Skipping Cluster subelement 0x%x - ignoring", id);
4446 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4447 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4453 if (ret == GST_FLOW_PARSE)
4457 gst_ebml_read_clear (&ebml);
4463 /* simply exit, maybe not enough data yet */
4464 /* no ebml to clear if read error */
4469 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4470 ("Failed to parse Element 0x%x", id));
4471 ret = GST_FLOW_ERROR;
4476 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4477 ("File layout does not permit streaming"));
4478 ret = GST_FLOW_ERROR;
4483 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4484 ("No Tracks element found"));
4485 ret = GST_FLOW_ERROR;
4490 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4491 ret = GST_FLOW_ERROR;
4496 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4497 ret = GST_FLOW_ERROR;
4503 gst_matroska_demux_loop (GstPad * pad)
4505 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4511 /* If we have to close a segment, send a new segment to do this now */
4512 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4513 if (G_UNLIKELY (demux->new_segment)) {
4514 gst_matroska_demux_send_event (demux, demux->new_segment);
4515 demux->new_segment = NULL;
4519 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4520 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4521 if (ret == GST_FLOW_EOS) {
4523 } else if (ret == GST_FLOW_FLUSHING) {
4525 } else if (ret != GST_FLOW_OK) {
4526 ret = gst_matroska_demux_check_parse_error (demux);
4528 /* Only handle EOS as no error if we're outside the segment already */
4529 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4530 && demux->common.offset >=
4531 demux->common.ebml_segment_start +
4532 demux->common.ebml_segment_length))
4534 else if (ret != GST_FLOW_OK)
4540 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4541 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4544 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4545 if (ret == GST_FLOW_EOS)
4547 if (ret != GST_FLOW_OK)
4550 /* check if we're at the end of a configured segment */
4551 if (G_LIKELY (demux->common.src->len)) {
4554 g_assert (demux->common.num_streams == demux->common.src->len);
4555 for (i = 0; i < demux->common.src->len; i++) {
4556 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4558 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4559 GST_TIME_ARGS (context->pos));
4560 if (context->eos == FALSE)
4564 GST_INFO_OBJECT (demux, "All streams are EOS");
4570 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4571 demux->common.offset >= demux->cached_length)) {
4572 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4573 if (demux->common.offset == demux->cached_length) {
4574 GST_LOG_OBJECT (demux, "Reached end of stream");
4585 if (demux->common.segment.rate < 0.0) {
4586 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4587 if (ret == GST_FLOW_OK)
4594 const gchar *reason = gst_flow_get_name (ret);
4595 gboolean push_eos = FALSE;
4597 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4598 gst_pad_pause_task (demux->common.sinkpad);
4600 if (ret == GST_FLOW_EOS) {
4601 /* perform EOS logic */
4603 /* If we were in the headers, make sure we send no-more-pads.
4604 This will ensure decodebin does not get stuck thinking
4605 the chain is not complete yet, and waiting indefinitely. */
4606 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4607 if (demux->common.src->len == 0) {
4608 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4609 ("No pads created"));
4611 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4612 ("Failed to finish reading headers"));
4614 gst_element_no_more_pads (GST_ELEMENT (demux));
4617 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4620 /* for segment playback we need to post when (in stream time)
4621 * we stopped, this is either stop (when set) or the duration. */
4622 if ((stop = demux->common.segment.stop) == -1)
4623 stop = demux->last_stop_end;
4625 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4626 gst_element_post_message (GST_ELEMENT (demux),
4627 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4629 gst_matroska_demux_send_event (demux,
4630 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4634 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4635 /* for fatal errors we post an error message */
4636 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4637 ("stream stopped, reason %s", reason));
4641 /* send EOS, and prevent hanging if no streams yet */
4642 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4643 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4644 (ret == GST_FLOW_EOS)) {
4645 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4646 (NULL), ("got eos but no streams (yet)"));
4654 * Create and push a flushing seek event upstream
4657 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4663 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4666 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4667 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4668 GST_SEEK_TYPE_NONE, -1);
4669 gst_event_set_seqnum (event, seqnum);
4671 res = gst_pad_push_event (demux->common.sinkpad, event);
4673 /* segment event will update offset */
4677 static GstFlowReturn
4678 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4680 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4682 GstFlowReturn ret = GST_FLOW_OK;
4687 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4688 GST_DEBUG_OBJECT (demux, "got DISCONT");
4689 gst_adapter_clear (demux->common.adapter);
4690 GST_OBJECT_LOCK (demux);
4691 gst_matroska_read_common_reset_streams (&demux->common,
4692 GST_CLOCK_TIME_NONE, FALSE);
4693 GST_OBJECT_UNLOCK (demux);
4696 gst_adapter_push (demux->common.adapter, buffer);
4700 available = gst_adapter_available (demux->common.adapter);
4702 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4703 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4704 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4705 if (demux->common.ebml_segment_length != G_MAXUINT64
4706 && demux->common.offset >=
4707 demux->common.ebml_segment_start + demux->common.ebml_segment_length)
4712 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4713 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4714 demux->common.offset, id, length, needed, available);
4716 if (needed > available)
4719 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4720 if (ret == GST_FLOW_EOS) {
4721 /* need more data */
4723 } else if (ret != GST_FLOW_OK) {
4730 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4733 gboolean res = TRUE;
4734 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4736 GST_DEBUG_OBJECT (demux,
4737 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4739 switch (GST_EVENT_TYPE (event)) {
4740 case GST_EVENT_SEGMENT:
4742 const GstSegment *segment;
4744 /* some debug output */
4745 gst_event_parse_segment (event, &segment);
4746 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4747 GST_DEBUG_OBJECT (demux,
4748 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4751 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4752 GST_DEBUG_OBJECT (demux, "still starting");
4756 /* we only expect a BYTE segment, e.g. following a seek */
4757 if (segment->format != GST_FORMAT_BYTES) {
4758 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4762 GST_DEBUG_OBJECT (demux, "clearing segment state");
4763 GST_OBJECT_LOCK (demux);
4764 /* clear current segment leftover */
4765 gst_adapter_clear (demux->common.adapter);
4766 /* and some streaming setup */
4767 demux->common.offset = segment->start;
4768 /* accumulate base based on current position */
4769 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4770 demux->common.segment.base +=
4771 (MAX (demux->common.segment.position, demux->stream_start_time)
4772 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4773 /* do not know where we are;
4774 * need to come across a cluster and generate segment */
4775 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4776 demux->cluster_time = GST_CLOCK_TIME_NONE;
4777 demux->cluster_offset = 0;
4778 demux->need_segment = TRUE;
4779 demux->segment_seqnum = gst_event_get_seqnum (event);
4780 /* but keep some of the upstream segment */
4781 demux->common.segment.rate = segment->rate;
4782 /* also check if need to keep some of the requested seek position */
4783 if (demux->seek_offset == segment->start) {
4784 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4785 demux->common.segment.position = demux->requested_seek_time;
4787 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4789 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4790 demux->seek_offset = -1;
4791 GST_OBJECT_UNLOCK (demux);
4793 /* chain will send initial segment after pads have been added,
4794 * or otherwise come up with one */
4795 GST_DEBUG_OBJECT (demux, "eating event");
4796 gst_event_unref (event);
4802 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4803 gst_event_unref (event);
4804 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4805 (NULL), ("got eos and didn't receive a complete header object"));
4806 } else if (demux->common.num_streams == 0) {
4807 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4808 (NULL), ("got eos but no streams (yet)"));
4810 gst_matroska_demux_send_event (demux, event);
4814 case GST_EVENT_FLUSH_STOP:
4818 gst_adapter_clear (demux->common.adapter);
4819 GST_OBJECT_LOCK (demux);
4820 gst_matroska_read_common_reset_streams (&demux->common,
4821 GST_CLOCK_TIME_NONE, TRUE);
4822 gst_flow_combiner_reset (demux->flowcombiner);
4823 dur = demux->common.segment.duration;
4824 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4825 demux->common.segment.duration = dur;
4826 demux->cluster_time = GST_CLOCK_TIME_NONE;
4827 demux->cluster_offset = 0;
4828 GST_OBJECT_UNLOCK (demux);
4832 res = gst_pad_event_default (pad, parent, event);
4840 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4842 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4844 gboolean pull_mode = FALSE;
4846 query = gst_query_new_scheduling ();
4848 if (gst_pad_peer_query (sinkpad, query))
4849 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4850 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4852 gst_query_unref (query);
4855 GST_DEBUG ("going to pull mode");
4856 demux->streaming = FALSE;
4857 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4859 GST_DEBUG ("going to push (streaming) mode");
4860 demux->streaming = TRUE;
4861 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4866 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4867 GstPadMode mode, gboolean active)
4870 case GST_PAD_MODE_PULL:
4872 /* if we have a scheduler we can start the task */
4873 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4876 gst_pad_stop_task (sinkpad);
4879 case GST_PAD_MODE_PUSH:
4887 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
4888 videocontext, const gchar * codec_id, guint8 * data, guint size,
4889 gchar ** codec_name, guint32 * riff_fourcc)
4891 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
4892 GstCaps *caps = NULL;
4894 g_assert (videocontext != NULL);
4895 g_assert (codec_name != NULL);
4900 /* TODO: check if we have all codec types from matroska-ids.h
4901 * check if we have to do more special things with codec_private
4904 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
4905 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
4908 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
4909 gst_riff_strf_vids *vids = NULL;
4912 GstBuffer *buf = NULL;
4914 vids = (gst_riff_strf_vids *) data;
4916 /* assure size is big enough */
4918 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
4921 if (size < sizeof (gst_riff_strf_vids)) {
4922 vids = g_new (gst_riff_strf_vids, 1);
4923 memcpy (vids, data, size);
4926 context->dts_only = TRUE; /* VFW files only store DTS */
4928 /* little-endian -> byte-order */
4929 vids->size = GUINT32_FROM_LE (vids->size);
4930 vids->width = GUINT32_FROM_LE (vids->width);
4931 vids->height = GUINT32_FROM_LE (vids->height);
4932 vids->planes = GUINT16_FROM_LE (vids->planes);
4933 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
4934 vids->compression = GUINT32_FROM_LE (vids->compression);
4935 vids->image_size = GUINT32_FROM_LE (vids->image_size);
4936 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
4937 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
4938 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
4939 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
4941 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
4942 gsize offset = sizeof (gst_riff_strf_vids);
4945 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
4946 size - offset), size - offset);
4950 *riff_fourcc = vids->compression;
4952 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
4953 buf, NULL, codec_name);
4956 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
4957 GST_FOURCC_ARGS (vids->compression));
4959 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
4960 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
4961 "video/x-compressed-yuv");
4962 context->intra_only =
4963 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
4967 gst_buffer_unref (buf);
4969 if (vids != (gst_riff_strf_vids *) data)
4972 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
4974 GstVideoFormat format;
4976 gst_video_info_init (&info);
4977 switch (videocontext->fourcc) {
4978 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
4979 format = GST_VIDEO_FORMAT_I420;
4981 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
4982 format = GST_VIDEO_FORMAT_YUY2;
4984 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
4985 format = GST_VIDEO_FORMAT_YV12;
4987 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
4988 format = GST_VIDEO_FORMAT_UYVY;
4990 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
4991 format = GST_VIDEO_FORMAT_AYUV;
4993 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
4994 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
4995 format = GST_VIDEO_FORMAT_GRAY8;
4997 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
4998 format = GST_VIDEO_FORMAT_RGB;
5000 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
5001 format = GST_VIDEO_FORMAT_BGR;
5004 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5005 GST_FOURCC_ARGS (videocontext->fourcc));
5009 context->intra_only = TRUE;
5011 gst_video_info_set_format (&info, format, videocontext->pixel_width,
5012 videocontext->pixel_height);
5013 caps = gst_video_info_to_caps (&info);
5014 *codec_name = gst_pb_utils_get_codec_description (caps);
5015 context->alignment = 32;
5016 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5017 caps = gst_caps_new_simple ("video/x-divx",
5018 "divxversion", G_TYPE_INT, 4, NULL);
5019 *codec_name = g_strdup ("MPEG-4 simple profile");
5020 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5021 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5022 caps = gst_caps_new_simple ("video/mpeg",
5023 "mpegversion", G_TYPE_INT, 4,
5024 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5028 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5029 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5030 gst_buffer_unref (priv);
5032 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
5034 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5035 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5037 *codec_name = g_strdup ("MPEG-4 advanced profile");
5038 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5040 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5041 "divxversion", G_TYPE_INT, 3, NULL),
5042 gst_structure_new ("video/x-msmpeg",
5043 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5045 caps = gst_caps_new_simple ("video/x-msmpeg",
5046 "msmpegversion", G_TYPE_INT, 43, NULL);
5047 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5048 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5049 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5052 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5057 caps = gst_caps_new_simple ("video/mpeg",
5058 "systemstream", G_TYPE_BOOLEAN, FALSE,
5059 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5060 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5061 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5062 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5063 caps = gst_caps_new_empty_simple ("image/jpeg");
5064 *codec_name = g_strdup ("Motion-JPEG");
5065 context->intra_only = TRUE;
5066 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5067 caps = gst_caps_new_empty_simple ("video/x-h264");
5071 /* First byte is the version, second is the profile indication, and third
5072 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5073 * level indication. */
5074 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5077 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5078 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5079 gst_buffer_unref (priv);
5081 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5082 "alignment", G_TYPE_STRING, "au", NULL);
5084 GST_WARNING ("No codec data found, assuming output is byte-stream");
5085 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5088 *codec_name = g_strdup ("H264");
5089 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
5090 caps = gst_caps_new_empty_simple ("video/x-h265");
5094 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
5097 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5098 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5099 gst_buffer_unref (priv);
5101 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
5102 "alignment", G_TYPE_STRING, "au", NULL);
5104 GST_WARNING ("No codec data found, assuming output is byte-stream");
5105 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5108 *codec_name = g_strdup ("HEVC");
5109 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5110 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5111 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5112 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5113 gint rmversion = -1;
5115 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5117 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5119 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5121 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5124 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5125 "rmversion", G_TYPE_INT, rmversion, NULL);
5126 GST_DEBUG ("data:%p, size:0x%x", data, size);
5127 /* We need to extract the extradata ! */
5128 if (data && (size >= 0x22)) {
5133 subformat = GST_READ_UINT32_BE (data + 0x1a);
5134 rformat = GST_READ_UINT32_BE (data + 0x1e);
5137 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5139 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5140 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5141 gst_buffer_unref (priv);
5144 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5145 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5146 caps = gst_caps_new_empty_simple ("video/x-theora");
5147 context->stream_headers =
5148 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5149 context->codec_priv_size);
5150 /* FIXME: mark stream as broken and skip if there are no stream headers */
5151 context->send_stream_headers = TRUE;
5152 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5153 caps = gst_caps_new_empty_simple ("video/x-dirac");
5154 *codec_name = g_strdup_printf ("Dirac");
5155 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5156 caps = gst_caps_new_empty_simple ("video/x-vp8");
5157 *codec_name = g_strdup_printf ("On2 VP8");
5158 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5159 caps = gst_caps_new_empty_simple ("video/x-vp9");
5160 *codec_name = g_strdup_printf ("On2 VP9");
5162 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5168 GstStructure *structure;
5170 for (i = 0; i < gst_caps_get_size (caps); i++) {
5171 structure = gst_caps_get_structure (caps, i);
5173 /* FIXME: use the real unit here! */
5174 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5175 videocontext->pixel_width,
5176 videocontext->pixel_height,
5177 videocontext->display_width, videocontext->display_height);
5179 /* pixel width and height are the w and h of the video in pixels */
5180 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5181 gint w = videocontext->pixel_width;
5182 gint h = videocontext->pixel_height;
5184 gst_structure_set (structure,
5185 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5188 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5191 if (videocontext->display_width <= 0)
5192 videocontext->display_width = videocontext->pixel_width;
5193 if (videocontext->display_height <= 0)
5194 videocontext->display_height = videocontext->pixel_height;
5196 /* calculate the pixel aspect ratio using the display and pixel w/h */
5197 n = videocontext->display_width * videocontext->pixel_height;
5198 d = videocontext->display_height * videocontext->pixel_width;
5199 GST_DEBUG ("setting PAR to %d/%d", n, d);
5200 gst_structure_set (structure, "pixel-aspect-ratio",
5202 videocontext->display_width * videocontext->pixel_height,
5203 videocontext->display_height * videocontext->pixel_width, NULL);
5206 if (videocontext->default_fps > 0.0) {
5209 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5211 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5213 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5215 } else if (context->default_duration > 0) {
5218 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5220 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5221 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5223 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5224 fps_n, fps_d, NULL);
5226 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5230 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5231 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5234 if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
5235 if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
5236 videocontext->pixel_width, videocontext->pixel_height,
5237 videocontext->display_width * videocontext->pixel_height,
5238 videocontext->display_height * videocontext->pixel_width)) {
5239 videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
5241 gst_caps_set_simple (caps,
5242 "multiview-mode", G_TYPE_STRING,
5243 gst_video_multiview_mode_to_caps_string
5244 (videocontext->multiview_mode), "multiview-flags",
5245 GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
5246 GST_FLAG_SET_MASK_EXACT, NULL);
5249 caps = gst_caps_simplify (caps);
5256 * Some AAC specific code... *sigh*
5257 * FIXME: maybe we should use '15' and code the sample rate explicitly
5258 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5262 aac_rate_idx (gint rate)
5266 else if (75132 <= rate)
5268 else if (55426 <= rate)
5270 else if (46009 <= rate)
5272 else if (37566 <= rate)
5274 else if (27713 <= rate)
5276 else if (23004 <= rate)
5278 else if (18783 <= rate)
5280 else if (13856 <= rate)
5282 else if (11502 <= rate)
5284 else if (9391 <= rate)
5291 aac_profile_idx (const gchar * codec_id)
5295 if (strlen (codec_id) <= 12)
5297 else if (!strncmp (&codec_id[12], "MAIN", 4))
5299 else if (!strncmp (&codec_id[12], "LC", 2))
5301 else if (!strncmp (&codec_id[12], "SSR", 3))
5310 round_up_pow2 (guint n)
5321 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5324 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5325 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5326 gchar ** codec_name, guint16 * riff_audio_fmt)
5328 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5329 GstCaps *caps = NULL;
5331 g_assert (audiocontext != NULL);
5332 g_assert (codec_name != NULL);
5335 *riff_audio_fmt = 0;
5337 /* TODO: check if we have all codec types from matroska-ids.h
5338 * check if we have to do more special things with codec_private
5339 * check if we need bitdepth in different places too
5340 * implement channel position magic
5342 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5343 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5344 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5345 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5348 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5349 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5350 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5353 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5355 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5360 caps = gst_caps_new_simple ("audio/mpeg",
5361 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5362 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5363 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5364 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5367 GstAudioFormat format;
5369 sign = (audiocontext->bitdepth != 8);
5370 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5371 endianness = G_BIG_ENDIAN;
5373 endianness = G_LITTLE_ENDIAN;
5375 format = gst_audio_format_build_integer (sign, endianness,
5376 audiocontext->bitdepth, audiocontext->bitdepth);
5378 /* FIXME: Channel mask and reordering */
5379 caps = gst_caps_new_simple ("audio/x-raw",
5380 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5381 "layout", G_TYPE_STRING, "interleaved", NULL);
5383 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5384 audiocontext->bitdepth);
5385 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5386 context->alignment = round_up_pow2 (context->alignment);
5387 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5388 const gchar *format;
5389 if (audiocontext->bitdepth == 32)
5393 /* FIXME: Channel mask and reordering */
5394 caps = gst_caps_new_simple ("audio/x-raw",
5395 "format", G_TYPE_STRING, format,
5396 "layout", G_TYPE_STRING, "interleaved", NULL);
5397 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5398 audiocontext->bitdepth);
5399 context->alignment = audiocontext->bitdepth / 8;
5400 context->alignment = round_up_pow2 (context->alignment);
5401 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5402 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5403 caps = gst_caps_new_simple ("audio/x-ac3",
5404 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5405 *codec_name = g_strdup ("AC-3 audio");
5406 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5407 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5408 caps = gst_caps_new_simple ("audio/x-eac3",
5409 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5410 *codec_name = g_strdup ("E-AC-3 audio");
5411 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5412 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5413 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5414 *codec_name = g_strdup ("Dolby TrueHD");
5415 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5416 caps = gst_caps_new_empty_simple ("audio/x-dts");
5417 *codec_name = g_strdup ("DTS audio");
5418 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5419 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5420 context->stream_headers =
5421 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5422 context->codec_priv_size);
5423 /* FIXME: mark stream as broken and skip if there are no stream headers */
5424 context->send_stream_headers = TRUE;
5425 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5426 caps = gst_caps_new_empty_simple ("audio/x-flac");
5427 context->stream_headers =
5428 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5429 context->codec_priv_size);
5430 /* FIXME: mark stream as broken and skip if there are no stream headers */
5431 context->send_stream_headers = TRUE;
5432 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5433 caps = gst_caps_new_empty_simple ("audio/x-speex");
5434 context->stream_headers =
5435 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5436 context->codec_priv_size);
5437 /* FIXME: mark stream as broken and skip if there are no stream headers */
5438 context->send_stream_headers = TRUE;
5439 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5440 caps = gst_caps_new_empty_simple ("audio/x-opus");
5441 *codec_name = g_strdup ("Opus");
5442 context->stream_headers =
5443 gst_matroska_parse_opus_stream_headers (context->codec_priv,
5444 context->codec_priv_size);
5445 if (context->stream_headers) {
5446 /* There was a valid header. Multistream headers are more than
5447 * 19 bytes, as they include an extra channel mapping table. */
5448 gboolean multistream = (context->codec_priv_size > 19);
5449 gst_caps_set_simple (caps, "multistream", G_TYPE_BOOLEAN, multistream,
5452 /* FIXME: mark stream as broken and skip if there are no stream headers */
5453 context->send_stream_headers = TRUE;
5454 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5455 gst_riff_strf_auds auds;
5457 if (data && size >= 18) {
5458 GstBuffer *codec_data = NULL;
5460 /* little-endian -> byte-order */
5461 auds.format = GST_READ_UINT16_LE (data);
5462 auds.channels = GST_READ_UINT16_LE (data + 2);
5463 auds.rate = GST_READ_UINT32_LE (data + 4);
5464 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5465 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5466 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5468 /* 18 is the waveformatex size */
5470 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5471 data + 18, size - 18, 0, size - 18, NULL, NULL);
5475 *riff_audio_fmt = auds.format;
5477 /* FIXME: Handle reorder map */
5478 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5479 codec_data, codec_name, NULL);
5481 gst_buffer_unref (codec_data);
5484 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5487 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5489 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5490 GstBuffer *priv = NULL;
5492 gint rate_idx, profile;
5493 guint8 *data = NULL;
5495 /* unspecified AAC profile with opaque private codec data */
5496 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5497 if (context->codec_priv_size >= 2) {
5498 guint obj_type, freq_index, explicit_freq_bytes = 0;
5500 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5502 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5503 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5504 if (freq_index == 15)
5505 explicit_freq_bytes = 3;
5506 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5507 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5508 context->codec_priv_size), context->codec_priv_size);
5509 /* assume SBR if samplerate <= 24kHz */
5510 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5511 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5512 audiocontext->samplerate *= 2;
5515 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5516 /* this is pretty broken;
5517 * maybe we need to make up some default private,
5518 * or maybe ADTS data got dumped in.
5519 * Let's set up some private data now, and check actual data later */
5520 /* just try this and see what happens ... */
5521 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5522 context->postprocess_frame = gst_matroska_demux_check_aac;
5526 /* make up decoder-specific data if it is not supplied */
5530 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5531 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5533 rate_idx = aac_rate_idx (audiocontext->samplerate);
5534 profile = aac_profile_idx (codec_id);
5536 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5537 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5539 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5540 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5542 gst_buffer_unmap (priv, &map);
5543 gst_buffer_set_size (priv, 2);
5544 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5545 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5548 if (g_strrstr (codec_id, "SBR")) {
5549 /* HE-AAC (aka SBR AAC) */
5550 audiocontext->samplerate *= 2;
5551 rate_idx = aac_rate_idx (audiocontext->samplerate);
5552 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5553 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5554 data[4] = (1 << 7) | (rate_idx << 3);
5555 gst_buffer_unmap (priv, &map);
5557 gst_buffer_unmap (priv, &map);
5558 gst_buffer_set_size (priv, 2);
5561 gst_buffer_unmap (priv, &map);
5562 gst_buffer_unref (priv);
5564 GST_ERROR ("Unknown AAC profile and no codec private data");
5569 caps = gst_caps_new_simple ("audio/mpeg",
5570 "mpegversion", G_TYPE_INT, mpegversion,
5571 "framed", G_TYPE_BOOLEAN, TRUE,
5572 "stream-format", G_TYPE_STRING, "raw", NULL);
5573 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5574 if (context->codec_priv && context->codec_priv_size > 0)
5575 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5576 context->codec_priv, context->codec_priv_size);
5577 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5578 gst_buffer_unref (priv);
5580 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5581 caps = gst_caps_new_simple ("audio/x-tta",
5582 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5583 *codec_name = g_strdup ("TTA audio");
5584 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5585 caps = gst_caps_new_simple ("audio/x-wavpack",
5586 "width", G_TYPE_INT, audiocontext->bitdepth,
5587 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5588 *codec_name = g_strdup ("Wavpack audio");
5589 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5590 audiocontext->wvpk_block_index = 0;
5591 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5592 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5593 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5594 gint raversion = -1;
5596 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5598 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5603 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5604 "raversion", G_TYPE_INT, raversion, NULL);
5605 /* Extract extra information from caps, mapping varies based on codec */
5606 if (data && (size >= 0x50)) {
5613 guint extra_data_size;
5615 GST_ERROR ("real audio raversion:%d", raversion);
5616 if (raversion == 8) {
5618 flavor = GST_READ_UINT16_BE (data + 22);
5619 packet_size = GST_READ_UINT32_BE (data + 24);
5620 height = GST_READ_UINT16_BE (data + 40);
5621 leaf_size = GST_READ_UINT16_BE (data + 44);
5622 sample_width = GST_READ_UINT16_BE (data + 58);
5623 extra_data_size = GST_READ_UINT32_BE (data + 74);
5626 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5627 flavor, packet_size, height, leaf_size, sample_width,
5629 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5630 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5631 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5633 if ((size - 78) >= extra_data_size) {
5634 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5636 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5637 gst_buffer_unref (priv);
5642 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5643 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5644 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5645 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5646 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5647 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5648 *codec_name = g_strdup ("Real Audio Lossless");
5649 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5650 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5651 *codec_name = g_strdup ("Sony ATRAC3");
5653 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5658 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5661 for (i = 0; i < gst_caps_get_size (caps); i++) {
5662 gst_structure_set (gst_caps_get_structure (caps, i),
5663 "channels", G_TYPE_INT, audiocontext->channels,
5664 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5668 caps = gst_caps_simplify (caps);
5675 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5676 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5678 GstCaps *caps = NULL;
5679 GstMatroskaTrackContext *context =
5680 (GstMatroskaTrackContext *) subtitlecontext;
5682 /* for backwards compatibility */
5683 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5684 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5685 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5686 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5687 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5688 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5689 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5690 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5692 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5693 * Check if we have to do something with codec_private */
5694 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5695 /* well, plain text simply does not have a lot of markup ... */
5696 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5697 "pango-markup", NULL);
5698 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5699 subtitlecontext->check_markup = TRUE;
5700 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5701 caps = gst_caps_new_empty_simple ("application/x-ssa");
5702 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5703 subtitlecontext->check_markup = FALSE;
5704 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5705 caps = gst_caps_new_empty_simple ("application/x-ass");
5706 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5707 subtitlecontext->check_markup = FALSE;
5708 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5709 caps = gst_caps_new_empty_simple ("application/x-usf");
5710 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5711 subtitlecontext->check_markup = FALSE;
5712 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5713 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5714 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5715 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5716 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5717 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5718 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5719 context->stream_headers =
5720 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5721 context->codec_priv_size);
5722 /* FIXME: mark stream as broken and skip if there are no stream headers */
5723 context->send_stream_headers = TRUE;
5725 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5726 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5729 if (data != NULL && size > 0) {
5732 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5733 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5734 gst_buffer_unref (buf);
5742 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5744 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5746 GST_OBJECT_LOCK (demux);
5747 if (demux->common.element_index)
5748 gst_object_unref (demux->common.element_index);
5749 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5750 GST_OBJECT_UNLOCK (demux);
5751 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5752 demux->common.element_index);
5756 gst_matroska_demux_get_index (GstElement * element)
5758 GstIndex *result = NULL;
5759 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5761 GST_OBJECT_LOCK (demux);
5762 if (demux->common.element_index)
5763 result = gst_object_ref (demux->common.element_index);
5764 GST_OBJECT_UNLOCK (demux);
5766 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5772 static GstStateChangeReturn
5773 gst_matroska_demux_change_state (GstElement * element,
5774 GstStateChange transition)
5776 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5777 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5779 /* handle upwards state changes here */
5780 switch (transition) {
5785 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5787 /* handle downwards state changes */
5788 switch (transition) {
5789 case GST_STATE_CHANGE_PAUSED_TO_READY:
5790 gst_matroska_demux_reset (GST_ELEMENT (demux));
5800 gst_matroska_demux_set_property (GObject * object,
5801 guint prop_id, const GValue * value, GParamSpec * pspec)
5803 GstMatroskaDemux *demux;
5805 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5806 demux = GST_MATROSKA_DEMUX (object);
5809 case PROP_MAX_GAP_TIME:
5810 GST_OBJECT_LOCK (demux);
5811 demux->max_gap_time = g_value_get_uint64 (value);
5812 GST_OBJECT_UNLOCK (demux);
5815 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5821 gst_matroska_demux_get_property (GObject * object,
5822 guint prop_id, GValue * value, GParamSpec * pspec)
5824 GstMatroskaDemux *demux;
5826 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
5827 demux = GST_MATROSKA_DEMUX (object);
5830 case PROP_MAX_GAP_TIME:
5831 GST_OBJECT_LOCK (demux);
5832 g_value_set_uint64 (value, demux->max_gap_time);
5833 GST_OBJECT_UNLOCK (demux);
5836 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5842 gst_matroska_demux_plugin_init (GstPlugin * plugin)
5846 /* parser helper separate debug */
5847 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
5848 0, "EBML stream helper class");
5850 /* create an elementfactory for the matroska_demux element */
5851 if (!gst_element_register (plugin, "matroskademux",
5852 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))