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_static_pad_template (gstelement_class,
232 gst_element_class_add_static_pad_template (gstelement_class,
234 gst_element_class_add_static_pad_template (gstelement_class,
235 &subtitle_src_templ);
236 gst_element_class_add_static_pad_template (gstelement_class, &sink_templ);
238 gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
240 "Demuxes Matroska/WebM streams into video/audio/subtitles",
241 "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
245 gst_matroska_demux_init (GstMatroskaDemux * demux)
247 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
249 gst_pad_set_activate_function (demux->common.sinkpad,
250 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
251 gst_pad_set_activatemode_function (demux->common.sinkpad,
252 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
253 gst_pad_set_chain_function (demux->common.sinkpad,
254 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
255 gst_pad_set_event_function (demux->common.sinkpad,
256 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
257 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
259 /* init defaults for common read context */
260 gst_matroska_read_common_init (&demux->common);
262 /* property defaults */
263 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
265 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
267 demux->flowcombiner = gst_flow_combiner_new ();
270 gst_matroska_demux_reset (GST_ELEMENT (demux));
274 gst_matroska_demux_reset (GstElement * element)
276 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
278 GST_DEBUG_OBJECT (demux, "Resetting state");
280 gst_matroska_read_common_reset (GST_ELEMENT (demux), &demux->common);
282 demux->num_a_streams = 0;
283 demux->num_t_streams = 0;
284 demux->num_v_streams = 0;
286 demux->have_group_id = FALSE;
287 demux->group_id = G_MAXUINT;
290 demux->tracks_parsed = FALSE;
292 if (demux->clusters) {
293 g_array_free (demux->clusters, TRUE);
294 demux->clusters = NULL;
297 g_list_foreach (demux->seek_parsed,
298 (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
299 g_list_free (demux->seek_parsed);
300 demux->seek_parsed = NULL;
302 demux->last_stop_end = GST_CLOCK_TIME_NONE;
303 demux->seek_block = 0;
304 demux->stream_start_time = GST_CLOCK_TIME_NONE;
305 demux->to_time = GST_CLOCK_TIME_NONE;
306 demux->cluster_time = GST_CLOCK_TIME_NONE;
307 demux->cluster_offset = 0;
308 demux->next_cluster_offset = 0;
309 demux->index_offset = 0;
310 demux->seekable = FALSE;
311 demux->need_segment = FALSE;
312 demux->segment_seqnum = 0;
313 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
314 demux->seek_offset = -1;
315 demux->building_index = FALSE;
316 if (demux->seek_event) {
317 gst_event_unref (demux->seek_event);
318 demux->seek_event = NULL;
321 demux->seek_index = NULL;
322 demux->seek_entry = 0;
324 if (demux->new_segment) {
325 gst_event_unref (demux->new_segment);
326 demux->new_segment = NULL;
329 demux->invalid_duration = FALSE;
331 demux->cached_length = G_MAXUINT64;
333 gst_flow_combiner_clear (demux->flowcombiner);
337 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
343 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
345 GST_DEBUG ("decoding buffer %p", buf);
347 gst_buffer_map (buf, &map, GST_MAP_READ);
351 g_return_val_if_fail (size > 0, buf);
353 if (gst_matroska_decode_data (context->encodings, &data, &size,
354 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
355 gst_buffer_unmap (buf, &map);
356 gst_buffer_unref (buf);
357 return gst_buffer_new_wrapped (data, size);
359 GST_DEBUG ("decode data failed");
360 gst_buffer_unmap (buf, &map);
361 gst_buffer_unref (buf);
367 gst_matroska_demux_add_stream_headers_to_caps (GstMatroskaDemux * demux,
368 GstBufferList * list, GstCaps * caps)
371 GValue arr_val = G_VALUE_INIT;
372 GValue buf_val = G_VALUE_INIT;
375 g_assert (gst_caps_is_writable (caps));
377 g_value_init (&arr_val, GST_TYPE_ARRAY);
378 g_value_init (&buf_val, GST_TYPE_BUFFER);
380 num = gst_buffer_list_length (list);
381 for (i = 0; i < num; ++i) {
382 g_value_set_boxed (&buf_val, gst_buffer_list_get (list, i));
383 gst_value_array_append_value (&arr_val, &buf_val);
386 s = gst_caps_get_structure (caps, 0);
387 gst_structure_take_value (s, "streamheader", &arr_val);
388 g_value_unset (&buf_val);
392 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
394 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
395 GstMatroskaTrackContext *context;
396 GstPadTemplate *templ = NULL;
397 GstStreamFlags stream_flags;
398 GstCaps *caps = NULL;
399 GstTagList *cached_taglist;
400 gchar *padname = NULL;
402 guint32 id, riff_fourcc = 0;
403 guint16 riff_audio_fmt = 0;
404 GstEvent *stream_start;
408 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
410 /* start with the master */
411 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
412 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
416 /* allocate generic... if we know the type, we'll g_renew()
417 * with the precise type */
418 context = g_new0 (GstMatroskaTrackContext, 1);
419 g_ptr_array_add (demux->common.src, context);
420 context->index = demux->common.num_streams;
421 context->index_writer_id = -1;
422 context->type = 0; /* no type yet */
423 context->default_duration = 0;
425 context->set_discont = TRUE;
426 context->timecodescale = 1.0;
428 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
429 GST_MATROSKA_TRACK_LACING;
430 context->from_time = GST_CLOCK_TIME_NONE;
431 context->from_offset = -1;
432 context->to_offset = G_MAXINT64;
433 context->alignment = 1;
434 context->dts_only = FALSE;
435 context->intra_only = FALSE;
436 context->tags = gst_tag_list_new_empty ();
437 demux->common.num_streams++;
438 g_assert (demux->common.src->len == demux->common.num_streams);
440 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
442 /* try reading the trackentry headers */
443 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
444 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
448 /* track number (unique stream ID) */
449 case GST_MATROSKA_ID_TRACKNUMBER:{
452 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
456 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
457 ret = GST_FLOW_ERROR;
459 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
461 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
462 " is not unique", num);
463 ret = GST_FLOW_ERROR;
467 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
471 /* track UID (unique identifier) */
472 case GST_MATROSKA_ID_TRACKUID:{
475 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
479 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
480 ret = GST_FLOW_ERROR;
484 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
489 /* track type (video, audio, combined, subtitle, etc.) */
490 case GST_MATROSKA_ID_TRACKTYPE:{
493 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
497 if (context->type != 0 && context->type != track_type) {
498 GST_WARNING_OBJECT (demux,
499 "More than one tracktype defined in a TrackEntry - skipping");
501 } else if (track_type < 1 || track_type > 254) {
502 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
507 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
509 /* ok, so we're actually going to reallocate this thing */
510 switch (track_type) {
511 case GST_MATROSKA_TRACK_TYPE_VIDEO:
512 gst_matroska_track_init_video_context (&context);
514 case GST_MATROSKA_TRACK_TYPE_AUDIO:
515 gst_matroska_track_init_audio_context (&context);
517 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
518 gst_matroska_track_init_subtitle_context (&context);
520 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
521 case GST_MATROSKA_TRACK_TYPE_LOGO:
522 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
523 case GST_MATROSKA_TRACK_TYPE_CONTROL:
525 GST_WARNING_OBJECT (demux,
526 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
531 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
536 /* tracktype specific stuff for video */
537 case GST_MATROSKA_ID_TRACKVIDEO:{
538 GstMatroskaTrackVideoContext *videocontext;
540 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
542 if (!gst_matroska_track_init_video_context (&context)) {
543 GST_WARNING_OBJECT (demux,
544 "TrackVideo element in non-video track - ignoring track");
545 ret = GST_FLOW_ERROR;
547 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
550 videocontext = (GstMatroskaTrackVideoContext *) context;
551 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
554 while (ret == GST_FLOW_OK &&
555 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
556 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
560 /* Should be one level up but some broken muxers write it here. */
561 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
564 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
568 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
572 GST_DEBUG_OBJECT (demux,
573 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
574 context->default_duration = num;
578 /* video framerate */
579 /* NOTE: This one is here only for backward compatibility.
580 * Use _TRACKDEFAULDURATION one level up. */
581 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
584 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
588 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
592 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
593 if (context->default_duration == 0)
594 context->default_duration =
595 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
596 videocontext->default_fps = num;
600 /* width of the size to display the video at */
601 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
604 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
608 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
612 GST_DEBUG_OBJECT (demux,
613 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
614 videocontext->display_width = num;
618 /* height of the size to display the video at */
619 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
622 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
626 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
630 GST_DEBUG_OBJECT (demux,
631 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
632 videocontext->display_height = num;
636 /* width of the video in the file */
637 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
640 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
644 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
648 GST_DEBUG_OBJECT (demux,
649 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
650 videocontext->pixel_width = num;
654 /* height of the video in the file */
655 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
658 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
662 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
666 GST_DEBUG_OBJECT (demux,
667 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
668 videocontext->pixel_height = num;
672 /* whether the video is interlaced */
673 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
676 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
680 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
682 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
683 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
684 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
689 /* aspect ratio behaviour */
690 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
693 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
696 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
697 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
698 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
699 GST_WARNING_OBJECT (demux,
700 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
703 GST_DEBUG_OBJECT (demux,
704 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
705 videocontext->asr_mode = num;
709 /* colourspace (only matters for raw video) fourcc */
710 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
715 gst_ebml_read_binary (ebml, &id, &data,
716 &datalen)) != GST_FLOW_OK)
721 GST_WARNING_OBJECT (demux,
722 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
727 memcpy (&videocontext->fourcc, data, 4);
728 GST_DEBUG_OBJECT (demux,
729 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
730 GST_FOURCC_ARGS (videocontext->fourcc));
734 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
738 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
741 GST_DEBUG_OBJECT (demux, "StereoMode: %" G_GUINT64_FORMAT, num);
744 case GST_MATROSKA_STEREO_MODE_SBS_RL:
745 videocontext->multiview_flags =
746 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
748 case GST_MATROSKA_STEREO_MODE_SBS_LR:
749 videocontext->multiview_mode =
750 GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
752 case GST_MATROSKA_STEREO_MODE_TB_RL:
753 videocontext->multiview_flags =
754 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
756 case GST_MATROSKA_STEREO_MODE_TB_LR:
757 videocontext->multiview_mode =
758 GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM;
760 case GST_MATROSKA_STEREO_MODE_CHECKER_RL:
761 videocontext->multiview_flags =
762 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
764 case GST_MATROSKA_STEREO_MODE_CHECKER_LR:
765 videocontext->multiview_mode =
766 GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD;
768 case GST_MATROSKA_STEREO_MODE_FBF_RL:
769 videocontext->multiview_flags =
770 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
772 case GST_MATROSKA_STEREO_MODE_FBF_LR:
773 videocontext->multiview_mode =
774 GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
775 /* FIXME: In frame-by-frame mode, left/right frame buffers are
776 * laced within one block, and we'll need to apply FIRST_IN_BUNDLE
777 * accordingly. See http://www.matroska.org/technical/specs/index.html#StereoMode */
778 GST_FIXME_OBJECT (demux,
779 "Frame-by-frame stereoscopic mode not fully implemented");
786 GST_WARNING_OBJECT (demux,
787 "Unknown TrackVideo subelement 0x%x - ignoring", id);
789 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
790 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
791 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
792 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
793 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
794 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
795 ret = gst_ebml_read_skip (ebml);
800 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
804 /* tracktype specific stuff for audio */
805 case GST_MATROSKA_ID_TRACKAUDIO:{
806 GstMatroskaTrackAudioContext *audiocontext;
808 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
810 if (!gst_matroska_track_init_audio_context (&context)) {
811 GST_WARNING_OBJECT (demux,
812 "TrackAudio element in non-audio track - ignoring track");
813 ret = GST_FLOW_ERROR;
817 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
820 audiocontext = (GstMatroskaTrackAudioContext *) context;
821 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
824 while (ret == GST_FLOW_OK &&
825 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
826 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
831 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
834 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
839 GST_WARNING_OBJECT (demux,
840 "Invalid TrackAudioSamplingFrequency %lf", num);
844 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
845 audiocontext->samplerate = num;
850 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
853 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
857 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
861 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
863 audiocontext->bitdepth = num;
868 case GST_MATROSKA_ID_AUDIOCHANNELS:{
871 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
875 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
879 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
881 audiocontext->channels = num;
886 GST_WARNING_OBJECT (demux,
887 "Unknown TrackAudio subelement 0x%x - ignoring", id);
889 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
890 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
891 ret = gst_ebml_read_skip (ebml);
896 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
901 /* codec identifier */
902 case GST_MATROSKA_ID_CODECID:{
905 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
908 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
909 context->codec_id = text;
913 /* codec private data */
914 case GST_MATROSKA_ID_CODECPRIVATE:{
919 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
922 context->codec_priv = data;
923 context->codec_priv_size = size;
925 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
930 /* name of the codec */
931 case GST_MATROSKA_ID_CODECNAME:{
934 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
937 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
938 context->codec_name = text;
943 case GST_MATROSKA_ID_CODECDELAY:{
946 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
949 context->codec_delay = num;
951 GST_DEBUG_OBJECT (demux, "CodecDelay: %" GST_TIME_FORMAT,
952 GST_TIME_ARGS (num));
957 case GST_MATROSKA_ID_SEEKPREROLL:{
960 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
963 context->seek_preroll = num;
965 GST_DEBUG_OBJECT (demux, "SeekPreroll: %" GST_TIME_FORMAT,
966 GST_TIME_ARGS (num));
970 /* name of this track */
971 case GST_MATROSKA_ID_TRACKNAME:{
974 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
977 context->name = text;
978 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
982 /* language (matters for audio/subtitles, mostly) */
983 case GST_MATROSKA_ID_TRACKLANGUAGE:{
986 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
990 context->language = text;
993 if (strlen (context->language) >= 4 && context->language[3] == '-')
994 context->language[3] = '\0';
996 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
997 GST_STR_NULL (context->language));
1001 /* whether this is actually used */
1002 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1005 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1009 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1011 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1013 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1014 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1018 /* whether it's the default for this track type */
1019 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1022 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1026 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1028 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1030 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1031 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
1035 /* whether the track must be used during playback */
1036 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1039 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1043 context->flags |= GST_MATROSKA_TRACK_FORCED;
1045 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1047 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1048 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
1052 /* lacing (like MPEG, where blocks don't end/start on frame
1054 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1057 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1061 context->flags |= GST_MATROSKA_TRACK_LACING;
1063 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1065 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1066 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
1070 /* default length (in time) of one data block in this track */
1071 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1074 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1079 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1083 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1085 context->default_duration = num;
1089 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1090 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1095 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1098 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1102 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1106 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1107 context->timecodescale = num;
1112 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1115 /* we ignore these because they're nothing useful (i.e. crap)
1116 * or simply not implemented yet. */
1117 case GST_MATROSKA_ID_TRACKMINCACHE:
1118 case GST_MATROSKA_ID_TRACKMAXCACHE:
1119 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1120 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1121 case GST_MATROSKA_ID_TRACKOVERLAY:
1122 case GST_MATROSKA_ID_TRACKTRANSLATE:
1123 case GST_MATROSKA_ID_TRACKOFFSET:
1124 case GST_MATROSKA_ID_CODECSETTINGS:
1125 case GST_MATROSKA_ID_CODECINFOURL:
1126 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1127 case GST_MATROSKA_ID_CODECDECODEALL:
1128 ret = gst_ebml_read_skip (ebml);
1133 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1135 /* Decode codec private data if necessary */
1136 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1137 && context->codec_priv_size > 0) {
1138 if (!gst_matroska_decode_data (context->encodings,
1139 &context->codec_priv, &context->codec_priv_size,
1140 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1141 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1142 ret = GST_FLOW_ERROR;
1146 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1147 && ret != GST_FLOW_EOS)) {
1148 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1149 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1151 demux->common.num_streams--;
1152 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1153 g_assert (demux->common.src->len == demux->common.num_streams);
1154 gst_matroska_track_free (context);
1159 /* check for a cached track taglist */
1161 (GstTagList *) g_hash_table_lookup (demux->common.cached_track_taglists,
1162 GUINT_TO_POINTER (context->uid));
1164 gst_tag_list_insert (context->tags, cached_taglist, GST_TAG_MERGE_APPEND);
1166 /* now create the GStreamer connectivity */
1167 switch (context->type) {
1168 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1169 GstMatroskaTrackVideoContext *videocontext =
1170 (GstMatroskaTrackVideoContext *) context;
1172 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1173 templ = gst_element_class_get_pad_template (klass, "video_%u");
1174 caps = gst_matroska_demux_video_caps (videocontext,
1175 context->codec_id, context->codec_priv,
1176 context->codec_priv_size, &codec, &riff_fourcc);
1179 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1180 GST_TAG_VIDEO_CODEC, codec, NULL);
1181 context->tags_changed = TRUE;
1187 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1188 GstMatroskaTrackAudioContext *audiocontext =
1189 (GstMatroskaTrackAudioContext *) context;
1191 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1192 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1193 caps = gst_matroska_demux_audio_caps (audiocontext,
1194 context->codec_id, context->codec_priv, context->codec_priv_size,
1195 &codec, &riff_audio_fmt);
1198 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1199 GST_TAG_AUDIO_CODEC, codec, NULL);
1200 context->tags_changed = TRUE;
1206 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1207 GstMatroskaTrackSubtitleContext *subtitlecontext =
1208 (GstMatroskaTrackSubtitleContext *) context;
1210 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1211 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1212 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1213 context->codec_id, context->codec_priv, context->codec_priv_size);
1217 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1218 case GST_MATROSKA_TRACK_TYPE_LOGO:
1219 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1220 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1222 /* we should already have quit by now */
1223 g_assert_not_reached ();
1226 if ((context->language == NULL || *context->language == '\0') &&
1227 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1228 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1229 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1230 context->language = g_strdup ("eng");
1233 if (context->language) {
1236 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1237 lang = gst_tag_get_language_code (context->language);
1238 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1239 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1240 context->tags_changed = TRUE;
1244 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1245 "codec_id='%s'", context->codec_id);
1246 switch (context->type) {
1247 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1248 caps = gst_caps_new_empty_simple ("video/x-unknown");
1250 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1251 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1253 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1254 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1256 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1258 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1261 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1264 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1265 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1266 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1267 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1268 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1269 GST_FOURCC_ARGS (riff_fourcc));
1270 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1273 } else if (context->stream_headers != NULL) {
1274 gst_matroska_demux_add_stream_headers_to_caps (demux,
1275 context->stream_headers, caps);
1278 /* the pad in here */
1279 context->pad = gst_pad_new_from_template (templ, padname);
1280 context->caps = caps;
1282 gst_pad_set_event_function (context->pad,
1283 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1284 gst_pad_set_query_function (context->pad,
1285 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1287 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1290 gst_pad_set_element_private (context->pad, context);
1292 gst_pad_use_fixed_caps (context->pad);
1293 gst_pad_set_active (context->pad, TRUE);
1296 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1297 "%03" G_GUINT64_FORMAT ":%03" G_GUINT64_FORMAT,
1298 context->num, context->uid);
1300 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1303 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1304 demux->have_group_id = TRUE;
1306 demux->have_group_id = FALSE;
1307 gst_event_unref (stream_start);
1308 } else if (!demux->have_group_id) {
1309 demux->have_group_id = TRUE;
1310 demux->group_id = gst_util_group_id_next ();
1313 stream_start = gst_event_new_stream_start (stream_id);
1315 if (demux->have_group_id)
1316 gst_event_set_group_id (stream_start, demux->group_id);
1317 stream_flags = GST_STREAM_FLAG_NONE;
1318 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1319 stream_flags |= GST_STREAM_FLAG_SPARSE;
1320 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1321 stream_flags |= GST_STREAM_FLAG_SELECT;
1322 gst_event_set_stream_flags (stream_start, stream_flags);
1323 gst_pad_push_event (context->pad, stream_start);
1324 gst_pad_set_caps (context->pad, context->caps);
1327 if (demux->common.global_tags) {
1328 GstEvent *tag_event;
1330 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1331 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1332 GST_DEBUG_OBJECT (context->pad, "Sending global_tags %p: %" GST_PTR_FORMAT,
1333 demux->common.global_tags, demux->common.global_tags);
1336 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1338 gst_pad_push_event (context->pad, tag_event);
1341 if (G_UNLIKELY (context->tags_changed)) {
1342 GST_DEBUG_OBJECT (context->pad, "Sending tags %p: %"
1343 GST_PTR_FORMAT, context->tags, context->tags);
1344 gst_pad_push_event (context->pad,
1345 gst_event_new_tag (gst_tag_list_copy (context->tags)));
1346 context->tags_changed = FALSE;
1349 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1350 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1359 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1362 gboolean res = FALSE;
1363 GstMatroskaTrackContext *context = NULL;
1366 context = gst_pad_get_element_private (pad);
1369 switch (GST_QUERY_TYPE (query)) {
1370 case GST_QUERY_POSITION:
1374 gst_query_parse_position (query, &format, NULL);
1377 if (format == GST_FORMAT_TIME) {
1378 GST_OBJECT_LOCK (demux);
1380 gst_query_set_position (query, GST_FORMAT_TIME,
1381 MAX (context->pos, demux->stream_start_time) -
1382 demux->stream_start_time);
1384 gst_query_set_position (query, GST_FORMAT_TIME,
1385 MAX (demux->common.segment.position, demux->stream_start_time) -
1386 demux->stream_start_time);
1387 GST_OBJECT_UNLOCK (demux);
1388 } else if (format == GST_FORMAT_DEFAULT && context
1389 && context->default_duration) {
1390 GST_OBJECT_LOCK (demux);
1391 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1392 context->pos / context->default_duration);
1393 GST_OBJECT_UNLOCK (demux);
1395 GST_DEBUG_OBJECT (demux,
1396 "only position query in TIME and DEFAULT format is supported");
1402 case GST_QUERY_DURATION:
1406 gst_query_parse_duration (query, &format, NULL);
1409 if (format == GST_FORMAT_TIME) {
1410 GST_OBJECT_LOCK (demux);
1411 gst_query_set_duration (query, GST_FORMAT_TIME,
1412 demux->common.segment.duration);
1413 GST_OBJECT_UNLOCK (demux);
1414 } else if (format == GST_FORMAT_DEFAULT && context
1415 && context->default_duration) {
1416 GST_OBJECT_LOCK (demux);
1417 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1418 demux->common.segment.duration / context->default_duration);
1419 GST_OBJECT_UNLOCK (demux);
1421 GST_DEBUG_OBJECT (demux,
1422 "only duration query in TIME and DEFAULT format is supported");
1428 case GST_QUERY_SEEKING:
1432 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1433 GST_OBJECT_LOCK (demux);
1434 if (fmt == GST_FORMAT_TIME) {
1437 if (demux->streaming) {
1438 /* assuming we'll be able to get an index ... */
1439 seekable = demux->seekable;
1444 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1445 0, demux->common.segment.duration);
1448 GST_OBJECT_UNLOCK (demux);
1451 case GST_QUERY_SEGMENT:
1456 format = demux->common.segment.format;
1459 gst_segment_to_stream_time (&demux->common.segment, format,
1460 demux->common.segment.start);
1461 if ((stop = demux->common.segment.stop) == -1)
1462 stop = demux->common.segment.duration;
1465 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1467 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1474 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1477 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1486 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1488 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1492 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1495 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1497 return gst_matroska_demux_query (demux, pad, query);
1500 /* returns FALSE if there are no pads to deliver event to,
1501 * otherwise TRUE (whatever the outcome of event sending),
1502 * takes ownership of the passed event! */
1504 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1506 gboolean ret = FALSE;
1509 g_return_val_if_fail (event != NULL, FALSE);
1511 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1512 GST_EVENT_TYPE_NAME (event));
1514 g_assert (demux->common.src->len == demux->common.num_streams);
1515 for (i = 0; i < demux->common.src->len; i++) {
1516 GstMatroskaTrackContext *stream;
1518 stream = g_ptr_array_index (demux->common.src, i);
1519 gst_event_ref (event);
1520 gst_pad_push_event (stream->pad, event);
1524 gst_event_unref (event);
1529 gst_matroska_demux_send_tags (GstMatroskaDemux * demux)
1533 if (G_UNLIKELY (demux->common.global_tags_changed)) {
1534 GstEvent *tag_event;
1535 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1536 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1537 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1538 demux->common.global_tags, demux->common.global_tags);
1541 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1543 for (i = 0; i < demux->common.src->len; i++) {
1544 GstMatroskaTrackContext *stream;
1546 stream = g_ptr_array_index (demux->common.src, i);
1547 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1550 gst_event_unref (tag_event);
1551 demux->common.global_tags_changed = FALSE;
1554 g_assert (demux->common.src->len == demux->common.num_streams);
1555 for (i = 0; i < demux->common.src->len; i++) {
1556 GstMatroskaTrackContext *stream;
1558 stream = g_ptr_array_index (demux->common.src, i);
1560 if (G_UNLIKELY (stream->tags_changed)) {
1561 GST_DEBUG_OBJECT (demux, "Sending tags %p for pad %s:%s : %"
1562 GST_PTR_FORMAT, stream->tags,
1563 GST_DEBUG_PAD_NAME (stream->pad), stream->tags);
1564 gst_pad_push_event (stream->pad,
1565 gst_event_new_tag (gst_tag_list_copy (stream->tags)));
1566 stream->tags_changed = FALSE;
1572 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1574 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1577 g_return_val_if_fail (event != NULL, FALSE);
1579 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1580 /* no seeking until we are (safely) ready */
1581 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
1582 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
1583 gst_event_unref (event);
1586 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1588 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1589 GST_EVENT_TYPE_NAME (event));
1592 gst_event_unref (event);
1597 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1598 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1602 GST_OBJECT_LOCK (demux);
1605 /* seek (relative to matroska segment) */
1606 /* position might be invalid; will error when streaming resumes ... */
1607 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1608 demux->next_cluster_offset = 0;
1610 GST_DEBUG_OBJECT (demux,
1611 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1612 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1613 entry->block, GST_TIME_ARGS (entry->time));
1615 /* update the time */
1616 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1617 gst_flow_combiner_reset (demux->flowcombiner);
1618 demux->common.segment.position = entry->time;
1619 demux->seek_block = entry->block;
1620 demux->seek_first = TRUE;
1621 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1624 for (i = 0; i < demux->common.src->len; i++) {
1625 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1628 stream->to_offset = G_MAXINT64;
1630 if (stream->from_offset != -1)
1631 stream->to_offset = stream->from_offset;
1633 stream->from_offset = -1;
1634 stream->from_time = GST_CLOCK_TIME_NONE;
1637 GST_OBJECT_UNLOCK (demux);
1643 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1653 /* searches for a cluster start from @pos,
1654 * return GST_FLOW_OK and cluster position in @pos if found */
1655 static GstFlowReturn
1656 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
1658 gint64 newpos = *pos;
1660 GstFlowReturn ret = GST_FLOW_OK;
1661 const guint chunk = 64 * 1024;
1662 GstBuffer *buf = NULL;
1664 gpointer data = NULL;
1669 gint64 oldpos, oldlength;
1671 orig_offset = demux->common.offset;
1673 GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
1676 if (demux->clusters) {
1679 cpos = gst_util_array_binary_search (demux->clusters->data,
1680 demux->clusters->len, sizeof (gint64),
1681 (GCompareDataFunc) gst_matroska_cluster_compare,
1682 GST_SEARCH_MODE_AFTER, pos, NULL);
1685 GST_DEBUG_OBJECT (demux,
1686 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1687 demux->common.offset = *cpos;
1688 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1689 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1690 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1697 /* read in at newpos and scan for ebml cluster id */
1698 oldpos = oldlength = -1;
1700 GstByteReader reader;
1704 gst_buffer_unmap (buf, &map);
1705 gst_buffer_unref (buf);
1708 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, chunk, &buf);
1709 if (ret != GST_FLOW_OK)
1711 GST_DEBUG_OBJECT (demux,
1712 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1713 gst_buffer_get_size (buf), newpos);
1714 gst_buffer_map (buf, &map, GST_MAP_READ);
1717 if (oldpos == newpos && oldlength == map.size) {
1718 GST_ERROR_OBJECT (demux, "Stuck at same position");
1719 ret = GST_FLOW_ERROR;
1723 oldlength = map.size;
1726 gst_byte_reader_init (&reader, data, size);
1728 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1729 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1730 if (cluster_pos >= 0) {
1731 newpos += cluster_pos;
1732 /* prepare resuming at next byte */
1733 if (!gst_byte_reader_skip (&reader, cluster_pos + 1)) {
1734 GST_DEBUG_OBJECT (demux, "Need more data -> continue");
1737 GST_DEBUG_OBJECT (demux,
1738 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1739 /* extra checks whether we really sync'ed to a cluster:
1740 * - either it is the first and only cluster
1741 * - either there is a cluster after this one
1742 * - either cluster length is undefined
1744 /* ok if first cluster (there may not a subsequent one) */
1745 if (newpos == demux->first_cluster_offset) {
1746 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1749 demux->common.offset = newpos;
1750 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1751 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1752 if (ret != GST_FLOW_OK) {
1753 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1756 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1757 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1759 /* ok if undefined length or first cluster */
1760 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1761 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1765 demux->common.offset += length + needed;
1766 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1767 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1768 if (ret != GST_FLOW_OK)
1770 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1771 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1772 if (id == GST_MATROSKA_ID_CLUSTER)
1774 /* not ok, resume */
1777 /* partial cluster id may have been in tail of buffer */
1778 newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
1783 gst_buffer_unmap (buf, &map);
1784 gst_buffer_unref (buf);
1789 demux->common.offset = orig_offset;
1794 /* bisect and scan through file for cluster starting before @time,
1795 * returns fake index entry with corresponding info on cluster */
1796 static GstMatroskaIndex *
1797 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
1799 GstMatroskaIndex *entry = NULL;
1800 GstMatroskaReadState current_state;
1801 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
1802 gint64 opos, newpos, startpos = 0, current_offset;
1803 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
1804 const guint chunk = 64 * 1024;
1810 /* (under)estimate new position, resync using cluster ebml id,
1811 * and scan forward to appropriate cluster
1812 * (and re-estimate if need to go backward) */
1814 prev_cluster_time = GST_CLOCK_TIME_NONE;
1816 /* store some current state */
1817 current_state = demux->common.state;
1818 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
1820 current_cluster_offset = demux->cluster_offset;
1821 current_cluster_time = demux->cluster_time;
1822 current_offset = demux->common.offset;
1824 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
1826 /* estimate using start and current position */
1827 GST_OBJECT_LOCK (demux);
1828 opos = demux->common.offset - demux->common.ebml_segment_start;
1829 otime = demux->common.segment.position;
1830 GST_OBJECT_UNLOCK (demux);
1833 time = MAX (time, demux->stream_start_time);
1835 /* avoid division by zero in first estimation below */
1836 if (otime <= demux->stream_start_time)
1840 GST_LOG_OBJECT (demux,
1841 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
1842 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
1843 GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
1844 GST_TIME_ARGS (otime - demux->stream_start_time),
1845 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
1847 if (otime <= demux->stream_start_time) {
1851 gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
1852 time - demux->stream_start_time,
1853 otime - demux->stream_start_time) - chunk;
1857 /* favour undershoot */
1858 newpos = newpos * 90 / 100;
1859 newpos += demux->common.ebml_segment_start;
1861 GST_DEBUG_OBJECT (demux,
1862 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1863 GST_TIME_ARGS (time), newpos);
1865 /* and at least start scanning before previous scan start to avoid looping */
1866 startpos = startpos * 90 / 100;
1867 if (startpos && startpos < newpos)
1870 /* read in at newpos and scan for ebml cluster id */
1874 ret = gst_matroska_demux_search_cluster (demux, &newpos);
1875 if (ret == GST_FLOW_EOS) {
1876 /* heuristic HACK */
1877 newpos = startpos * 80 / 100;
1878 GST_DEBUG_OBJECT (demux, "EOS; "
1879 "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
1880 GST_TIME_ARGS (time), newpos);
1883 } else if (ret != GST_FLOW_OK) {
1890 /* then start scanning and parsing for cluster time,
1891 * re-estimate if overshoot, otherwise next cluster and so on */
1892 demux->common.offset = newpos;
1893 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
1895 guint64 cluster_size = 0;
1897 /* peek and parse some elements */
1898 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1899 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1900 if (ret != GST_FLOW_OK)
1902 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
1903 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
1905 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
1906 if (ret != GST_FLOW_OK)
1909 if (id == GST_MATROSKA_ID_CLUSTER) {
1910 cluster_time = GST_CLOCK_TIME_NONE;
1911 if (length == G_MAXUINT64)
1914 cluster_size = length + needed;
1916 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
1917 cluster_time == GST_CLOCK_TIME_NONE) {
1918 cluster_time = demux->cluster_time * demux->common.time_scale;
1919 cluster_offset = demux->cluster_offset;
1920 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
1921 " with time %" GST_TIME_FORMAT, cluster_offset,
1922 GST_TIME_ARGS (cluster_time));
1923 if (cluster_time > time) {
1924 GST_DEBUG_OBJECT (demux, "overshot target");
1925 /* cluster overshoots */
1926 if (cluster_offset == demux->first_cluster_offset) {
1927 /* but no prev one */
1928 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
1929 prev_cluster_time = cluster_time;
1930 prev_cluster_offset = cluster_offset;
1933 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
1934 /* prev cluster did not overshoot, so prev cluster is target */
1937 /* re-estimate using this new position info */
1938 opos = cluster_offset;
1939 otime = cluster_time;
1943 /* cluster undershoots, goto next one */
1944 prev_cluster_time = cluster_time;
1945 prev_cluster_offset = cluster_offset;
1946 /* skip cluster if length is defined,
1947 * otherwise will be skippingly parsed into */
1949 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
1950 demux->common.offset = cluster_offset + cluster_size;
1951 demux->cluster_time = GST_CLOCK_TIME_NONE;
1953 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
1960 if (ret == GST_FLOW_EOS) {
1961 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
1967 entry = g_new0 (GstMatroskaIndex, 1);
1968 entry->time = prev_cluster_time;
1969 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
1970 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
1971 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
1975 /* restore some state */
1976 demux->cluster_offset = current_cluster_offset;
1977 demux->cluster_time = current_cluster_time;
1978 demux->common.offset = current_offset;
1979 demux->common.state = current_state;
1985 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
1986 GstPad * pad, GstEvent * event)
1988 GstMatroskaIndex *entry = NULL;
1989 GstMatroskaIndex scan_entry;
1991 GstSeekType cur_type, stop_type;
1993 gboolean flush, keyunit, before, after, snap_next;
1996 GstMatroskaTrackContext *track = NULL;
1997 GstSegment seeksegment = { 0, };
1998 gboolean update = TRUE;
1999 gboolean pad_locked = FALSE;
2001 GstSearchMode snap_dir;
2003 g_return_val_if_fail (event != NULL, FALSE);
2006 track = gst_pad_get_element_private (pad);
2008 GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
2010 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2012 seqnum = gst_event_get_seqnum (event);
2014 /* we can only seek on time */
2015 if (format != GST_FORMAT_TIME) {
2016 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2020 /* copy segment, we need this because we still need the old
2021 * segment when we close the current segment. */
2022 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
2024 /* pull mode without index means that the actual duration is not known,
2025 * we might be playing a file that's still being recorded
2026 * so, invalidate our current duration, which is only a moving target,
2027 * and should not be used to clamp anything */
2028 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
2029 seeksegment.duration = GST_CLOCK_TIME_NONE;
2032 GST_DEBUG_OBJECT (demux, "configuring seek");
2033 /* Subtract stream_start_time so we always seek on a segment
2035 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2036 seeksegment.start -= demux->stream_start_time;
2037 seeksegment.position -= demux->stream_start_time;
2038 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2039 seeksegment.stop -= demux->stream_start_time;
2041 seeksegment.stop = seeksegment.duration;
2044 gst_segment_do_seek (&seeksegment, rate, format, flags,
2045 cur_type, cur, stop_type, stop, &update);
2047 /* Restore the clip timestamp offset */
2048 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2049 seeksegment.position += demux->stream_start_time;
2050 seeksegment.start += demux->stream_start_time;
2051 if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2052 seeksegment.stop = seeksegment.duration;
2053 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2054 seeksegment.stop += demux->stream_start_time;
2057 /* restore segment duration (if any effect),
2058 * would be determined again when parsing, but anyway ... */
2059 seeksegment.duration = demux->common.segment.duration;
2061 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2062 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2063 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
2064 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
2066 /* always do full update if flushing,
2067 * otherwise problems might arise downstream with missing keyframes etc */
2068 update = update || flush;
2070 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2072 /* check sanity before we start flushing and all that */
2073 snap_next = after && !before;
2074 if (seeksegment.rate < 0)
2075 snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
2077 snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
2079 GST_OBJECT_LOCK (demux);
2080 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2081 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2082 seeksegment.position, &demux->seek_index, &demux->seek_entry,
2083 snap_dir)) == NULL) {
2084 /* pull mode without index can scan later on */
2085 if (demux->streaming) {
2086 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2087 GST_OBJECT_UNLOCK (demux);
2089 } else if (rate < 0.0) {
2090 /* FIXME: We should build an index during playback or when scanning
2091 * that can be used here. The reverse playback code requires seek_index
2092 * and seek_entry to be set!
2094 GST_DEBUG_OBJECT (demux,
2095 "No matching seek entry in index, needed for reverse playback");
2096 GST_OBJECT_UNLOCK (demux);
2100 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2101 GST_OBJECT_UNLOCK (demux);
2104 /* only have to update some segment,
2105 * but also still have to honour flush and so on */
2106 GST_DEBUG_OBJECT (demux, "... no update");
2107 /* bad goto, bad ... */
2111 if (demux->streaming)
2116 GstEvent *flush_event = gst_event_new_flush_start ();
2117 gst_event_set_seqnum (flush_event, seqnum);
2118 GST_DEBUG_OBJECT (demux, "Starting flush");
2119 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2120 gst_matroska_demux_send_event (demux, flush_event);
2122 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2123 gst_pad_pause_task (demux->common.sinkpad);
2127 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2132 /* now grab the stream lock so that streaming cannot continue, for
2133 * non flushing seeks when the element is in PAUSED this could block
2135 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2136 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2139 /* pull mode without index can do some scanning */
2140 if (!demux->streaming && !entry) {
2141 GstEvent *flush_event;
2143 /* need to stop flushing upstream as we need it next */
2145 flush_event = gst_event_new_flush_stop (TRUE);
2146 gst_event_set_seqnum (flush_event, seqnum);
2147 gst_pad_push_event (demux->common.sinkpad, flush_event);
2149 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2150 /* keep local copy */
2152 scan_entry = *entry;
2154 entry = &scan_entry;
2156 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2158 flush_event = gst_event_new_flush_stop (TRUE);
2159 gst_event_set_seqnum (flush_event, seqnum);
2160 gst_matroska_demux_send_event (demux, flush_event);
2168 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2169 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2170 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2171 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2172 seeksegment.position = seeksegment.start;
2173 seeksegment.time = seeksegment.start - demux->stream_start_time;
2176 if (demux->streaming) {
2177 GST_OBJECT_LOCK (demux);
2178 /* track real position we should start at */
2179 GST_DEBUG_OBJECT (demux, "storing segment start");
2180 demux->requested_seek_time = seeksegment.position;
2181 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2182 GST_OBJECT_UNLOCK (demux);
2183 /* need to seek to cluster start to pick up cluster time */
2184 /* upstream takes care of flushing and all that
2185 * ... and newsegment event handling takes care of the rest */
2186 return perform_seek_to_offset (demux, rate,
2187 entry->pos + demux->common.ebml_segment_start, seqnum);
2192 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2193 gst_event_set_seqnum (flush_event, seqnum);
2194 GST_DEBUG_OBJECT (demux, "Stopping flush");
2195 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2196 gst_matroska_demux_send_event (demux, flush_event);
2199 GST_OBJECT_LOCK (demux);
2200 /* now update the real segment info */
2201 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2202 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2203 GST_OBJECT_UNLOCK (demux);
2205 /* update some (segment) state */
2206 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2209 /* notify start of new segment */
2210 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2213 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2214 GST_FORMAT_TIME, demux->common.segment.start);
2215 gst_message_set_seqnum (msg, seqnum);
2216 gst_element_post_message (GST_ELEMENT (demux), msg);
2219 GST_OBJECT_LOCK (demux);
2220 if (demux->new_segment)
2221 gst_event_unref (demux->new_segment);
2223 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2224 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2225 gst_event_set_seqnum (demux->new_segment, seqnum);
2226 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2227 demux->to_time = demux->common.segment.position;
2229 demux->to_time = GST_CLOCK_TIME_NONE;
2230 GST_OBJECT_UNLOCK (demux);
2232 /* restart our task since it might have been stopped when we did the
2234 gst_pad_start_task (demux->common.sinkpad,
2235 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2237 /* streaming can continue now */
2239 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2247 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2249 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2255 * Handle whether we can perform the seek event or if we have to let the chain
2256 * function handle seeks to build the seek indexes first.
2259 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2263 GstSeekType cur_type, stop_type;
2268 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2273 /* we can only seek on time */
2274 if (format != GST_FORMAT_TIME) {
2275 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2279 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2280 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2284 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2285 GST_DEBUG_OBJECT (demux,
2286 "Non-flushing seek not supported in streaming mode");
2290 if (flags & GST_SEEK_FLAG_SEGMENT) {
2291 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2295 /* check for having parsed index already */
2296 if (!demux->common.index_parsed) {
2297 gboolean building_index;
2300 if (!demux->index_offset) {
2301 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2305 GST_OBJECT_LOCK (demux);
2306 /* handle the seek event in the chain function */
2307 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2308 /* no more seek can be issued until state reset to _DATA */
2310 /* copy the event */
2311 if (demux->seek_event)
2312 gst_event_unref (demux->seek_event);
2313 demux->seek_event = gst_event_ref (event);
2315 /* set the building_index flag so that only one thread can setup the
2316 * structures for index seeking. */
2317 building_index = demux->building_index;
2318 if (!building_index) {
2319 demux->building_index = TRUE;
2320 offset = demux->index_offset;
2322 GST_OBJECT_UNLOCK (demux);
2324 if (!building_index) {
2325 /* seek to the first subindex or legacy index */
2326 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2327 return perform_seek_to_offset (demux, rate, offset,
2328 gst_event_get_seqnum (event));
2331 /* well, we are handling it already */
2335 /* delegate to tweaked regular seek */
2336 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2340 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2343 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2344 gboolean res = TRUE;
2346 switch (GST_EVENT_TYPE (event)) {
2347 case GST_EVENT_SEEK:
2348 /* no seeking until we are (safely) ready */
2349 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2350 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2351 gst_event_unref (event);
2354 if (!demux->streaming)
2355 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2357 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2358 gst_event_unref (event);
2363 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2364 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2365 GstMatroskaTrackVideoContext *videocontext =
2366 (GstMatroskaTrackVideoContext *) context;
2368 GstClockTimeDiff diff;
2369 GstClockTime timestamp;
2371 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2373 GST_OBJECT_LOCK (demux);
2374 videocontext->earliest_time = timestamp + diff;
2375 GST_OBJECT_UNLOCK (demux);
2378 gst_event_unref (event);
2382 case GST_EVENT_TOC_SELECT:
2385 GstTocEntry *entry = NULL;
2386 GstEvent *seek_event;
2389 if (!demux->common.toc) {
2390 GST_DEBUG_OBJECT (demux, "no TOC to select");
2393 gst_event_parse_toc_select (event, &uid);
2395 GST_OBJECT_LOCK (demux);
2396 entry = gst_toc_find_entry (demux->common.toc, uid);
2397 if (entry == NULL) {
2398 GST_OBJECT_UNLOCK (demux);
2399 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2402 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2403 GST_OBJECT_UNLOCK (demux);
2404 seek_event = gst_event_new_seek (1.0,
2406 GST_SEEK_FLAG_FLUSH,
2407 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2408 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2409 gst_event_unref (seek_event);
2413 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2417 gst_event_unref (event);
2421 /* events we don't need to handle */
2422 case GST_EVENT_NAVIGATION:
2423 gst_event_unref (event);
2427 case GST_EVENT_LATENCY:
2429 res = gst_pad_push_event (demux->common.sinkpad, event);
2436 static GstFlowReturn
2437 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2439 GstFlowReturn ret = GST_FLOW_EOS;
2440 gboolean done = TRUE;
2443 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2444 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2447 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2449 if (!demux->seek_entry) {
2450 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2454 for (i = 0; i < demux->common.src->len; i++) {
2455 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2457 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2458 ", stream %d at %" GST_TIME_FORMAT,
2459 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2460 GST_TIME_ARGS (stream->from_time));
2461 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2462 if (stream->from_time > demux->common.segment.start) {
2463 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2467 /* nothing pushed for this stream;
2468 * likely seek entry did not start at keyframe, so all was skipped.
2469 * So we need an earlier entry */
2475 GstMatroskaIndex *entry;
2477 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2478 --demux->seek_entry);
2479 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2489 static GstFlowReturn
2490 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2492 GstFlowReturn ret = GST_FLOW_OK;
2495 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2497 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2498 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2502 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2503 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2507 /* one track within the "all-tracks" header */
2508 case GST_MATROSKA_ID_TRACKENTRY:
2509 ret = gst_matroska_demux_add_stream (demux, ebml);
2513 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2518 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2520 demux->tracks_parsed = TRUE;
2526 * Read signed/unsigned "EBML" numbers.
2527 * Return: number of bytes processed.
2531 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2533 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2541 while (read <= 8 && !(total & len_mask)) {
2548 if ((total &= (len_mask - 1)) == len_mask - 1)
2553 if (data[n] == 0xff)
2555 total = (total << 8) | data[n];
2559 if (read == num_ffs && total != 0)
2568 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2573 /* read as unsigned number first */
2574 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2578 if (unum == G_MAXUINT64)
2581 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2587 * Mostly used for subtitles. We add void filler data for each
2588 * lagging stream to make sure we don't deadlock.
2592 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2594 GstClockTime gap_threshold;
2597 GST_OBJECT_LOCK (demux);
2599 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2600 GST_TIME_ARGS (demux->common.segment.position));
2602 g_assert (demux->common.num_streams == demux->common.src->len);
2603 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2604 GstMatroskaTrackContext *context;
2606 context = g_ptr_array_index (demux->common.src, stream_nr);
2608 GST_LOG_OBJECT (demux,
2609 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2610 GST_TIME_ARGS (context->pos));
2612 /* Only send gap events on non-subtitle streams if lagging way behind.
2613 * The 0.5 second threshold for subtitle streams is also quite random. */
2614 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
2615 gap_threshold = GST_SECOND / 2;
2617 gap_threshold = 3 * GST_SECOND;
2619 /* Lag need only be considered if we have advanced into requested segment */
2620 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2621 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2622 demux->common.segment.position > demux->common.segment.start &&
2623 context->pos + gap_threshold < demux->common.segment.position) {
2626 guint64 start = context->pos;
2627 guint64 stop = demux->common.segment.position - gap_threshold;
2629 GST_DEBUG_OBJECT (demux,
2630 "Synchronizing stream %d with other by advancing time from %"
2631 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2632 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2634 context->pos = stop;
2636 event = gst_event_new_gap (start, stop - start);
2637 GST_OBJECT_UNLOCK (demux);
2638 gst_pad_push_event (context->pad, event);
2639 GST_OBJECT_LOCK (demux);
2643 GST_OBJECT_UNLOCK (demux);
2646 static GstFlowReturn
2647 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2648 GstMatroskaTrackContext * stream)
2650 GstFlowReturn ret = GST_FLOW_OK;
2653 num = gst_buffer_list_length (stream->stream_headers);
2654 for (i = 0; i < num; ++i) {
2657 buf = gst_buffer_list_get (stream->stream_headers, i);
2658 buf = gst_buffer_copy (buf);
2660 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2662 if (stream->set_discont) {
2663 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2664 stream->set_discont = FALSE;
2666 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2669 /* push out all headers in one go and use last flow return */
2670 ret = gst_pad_push (stream->pad, buf);
2673 /* don't need these any longer */
2674 gst_buffer_list_unref (stream->stream_headers);
2675 stream->stream_headers = NULL;
2678 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2684 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2685 GstMatroskaTrackContext * stream)
2689 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2691 if (!stream->codec_priv)
2694 /* ideally, VobSub private data should be parsed and stored more convenient
2695 * elsewhere, but for now, only interested in a small part */
2697 /* make sure we have terminating 0 */
2698 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2700 /* just locate and parse palette part */
2701 start = strstr (buf, "palette:");
2706 guint8 r, g, b, y, u, v;
2709 while (g_ascii_isspace (*start))
2711 for (i = 0; i < 16; i++) {
2712 if (sscanf (start, "%06x", &col) != 1)
2715 while ((*start == ',') || g_ascii_isspace (*start))
2717 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2718 r = (col >> 16) & 0xff;
2719 g = (col >> 8) & 0xff;
2721 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2723 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2724 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2725 clut[i] = (y << 16) | (u << 8) | v;
2728 /* got them all without problems; build and send event */
2732 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2733 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2734 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2735 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2736 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2737 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2738 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2739 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2740 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2741 G_TYPE_INT, clut[15], NULL);
2743 gst_pad_push_event (stream->pad,
2744 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2751 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2755 GST_OBJECT_LOCK (demux);
2757 g_assert (demux->common.num_streams == demux->common.src->len);
2758 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2759 GstMatroskaTrackContext *stream;
2761 stream = g_ptr_array_index (demux->common.src, stream_nr);
2763 if (stream->send_stream_headers) {
2764 if (stream->stream_headers != NULL) {
2765 gst_matroska_demux_push_stream_headers (demux, stream);
2767 /* FIXME: perhaps we can just disable and skip this stream then */
2768 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2769 ("Failed to extract stream headers from codec private data"));
2771 stream->send_stream_headers = FALSE;
2774 if (stream->send_dvd_event) {
2775 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2776 /* FIXME: should we send this event again after (flushing) seek ? */
2777 stream->send_dvd_event = FALSE;
2781 GST_OBJECT_UNLOCK (demux);
2784 static GstFlowReturn
2785 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2786 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2789 guint seq_header_len;
2790 guint32 header, tmp;
2792 if (stream->codec_state) {
2793 seq_header = stream->codec_state;
2794 seq_header_len = stream->codec_state_size;
2795 } else if (stream->codec_priv) {
2796 seq_header = stream->codec_priv;
2797 seq_header_len = stream->codec_priv_size;
2802 /* Sequence header only needed for keyframes */
2803 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2806 if (gst_buffer_get_size (*buf) < 4)
2809 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2810 header = GUINT32_FROM_BE (tmp);
2812 /* Sequence start code, if not found prepend */
2813 if (header != 0x000001b3) {
2816 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2818 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2821 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2822 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2823 gst_buffer_get_size (*buf));
2825 gst_buffer_unref (*buf);
2832 static GstFlowReturn
2833 gst_matroska_demux_add_wvpk_header (GstElement * element,
2834 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2836 GstMatroskaTrackAudioContext *audiocontext =
2837 (GstMatroskaTrackAudioContext *) stream;
2838 GstBuffer *newbuf = NULL;
2839 GstMapInfo map, outmap;
2840 guint8 *buf_data, *data;
2848 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2851 wvh.total_samples = -1;
2852 wvh.block_index = audiocontext->wvpk_block_index;
2854 if (audiocontext->channels <= 2) {
2855 guint32 block_samples, tmp;
2856 gsize size = gst_buffer_get_size (*buf);
2858 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2859 block_samples = GUINT32_FROM_LE (tmp);
2860 /* we need to reconstruct the header of the wavpack block */
2862 /* -20 because ck_size is the size of the wavpack block -8
2863 * and lace_size is the size of the wavpack block + 12
2864 * (the three guint32 of the header that already are in the buffer) */
2865 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2867 /* block_samples, flags and crc are already in the buffer */
2868 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2870 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2876 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2877 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2878 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2879 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2880 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2881 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2882 gst_buffer_unmap (newbuf, &outmap);
2884 /* Append data from buf: */
2885 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2886 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2888 gst_buffer_unref (*buf);
2890 audiocontext->wvpk_block_index += block_samples;
2892 guint8 *outdata = NULL;
2894 gsize buf_size, size, out_size = 0;
2895 guint32 block_samples, flags, crc, blocksize;
2897 gst_buffer_map (*buf, &map, GST_MAP_READ);
2898 buf_data = map.data;
2899 buf_size = map.size;
2902 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2903 gst_buffer_unmap (*buf, &map);
2904 return GST_FLOW_ERROR;
2910 block_samples = GST_READ_UINT32_LE (data);
2915 flags = GST_READ_UINT32_LE (data);
2918 crc = GST_READ_UINT32_LE (data);
2921 blocksize = GST_READ_UINT32_LE (data);
2925 if (blocksize == 0 || size < blocksize)
2928 g_assert ((newbuf == NULL) == (outdata == NULL));
2930 if (newbuf == NULL) {
2931 out_size = sizeof (Wavpack4Header) + blocksize;
2932 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2934 gst_buffer_copy_into (newbuf, *buf,
2935 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2938 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2939 outdata = outmap.data;
2941 gst_buffer_unmap (newbuf, &outmap);
2942 out_size += sizeof (Wavpack4Header) + blocksize;
2943 gst_buffer_set_size (newbuf, out_size);
2944 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2945 outdata = outmap.data;
2948 outdata[outpos] = 'w';
2949 outdata[outpos + 1] = 'v';
2950 outdata[outpos + 2] = 'p';
2951 outdata[outpos + 3] = 'k';
2954 GST_WRITE_UINT32_LE (outdata + outpos,
2955 blocksize + sizeof (Wavpack4Header) - 8);
2956 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2957 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2958 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2959 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2960 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2961 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2962 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2963 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2966 memmove (outdata + outpos, data, blocksize);
2967 outpos += blocksize;
2971 gst_buffer_unmap (*buf, &map);
2972 gst_buffer_unref (*buf);
2975 gst_buffer_unmap (newbuf, &outmap);
2978 audiocontext->wvpk_block_index += block_samples;
2984 static GstFlowReturn
2985 gst_matroska_demux_add_prores_header (GstElement * element,
2986 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2988 GstBuffer *newbuf = gst_buffer_new_allocate (NULL, 8, NULL);
2992 if (!gst_buffer_map (newbuf, &map, GST_MAP_WRITE)) {
2993 GST_ERROR ("Failed to map newly allocated buffer");
2994 return GST_FLOW_ERROR;
2997 frame_size = gst_buffer_get_size (*buf);
2999 GST_WRITE_UINT32_BE (map.data, frame_size);
3005 gst_buffer_unmap (newbuf, &map);
3006 *buf = gst_buffer_append (newbuf, *buf);
3011 /* @text must be null-terminated */
3013 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
3018 g_return_val_if_fail (text != NULL, FALSE);
3020 /* yes, this might all lead to false positives ... */
3021 tag = (gchar *) text;
3022 while ((tag = strchr (tag, '<'))) {
3024 if (*tag != '\0' && *(tag + 1) == '>') {
3025 /* some common convenience ones */
3026 /* maybe any character will do here ? */
3039 if (strstr (text, "<span"))
3045 static GstFlowReturn
3046 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
3047 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3049 GstMatroskaTrackSubtitleContext *sub_stream;
3050 const gchar *encoding;
3055 gboolean needs_unmap = TRUE;
3057 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3059 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
3062 /* The subtitle buffer we push out should not include a NUL terminator as
3063 * part of the data. */
3064 if (map.data[map.size - 1] == '\0') {
3065 gst_buffer_set_size (*buf, map.size - 1);
3066 gst_buffer_unmap (*buf, &map);
3067 gst_buffer_map (*buf, &map, GST_MAP_READ);
3070 if (!sub_stream->invalid_utf8) {
3071 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
3074 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
3075 " is not valid UTF-8, this is broken according to the matroska"
3076 " specification", stream->num);
3077 sub_stream->invalid_utf8 = TRUE;
3080 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3081 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3082 if (encoding == NULL || *encoding == '\0') {
3083 /* if local encoding is UTF-8 and no encoding specified
3084 * via the environment variable, assume ISO-8859-15 */
3085 if (g_get_charset (&encoding)) {
3086 encoding = "ISO-8859-15";
3091 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3092 (char *) "*", NULL, NULL, &err);
3095 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3096 encoding, err->message);
3100 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3101 encoding = "ISO-8859-15";
3103 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3104 encoding, (char *) "*", NULL, NULL, NULL);
3107 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3108 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3111 utf8 = g_strdup ("invalid subtitle");
3113 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3114 gst_buffer_unmap (*buf, &map);
3115 gst_buffer_copy_into (newbuf, *buf,
3116 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3118 gst_buffer_unref (*buf);
3121 gst_buffer_map (*buf, &map, GST_MAP_READ);
3125 if (sub_stream->check_markup) {
3126 /* caps claim markup text, so we need to escape text,
3127 * except if text is already markup and then needs no further escaping */
3128 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3129 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3131 if (!sub_stream->seen_markup_tag) {
3132 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3134 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3135 gst_buffer_unmap (*buf, &map);
3136 gst_buffer_copy_into (newbuf, *buf,
3137 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3138 GST_BUFFER_COPY_META, 0, -1);
3139 gst_buffer_unref (*buf);
3142 needs_unmap = FALSE;
3147 gst_buffer_unmap (*buf, &map);
3152 static GstFlowReturn
3153 gst_matroska_demux_check_aac (GstElement * element,
3154 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3159 gst_buffer_extract (*buf, 0, data, 2);
3160 size = gst_buffer_get_size (*buf);
3162 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3165 /* tss, ADTS data, remove codec_data
3166 * still assume it is at least parsed */
3167 stream->caps = gst_caps_make_writable (stream->caps);
3168 s = gst_caps_get_structure (stream->caps, 0);
3170 gst_structure_remove_field (s, "codec_data");
3171 gst_pad_set_caps (stream->pad, stream->caps);
3172 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3173 "new caps: %" GST_PTR_FORMAT, stream->caps);
3176 /* disable subsequent checking */
3177 stream->postprocess_frame = NULL;
3183 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3184 GstBuffer * buffer, gsize alignment)
3188 gst_buffer_map (buffer, &map, GST_MAP_READ);
3190 if (map.size < sizeof (guintptr)) {
3191 gst_buffer_unmap (buffer, &map);
3195 if (((guintptr) map.data) & (alignment - 1)) {
3196 GstBuffer *new_buffer;
3197 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3199 new_buffer = gst_buffer_new_allocate (NULL,
3200 gst_buffer_get_size (buffer), ¶ms);
3202 /* Copy data "by hand", so ensure alignment is kept: */
3203 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3205 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3206 GST_DEBUG_OBJECT (demux,
3207 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3210 gst_buffer_unmap (buffer, &map);
3211 gst_buffer_unref (buffer);
3216 gst_buffer_unmap (buffer, &map);
3220 static GstFlowReturn
3221 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3222 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3223 gboolean is_simpleblock)
3225 GstMatroskaTrackContext *stream = NULL;
3226 GstFlowReturn ret = GST_FLOW_OK;
3227 gboolean readblock = FALSE;
3229 guint64 block_duration = -1;
3230 gint64 block_discardpadding = 0;
3231 GstBuffer *buf = NULL;
3233 gint stream_num = -1, n, laces = 0;
3235 gint *lace_size = NULL;
3238 gint64 referenceblock = 0;
3240 GstClockTime buffer_timestamp;
3242 offset = gst_ebml_read_get_offset (ebml);
3244 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3245 if (!is_simpleblock) {
3246 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3250 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3254 /* one block inside the group. Note, block parsing is one
3255 * of the harder things, so this code is a bit complicated.
3256 * See http://www.matroska.org/ for documentation. */
3257 case GST_MATROSKA_ID_SIMPLEBLOCK:
3258 case GST_MATROSKA_ID_BLOCK:
3264 gst_buffer_unmap (buf, &map);
3265 gst_buffer_unref (buf);
3268 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3271 gst_buffer_map (buf, &map, GST_MAP_READ);
3275 /* first byte(s): blocknum */
3276 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3281 /* fetch stream from num */
3282 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3284 if (G_UNLIKELY (size < 3)) {
3285 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3286 /* non-fatal, try next block(group) */
3289 } else if (G_UNLIKELY (stream_num < 0 ||
3290 stream_num >= demux->common.num_streams)) {
3291 /* let's not give up on a stray invalid track number */
3292 GST_WARNING_OBJECT (demux,
3293 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3294 "; ignoring block", stream_num, num);
3298 stream = g_ptr_array_index (demux->common.src, stream_num);
3300 /* time (relative to cluster time) */
3301 time = ((gint16) GST_READ_UINT16_BE (data));
3304 flags = GST_READ_UINT8 (data);
3308 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3311 switch ((flags & 0x06) >> 1) {
3312 case 0x0: /* no lacing */
3314 lace_size = g_new (gint, 1);
3315 lace_size[0] = size;
3318 case 0x1: /* xiph lacing */
3319 case 0x2: /* fixed-size lacing */
3320 case 0x3: /* EBML lacing */
3322 goto invalid_lacing;
3323 laces = GST_READ_UINT8 (data) + 1;
3326 lace_size = g_new0 (gint, laces);
3328 switch ((flags & 0x06) >> 1) {
3329 case 0x1: /* xiph lacing */ {
3330 guint temp, total = 0;
3332 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3335 goto invalid_lacing;
3336 temp = GST_READ_UINT8 (data);
3337 lace_size[n] += temp;
3343 total += lace_size[n];
3345 lace_size[n] = size - total;
3349 case 0x2: /* fixed-size lacing */
3350 for (n = 0; n < laces; n++)
3351 lace_size[n] = size / laces;
3354 case 0x3: /* EBML lacing */ {
3357 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3361 total = lace_size[0] = num;
3362 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3366 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3370 lace_size[n] = lace_size[n - 1] + snum;
3371 total += lace_size[n];
3374 lace_size[n] = size - total;
3381 if (ret != GST_FLOW_OK)
3388 case GST_MATROSKA_ID_BLOCKDURATION:{
3389 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3390 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3395 case GST_MATROSKA_ID_DISCARDPADDING:{
3396 ret = gst_ebml_read_sint (ebml, &id, &block_discardpadding);
3397 GST_DEBUG_OBJECT (demux, "DiscardPadding: %" GST_STIME_FORMAT,
3398 GST_STIME_ARGS (block_discardpadding));
3402 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3403 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3404 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3409 case GST_MATROSKA_ID_CODECSTATE:{
3411 guint64 data_len = 0;
3414 gst_ebml_read_binary (ebml, &id, &data,
3415 &data_len)) != GST_FLOW_OK)
3418 if (G_UNLIKELY (stream == NULL)) {
3419 GST_WARNING_OBJECT (demux,
3420 "Unexpected CodecState subelement - ignoring");
3424 g_free (stream->codec_state);
3425 stream->codec_state = data;
3426 stream->codec_state_size = data_len;
3428 /* Decode if necessary */
3429 if (stream->encodings && stream->encodings->len > 0
3430 && stream->codec_state && stream->codec_state_size > 0) {
3431 if (!gst_matroska_decode_data (stream->encodings,
3432 &stream->codec_state, &stream->codec_state_size,
3433 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3434 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3438 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3439 stream->codec_state_size);
3444 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3448 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3449 case GST_MATROSKA_ID_BLOCKADDITIONS:
3450 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3451 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3452 case GST_MATROSKA_ID_SLICES:
3453 GST_DEBUG_OBJECT (demux,
3454 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3455 ret = gst_ebml_read_skip (ebml);
3463 /* reading a number or so could have failed */
3464 if (ret != GST_FLOW_OK)
3467 if (ret == GST_FLOW_OK && readblock) {
3468 gboolean invisible_frame = FALSE;
3469 gboolean delta_unit = FALSE;
3470 guint64 duration = 0;
3471 gint64 lace_time = 0;
3473 stream = g_ptr_array_index (demux->common.src, stream_num);
3475 if (cluster_time != GST_CLOCK_TIME_NONE) {
3476 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3477 * Drop unless the lace contains timestamp 0? */
3478 if (time < 0 && (-time) > cluster_time) {
3481 if (stream->timecodescale == 1.0)
3482 lace_time = (cluster_time + time) * demux->common.time_scale;
3485 gst_util_guint64_to_gdouble ((cluster_time + time) *
3486 demux->common.time_scale) * stream->timecodescale;
3489 lace_time = GST_CLOCK_TIME_NONE;
3492 /* need to refresh segment info ASAP */
3493 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3494 GstSegment *segment = &demux->common.segment;
3496 GstEvent *segment_event;
3498 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3499 demux->stream_start_time = lace_time;
3500 GST_DEBUG_OBJECT (demux,
3501 "Setting stream start time to %" GST_TIME_FORMAT,
3502 GST_TIME_ARGS (lace_time));
3504 clace_time = MAX (lace_time, demux->stream_start_time);
3505 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3506 demux->common.segment.position != 0) {
3507 GST_DEBUG_OBJECT (demux,
3508 "using stored seek position %" GST_TIME_FORMAT,
3509 GST_TIME_ARGS (demux->common.segment.position));
3510 clace_time = demux->common.segment.position + demux->stream_start_time;
3511 segment->position = GST_CLOCK_TIME_NONE;
3513 segment->start = clace_time;
3514 segment->stop = GST_CLOCK_TIME_NONE;
3515 segment->time = segment->start - demux->stream_start_time;
3516 segment->position = segment->start - demux->stream_start_time;
3517 GST_DEBUG_OBJECT (demux,
3518 "generated segment starting at %" GST_TIME_FORMAT ": %"
3519 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3520 /* now convey our segment notion downstream */
3521 segment_event = gst_event_new_segment (segment);
3522 if (demux->segment_seqnum)
3523 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3524 gst_matroska_demux_send_event (demux, segment_event);
3525 demux->need_segment = FALSE;
3526 demux->segment_seqnum = 0;
3529 /* send pending codec data headers for all streams,
3530 * before we perform sync across all streams */
3531 gst_matroska_demux_push_codec_data_all (demux);
3533 if (block_duration != -1) {
3534 if (stream->timecodescale == 1.0)
3535 duration = gst_util_uint64_scale (block_duration,
3536 demux->common.time_scale, 1);
3539 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3540 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3541 1)) * stream->timecodescale);
3542 } else if (stream->default_duration) {
3543 duration = stream->default_duration * laces;
3545 /* else duration is diff between timecode of this and next block */
3547 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3548 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3549 a ReferenceBlock implies that this is not a keyframe. In either
3550 case, it only makes sense for video streams. */
3551 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3553 invisible_frame = ((flags & 0x08)) &&
3554 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3555 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3558 /* If we're doing a keyframe-only trickmode, only push keyframes on video
3562 segment.flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) {
3563 GST_LOG_OBJECT (demux, "Skipping non-keyframe on stream %d",
3570 for (n = 0; n < laces; n++) {
3573 if (G_UNLIKELY (lace_size[n] > size)) {
3574 GST_WARNING_OBJECT (demux, "Invalid lace size");
3578 /* QoS for video track with an index. the assumption is that
3579 index entries point to keyframes, but if that is not true we
3580 will instad skip until the next keyframe. */
3581 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3582 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3583 stream->index_table && demux->common.segment.rate > 0.0) {
3584 GstMatroskaTrackVideoContext *videocontext =
3585 (GstMatroskaTrackVideoContext *) stream;
3586 GstClockTime earliest_time;
3587 GstClockTime earliest_stream_time;
3589 GST_OBJECT_LOCK (demux);
3590 earliest_time = videocontext->earliest_time;
3591 GST_OBJECT_UNLOCK (demux);
3592 earliest_stream_time =
3593 gst_segment_position_from_running_time (&demux->common.segment,
3594 GST_FORMAT_TIME, earliest_time);
3596 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3597 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3598 lace_time <= earliest_stream_time) {
3599 /* find index entry (keyframe) <= earliest_stream_time */
3600 GstMatroskaIndex *entry =
3601 gst_util_array_binary_search (stream->index_table->data,
3602 stream->index_table->len, sizeof (GstMatroskaIndex),
3603 (GCompareDataFunc) gst_matroska_index_seek_find,
3604 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3606 /* if that entry (keyframe) is after the current the current
3607 buffer, we can skip pushing (and thus decoding) all
3608 buffers until that keyframe. */
3609 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3610 entry->time > lace_time) {
3611 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3612 stream->set_discont = TRUE;
3618 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3619 gst_buffer_get_size (buf) - size, lace_size[n]);
3620 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3623 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3625 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3627 if (invisible_frame)
3628 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3630 if (stream->encodings != NULL && stream->encodings->len > 0)
3631 sub = gst_matroska_decode_buffer (stream, sub);
3634 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3638 if (!stream->dts_only) {
3639 GST_BUFFER_PTS (sub) = lace_time;
3641 GST_BUFFER_DTS (sub) = lace_time;
3642 if (stream->intra_only)
3643 GST_BUFFER_PTS (sub) = lace_time;
3646 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
3648 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3649 GstClockTime last_stop_end;
3651 /* Check if this stream is after segment stop */
3652 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3653 lace_time >= demux->common.segment.stop) {
3654 GST_DEBUG_OBJECT (demux,
3655 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3656 GST_TIME_ARGS (demux->common.segment.stop));
3657 gst_buffer_unref (sub);
3660 if (offset >= stream->to_offset
3661 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3662 && lace_time > demux->to_time)) {
3663 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3665 gst_buffer_unref (sub);
3669 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3670 * that landed us with timestamps not quite intended */
3671 GST_OBJECT_LOCK (demux);
3672 if (demux->max_gap_time &&
3673 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3674 demux->common.segment.rate > 0.0) {
3675 GstClockTimeDiff diff;
3677 /* only send segments with increasing start times,
3678 * otherwise if these go back and forth downstream (sinks) increase
3679 * accumulated time and running_time */
3680 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3681 if (diff > 0 && diff > demux->max_gap_time
3682 && lace_time > demux->common.segment.start
3683 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3684 || lace_time < demux->common.segment.stop)) {
3686 GST_DEBUG_OBJECT (demux,
3687 "Gap of %" G_GINT64_FORMAT " ns detected in"
3688 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3689 "Sending updated SEGMENT events", diff,
3690 stream->index, GST_TIME_ARGS (stream->pos),
3691 GST_TIME_ARGS (lace_time));
3693 event = gst_event_new_gap (demux->last_stop_end, diff);
3694 GST_OBJECT_UNLOCK (demux);
3695 gst_pad_push_event (stream->pad, event);
3696 GST_OBJECT_LOCK (demux);
3700 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3701 || demux->common.segment.position < lace_time) {
3702 demux->common.segment.position = lace_time;
3704 GST_OBJECT_UNLOCK (demux);
3706 last_stop_end = lace_time;
3708 GST_BUFFER_DURATION (sub) = duration / laces;
3709 last_stop_end += GST_BUFFER_DURATION (sub);
3712 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3713 demux->last_stop_end < last_stop_end)
3714 demux->last_stop_end = last_stop_end;
3716 GST_OBJECT_LOCK (demux);
3717 if (demux->common.segment.duration == -1 ||
3718 demux->stream_start_time + demux->common.segment.duration <
3720 demux->common.segment.duration =
3721 last_stop_end - demux->stream_start_time;
3722 GST_OBJECT_UNLOCK (demux);
3723 if (!demux->invalid_duration) {
3724 gst_element_post_message (GST_ELEMENT_CAST (demux),
3725 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3726 demux->invalid_duration = TRUE;
3729 GST_OBJECT_UNLOCK (demux);
3733 stream->pos = lace_time;
3735 gst_matroska_demux_sync_streams (demux);
3737 if (stream->set_discont) {
3738 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3739 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3740 stream->set_discont = FALSE;
3742 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3745 /* reverse playback book-keeping */
3746 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3747 stream->from_time = lace_time;
3748 if (stream->from_offset == -1)
3749 stream->from_offset = offset;
3751 GST_DEBUG_OBJECT (demux,
3752 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3753 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3754 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3755 GST_TIME_ARGS (buffer_timestamp),
3756 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3759 if (demux->common.element_index) {
3760 if (stream->index_writer_id == -1)
3761 gst_index_get_writer_id (demux->common.element_index,
3762 GST_OBJECT (stream->pad), &stream->index_writer_id);
3764 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3765 G_GUINT64_FORMAT " for writer id %d",
3766 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
3767 stream->index_writer_id);
3768 gst_index_add_association (demux->common.element_index,
3769 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3770 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3771 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
3776 /* Postprocess the buffers depending on the codec used */
3777 if (stream->postprocess_frame) {
3778 GST_LOG_OBJECT (demux, "running post process");
3779 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3782 /* At this point, we have a sub-buffer pointing at data within a larger
3783 buffer. This data might not be aligned with anything. If the data is
3784 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3785 for 32 bit samples, etc), or bad things will happen downstream as
3786 elements typically assume minimal alignment.
3787 Therefore, create an aligned copy if necessary. */
3788 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3790 if (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
3791 guint64 start_clip = 0, end_clip = 0;
3793 /* Codec delay is part of the timestamps */
3794 if (GST_BUFFER_PTS_IS_VALID (sub) && stream->codec_delay) {
3795 if (GST_BUFFER_PTS (sub) > stream->codec_delay) {
3796 GST_BUFFER_PTS (sub) -= stream->codec_delay;
3798 GST_BUFFER_PTS (sub) = 0;
3800 gst_util_uint64_scale_round (stream->codec_delay, 48000,
3803 if (GST_BUFFER_DURATION_IS_VALID (sub)) {
3804 if (GST_BUFFER_DURATION (sub) > stream->codec_delay)
3805 GST_BUFFER_DURATION (sub) -= stream->codec_delay;
3807 GST_BUFFER_DURATION (sub) = 0;
3812 if (block_discardpadding) {
3814 gst_util_uint64_scale_round (block_discardpadding, 48000,
3818 if (start_clip || end_clip) {
3819 gst_buffer_add_audio_clipping_meta (sub, GST_FORMAT_DEFAULT,
3820 start_clip, end_clip);
3824 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3825 stream->pos = GST_BUFFER_PTS (sub);
3826 if (GST_BUFFER_DURATION_IS_VALID (sub))
3827 stream->pos += GST_BUFFER_DURATION (sub);
3828 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
3829 stream->pos = GST_BUFFER_DTS (sub);
3830 if (GST_BUFFER_DURATION_IS_VALID (sub))
3831 stream->pos += GST_BUFFER_DURATION (sub);
3834 ret = gst_pad_push (stream->pad, sub);
3836 if (demux->common.segment.rate < 0) {
3837 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3838 /* In reverse playback we can get a GST_FLOW_EOS when
3839 * we are at the end of the segment, so we just need to jump
3840 * back to the previous section. */
3841 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3846 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
3850 size -= lace_size[n];
3851 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3852 lace_time += duration / laces;
3854 lace_time = GST_CLOCK_TIME_NONE;
3860 gst_buffer_unmap (buf, &map);
3861 gst_buffer_unref (buf);
3873 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
3879 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3880 /* non-fatal, try next block(group) */
3886 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3887 /* non-fatal, try next block(group) */
3893 /* return FALSE if block(group) should be skipped (due to a seek) */
3894 static inline gboolean
3895 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3897 if (G_UNLIKELY (demux->seek_block)) {
3898 if (!(--demux->seek_block)) {
3901 GST_LOG_OBJECT (demux, "should skip block due to seek");
3909 static GstFlowReturn
3910 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3914 guint64 seek_pos = (guint64) - 1;
3915 guint32 seek_id = 0;
3918 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3920 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3921 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3925 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3926 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3930 case GST_MATROSKA_ID_SEEKID:
3934 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3937 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3942 case GST_MATROSKA_ID_SEEKPOSITION:
3946 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3949 if (t > G_MAXINT64) {
3950 GST_WARNING_OBJECT (demux,
3951 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3955 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3961 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3967 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3970 if (!seek_id || seek_pos == (guint64) - 1) {
3971 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3972 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3977 case GST_MATROSKA_ID_SEEKHEAD:
3980 case GST_MATROSKA_ID_CUES:
3981 case GST_MATROSKA_ID_TAGS:
3982 case GST_MATROSKA_ID_TRACKS:
3983 case GST_MATROSKA_ID_SEGMENTINFO:
3984 case GST_MATROSKA_ID_ATTACHMENTS:
3985 case GST_MATROSKA_ID_CHAPTERS:
3987 guint64 before_pos, length;
3991 length = gst_matroska_read_common_get_length (&demux->common);
3992 before_pos = demux->common.offset;
3994 if (length == (guint64) - 1) {
3995 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3999 /* check for validity */
4000 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
4001 GST_WARNING_OBJECT (demux,
4002 "SeekHead reference lies outside file!" " (%"
4003 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
4004 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
4009 /* only pick up index location when streaming */
4010 if (demux->streaming) {
4011 if (seek_id == GST_MATROSKA_ID_CUES) {
4012 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
4013 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
4014 demux->index_offset);
4020 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
4023 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4024 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
4028 if (id != seek_id) {
4029 GST_WARNING_OBJECT (demux,
4030 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
4031 seek_id, id, seek_pos + demux->common.ebml_segment_start);
4034 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4039 demux->common.offset = before_pos;
4043 case GST_MATROSKA_ID_CLUSTER:
4045 guint64 pos = seek_pos + demux->common.ebml_segment_start;
4047 GST_LOG_OBJECT (demux, "Cluster position");
4048 if (G_UNLIKELY (!demux->clusters))
4049 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
4050 g_array_append_val (demux->clusters, pos);
4055 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
4058 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4063 static GstFlowReturn
4064 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4066 GstFlowReturn ret = GST_FLOW_OK;
4069 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4071 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4072 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4076 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4077 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4081 case GST_MATROSKA_ID_SEEKENTRY:
4083 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
4084 /* Ignore EOS and errors here */
4085 if (ret != GST_FLOW_OK) {
4086 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4093 ret = gst_matroska_read_common_parse_skip (&demux->common,
4094 ebml, "SeekHead", id);
4099 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4101 /* Sort clusters by position for easier searching */
4102 if (demux->clusters)
4103 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4108 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
4110 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4112 static inline GstFlowReturn
4113 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4115 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4116 /* only a few blocks are expected/allowed to be large,
4117 * and will be recursed into, whereas others will be read and must fit */
4118 if (demux->streaming) {
4119 /* fatal in streaming case, as we can't step over easily */
4120 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4121 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4122 "file might be corrupt.", bytes));
4123 return GST_FLOW_ERROR;
4125 /* indicate higher level to quietly give up */
4126 GST_DEBUG_OBJECT (demux,
4127 "too large block of size %" G_GUINT64_FORMAT, bytes);
4128 return GST_FLOW_ERROR;
4135 /* returns TRUE if we truely are in error state, and should give up */
4136 static inline GstFlowReturn
4137 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4139 if (!demux->streaming && demux->next_cluster_offset > 0) {
4140 /* just repositioning to where next cluster should be and try from there */
4141 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4142 G_GUINT64_FORMAT, demux->next_cluster_offset);
4143 demux->common.offset = demux->next_cluster_offset;
4144 demux->next_cluster_offset = 0;
4150 /* sigh, one last attempt above and beyond call of duty ...;
4151 * search for cluster mark following current pos */
4152 pos = demux->common.offset;
4153 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4154 if ((ret = gst_matroska_demux_search_cluster (demux, &pos)) != GST_FLOW_OK) {
4155 /* did not work, give up */
4158 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4159 /* try that position */
4160 demux->common.offset = pos;
4166 static inline GstFlowReturn
4167 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4169 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4170 demux->common.offset += flush;
4171 if (demux->streaming) {
4174 /* hard to skip large blocks when streaming */
4175 ret = gst_matroska_demux_check_read_size (demux, flush);
4176 if (ret != GST_FLOW_OK)
4178 if (flush <= gst_adapter_available (demux->common.adapter))
4179 gst_adapter_flush (demux->common.adapter, flush);
4181 return GST_FLOW_EOS;
4186 /* initializes @ebml with @bytes from input stream at current offset.
4187 * Returns EOS if insufficient available,
4188 * ERROR if too much was attempted to read. */
4189 static inline GstFlowReturn
4190 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4193 GstBuffer *buffer = NULL;
4194 GstFlowReturn ret = GST_FLOW_OK;
4196 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4198 ret = gst_matroska_demux_check_read_size (demux, bytes);
4199 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4200 if (!demux->streaming) {
4201 /* in pull mode, we can skip */
4202 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4203 ret = GST_FLOW_OVERFLOW;
4205 /* otherwise fatal */
4206 ret = GST_FLOW_ERROR;
4210 if (demux->streaming) {
4211 if (gst_adapter_available (demux->common.adapter) >= bytes)
4212 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4216 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4217 demux->common.offset, bytes, &buffer, NULL);
4218 if (G_LIKELY (buffer)) {
4219 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4220 demux->common.offset);
4221 demux->common.offset += bytes;
4228 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4231 gboolean seekable = FALSE;
4232 gint64 start = -1, stop = -1;
4234 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4235 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4236 GST_DEBUG_OBJECT (demux, "seeking query failed");
4240 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4242 /* try harder to query upstream size if we didn't get it the first time */
4243 if (seekable && stop == -1) {
4244 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4245 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4249 /* if upstream doesn't know the size, it's likely that it's not seekable in
4250 * practice even if it technically may be seekable */
4251 if (seekable && (start != 0 || stop <= start)) {
4252 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4257 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4258 G_GUINT64_FORMAT ")", seekable, start, stop);
4259 demux->seekable = seekable;
4261 gst_query_unref (query);
4264 static GstFlowReturn
4265 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4271 GstFlowReturn ret = GST_FLOW_OK;
4273 GST_WARNING_OBJECT (demux,
4274 "Found Cluster element before Tracks, searching Tracks");
4277 before_pos = demux->common.offset;
4279 /* Search Tracks element */
4281 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4282 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4283 if (ret != GST_FLOW_OK)
4286 if (id != GST_MATROSKA_ID_TRACKS) {
4287 /* we may be skipping large cluster here, so forego size check etc */
4288 /* ... but we can't skip undefined size; force error */
4289 if (length == G_MAXUINT64) {
4290 ret = gst_matroska_demux_check_read_size (demux, length);
4293 demux->common.offset += needed;
4294 demux->common.offset += length;
4299 /* will lead to track parsing ... */
4300 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4305 demux->common.offset = before_pos;
4310 #define GST_READ_CHECK(stmt) \
4312 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4313 if (ret == GST_FLOW_OVERFLOW) { \
4314 ret = GST_FLOW_OK; \
4320 static GstFlowReturn
4321 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4322 guint64 length, guint needed)
4324 GstEbmlRead ebml = { 0, };
4325 GstFlowReturn ret = GST_FLOW_OK;
4328 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4329 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4331 /* if we plan to read and parse this element, we need prefix (id + length)
4332 * and the contents */
4333 /* mind about overflow wrap-around when dealing with undefined size */
4335 if (G_LIKELY (length != G_MAXUINT64))
4338 switch (demux->common.state) {
4339 case GST_MATROSKA_READ_STATE_START:
4341 case GST_EBML_ID_HEADER:
4342 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4343 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4344 if (ret != GST_FLOW_OK)
4346 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4347 gst_matroska_demux_check_seekability (demux);
4350 goto invalid_header;
4354 case GST_MATROSKA_READ_STATE_SEGMENT:
4356 case GST_MATROSKA_ID_SEGMENT:
4357 /* eat segment prefix */
4358 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4359 GST_DEBUG_OBJECT (demux,
4360 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4361 G_GUINT64_FORMAT, demux->common.offset, length);
4362 /* seeks are from the beginning of the segment,
4363 * after the segment ID/length */
4364 demux->common.ebml_segment_start = demux->common.offset;
4366 length = G_MAXUINT64;
4367 demux->common.ebml_segment_length = length;
4368 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4371 GST_WARNING_OBJECT (demux,
4372 "Expected a Segment ID (0x%x), but received 0x%x!",
4373 GST_MATROSKA_ID_SEGMENT, id);
4374 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4378 case GST_MATROSKA_READ_STATE_SCANNING:
4379 if (id != GST_MATROSKA_ID_CLUSTER &&
4380 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4383 case GST_MATROSKA_READ_STATE_HEADER:
4384 case GST_MATROSKA_READ_STATE_DATA:
4385 case GST_MATROSKA_READ_STATE_SEEK:
4387 case GST_MATROSKA_ID_SEGMENTINFO:
4388 if (!demux->common.segmentinfo_parsed) {
4389 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4390 ret = gst_matroska_read_common_parse_info (&demux->common,
4391 GST_ELEMENT_CAST (demux), &ebml);
4392 if (ret == GST_FLOW_OK)
4393 gst_matroska_demux_send_tags (demux);
4395 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4398 case GST_MATROSKA_ID_TRACKS:
4399 if (!demux->tracks_parsed) {
4400 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4401 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4403 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4406 case GST_MATROSKA_ID_CLUSTER:
4407 if (G_UNLIKELY (!demux->tracks_parsed)) {
4408 if (demux->streaming) {
4409 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4410 goto not_streamable;
4412 ret = gst_matroska_demux_find_tracks (demux);
4413 if (!demux->tracks_parsed)
4417 if (G_UNLIKELY (demux->common.state
4418 == GST_MATROSKA_READ_STATE_HEADER)) {
4419 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4420 demux->first_cluster_offset = demux->common.offset;
4421 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4422 gst_element_no_more_pads (GST_ELEMENT (demux));
4423 /* send initial segment - we wait till we know the first
4424 incoming timestamp, so we can properly set the start of
4426 demux->need_segment = TRUE;
4428 demux->cluster_time = GST_CLOCK_TIME_NONE;
4429 demux->cluster_offset = demux->common.offset;
4430 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4431 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4432 " not found in Cluster, trying next Cluster's first block instead",
4434 demux->seek_block = 0;
4436 demux->seek_first = FALSE;
4437 /* record next cluster for recovery */
4438 if (read != G_MAXUINT64)
4439 demux->next_cluster_offset = demux->cluster_offset + read;
4440 /* eat cluster prefix */
4441 gst_matroska_demux_flush (demux, needed);
4443 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4447 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4448 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4450 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4451 demux->cluster_time = num;
4453 if (demux->common.element_index) {
4454 if (demux->common.element_index_writer_id == -1)
4455 gst_index_get_writer_id (demux->common.element_index,
4456 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4457 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4458 G_GUINT64_FORMAT " for writer id %d",
4459 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4460 demux->common.element_index_writer_id);
4461 gst_index_add_association (demux->common.element_index,
4462 demux->common.element_index_writer_id,
4463 GST_ASSOCIATION_FLAG_KEY_UNIT,
4464 GST_FORMAT_TIME, demux->cluster_time,
4465 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4470 case GST_MATROSKA_ID_BLOCKGROUP:
4471 if (!gst_matroska_demux_seek_block (demux))
4473 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4474 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4475 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4476 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4477 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4479 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4481 case GST_MATROSKA_ID_SIMPLEBLOCK:
4482 if (!gst_matroska_demux_seek_block (demux))
4484 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4485 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4486 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4487 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4488 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4490 case GST_MATROSKA_ID_ATTACHMENTS:
4491 if (!demux->common.attachments_parsed) {
4492 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4493 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4494 GST_ELEMENT_CAST (demux), &ebml);
4495 if (ret == GST_FLOW_OK)
4496 gst_matroska_demux_send_tags (demux);
4498 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4501 case GST_MATROSKA_ID_TAGS:
4502 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4503 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4504 GST_ELEMENT_CAST (demux), &ebml);
4505 if (ret == GST_FLOW_OK)
4506 gst_matroska_demux_send_tags (demux);
4508 case GST_MATROSKA_ID_CHAPTERS:
4509 if (!demux->common.chapters_parsed) {
4510 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4512 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4514 if (demux->common.toc) {
4515 gst_matroska_demux_send_event (demux,
4516 gst_event_new_toc (demux->common.toc, FALSE));
4519 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4521 case GST_MATROSKA_ID_SEEKHEAD:
4522 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4523 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4525 case GST_MATROSKA_ID_CUES:
4526 if (demux->common.index_parsed) {
4527 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4530 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4531 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4532 /* only push based; delayed index building */
4533 if (ret == GST_FLOW_OK
4534 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4537 GST_OBJECT_LOCK (demux);
4538 event = demux->seek_event;
4539 demux->seek_event = NULL;
4540 GST_OBJECT_UNLOCK (demux);
4543 /* unlikely to fail, since we managed to seek to this point */
4544 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
4545 gst_event_unref (event);
4548 gst_event_unref (event);
4549 /* resume data handling, main thread clear to seek again */
4550 GST_OBJECT_LOCK (demux);
4551 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4552 GST_OBJECT_UNLOCK (demux);
4555 case GST_MATROSKA_ID_POSITION:
4556 case GST_MATROSKA_ID_PREVSIZE:
4557 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4558 case GST_MATROSKA_ID_SILENTTRACKS:
4559 GST_DEBUG_OBJECT (demux,
4560 "Skipping Cluster subelement 0x%x - ignoring", id);
4564 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4565 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4571 if (ret == GST_FLOW_PARSE)
4575 gst_ebml_read_clear (&ebml);
4581 /* simply exit, maybe not enough data yet */
4582 /* no ebml to clear if read error */
4587 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4588 ("Failed to parse Element 0x%x", id));
4589 ret = GST_FLOW_ERROR;
4594 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4595 ("File layout does not permit streaming"));
4596 ret = GST_FLOW_ERROR;
4601 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4602 ("No Tracks element found"));
4603 ret = GST_FLOW_ERROR;
4608 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4609 ret = GST_FLOW_ERROR;
4614 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4615 ret = GST_FLOW_ERROR;
4621 gst_matroska_demux_loop (GstPad * pad)
4623 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4629 /* If we have to close a segment, send a new segment to do this now */
4630 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4631 if (G_UNLIKELY (demux->new_segment)) {
4632 gst_matroska_demux_send_event (demux, demux->new_segment);
4633 demux->new_segment = NULL;
4637 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4638 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4639 if (ret == GST_FLOW_EOS) {
4641 } else if (ret == GST_FLOW_FLUSHING) {
4643 } else if (ret != GST_FLOW_OK) {
4644 ret = gst_matroska_demux_check_parse_error (demux);
4646 /* Only handle EOS as no error if we're outside the segment already */
4647 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4648 && demux->common.offset >=
4649 demux->common.ebml_segment_start +
4650 demux->common.ebml_segment_length))
4652 else if (ret != GST_FLOW_OK)
4658 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4659 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4662 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4663 if (ret == GST_FLOW_EOS)
4665 if (ret != GST_FLOW_OK)
4668 /* check if we're at the end of a configured segment */
4669 if (G_LIKELY (demux->common.src->len)) {
4672 g_assert (demux->common.num_streams == demux->common.src->len);
4673 for (i = 0; i < demux->common.src->len; i++) {
4674 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4676 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4677 GST_TIME_ARGS (context->pos));
4678 if (context->eos == FALSE)
4682 GST_INFO_OBJECT (demux, "All streams are EOS");
4688 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4689 demux->common.offset >= demux->cached_length)) {
4690 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4691 if (demux->common.offset == demux->cached_length) {
4692 GST_LOG_OBJECT (demux, "Reached end of stream");
4703 if (demux->common.segment.rate < 0.0) {
4704 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4705 if (ret == GST_FLOW_OK)
4712 const gchar *reason = gst_flow_get_name (ret);
4713 gboolean push_eos = FALSE;
4715 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4716 gst_pad_pause_task (demux->common.sinkpad);
4718 if (ret == GST_FLOW_EOS) {
4719 /* perform EOS logic */
4721 /* If we were in the headers, make sure we send no-more-pads.
4722 This will ensure decodebin does not get stuck thinking
4723 the chain is not complete yet, and waiting indefinitely. */
4724 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4725 if (demux->common.src->len == 0) {
4726 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4727 ("No pads created"));
4729 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4730 ("Failed to finish reading headers"));
4732 gst_element_no_more_pads (GST_ELEMENT (demux));
4735 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
4738 /* for segment playback we need to post when (in stream time)
4739 * we stopped, this is either stop (when set) or the duration. */
4740 if ((stop = demux->common.segment.stop) == -1)
4741 stop = demux->last_stop_end;
4743 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
4744 gst_element_post_message (GST_ELEMENT (demux),
4745 gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4747 gst_matroska_demux_send_event (demux,
4748 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
4752 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4753 /* for fatal errors we post an error message */
4754 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4755 ("stream stopped, reason %s", reason));
4759 /* send EOS, and prevent hanging if no streams yet */
4760 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4761 if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
4762 (ret == GST_FLOW_EOS)) {
4763 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4764 (NULL), ("got eos but no streams (yet)"));
4772 * Create and push a flushing seek event upstream
4775 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4781 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4784 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4785 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4786 GST_SEEK_TYPE_NONE, -1);
4787 gst_event_set_seqnum (event, seqnum);
4789 res = gst_pad_push_event (demux->common.sinkpad, event);
4791 /* segment event will update offset */
4795 static GstFlowReturn
4796 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4798 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4800 GstFlowReturn ret = GST_FLOW_OK;
4805 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4806 GST_DEBUG_OBJECT (demux, "got DISCONT");
4807 gst_adapter_clear (demux->common.adapter);
4808 GST_OBJECT_LOCK (demux);
4809 gst_matroska_read_common_reset_streams (&demux->common,
4810 GST_CLOCK_TIME_NONE, FALSE);
4811 GST_OBJECT_UNLOCK (demux);
4814 gst_adapter_push (demux->common.adapter, buffer);
4818 available = gst_adapter_available (demux->common.adapter);
4820 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4821 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4822 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4823 if (demux->common.ebml_segment_length != G_MAXUINT64
4824 && demux->common.offset >=
4825 demux->common.ebml_segment_start + demux->common.ebml_segment_length)
4830 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4831 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4832 demux->common.offset, id, length, needed, available);
4834 if (needed > available)
4837 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4838 if (ret == GST_FLOW_EOS) {
4839 /* need more data */
4841 } else if (ret != GST_FLOW_OK) {
4848 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4851 gboolean res = TRUE;
4852 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4854 GST_DEBUG_OBJECT (demux,
4855 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4857 switch (GST_EVENT_TYPE (event)) {
4858 case GST_EVENT_SEGMENT:
4860 const GstSegment *segment;
4862 /* some debug output */
4863 gst_event_parse_segment (event, &segment);
4864 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4865 GST_DEBUG_OBJECT (demux,
4866 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4869 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4870 GST_DEBUG_OBJECT (demux, "still starting");
4874 /* we only expect a BYTE segment, e.g. following a seek */
4875 if (segment->format != GST_FORMAT_BYTES) {
4876 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4880 GST_DEBUG_OBJECT (demux, "clearing segment state");
4881 GST_OBJECT_LOCK (demux);
4882 /* clear current segment leftover */
4883 gst_adapter_clear (demux->common.adapter);
4884 /* and some streaming setup */
4885 demux->common.offset = segment->start;
4886 /* accumulate base based on current position */
4887 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4888 demux->common.segment.base +=
4889 (MAX (demux->common.segment.position, demux->stream_start_time)
4890 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4891 /* do not know where we are;
4892 * need to come across a cluster and generate segment */
4893 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4894 demux->cluster_time = GST_CLOCK_TIME_NONE;
4895 demux->cluster_offset = 0;
4896 demux->need_segment = TRUE;
4897 demux->segment_seqnum = gst_event_get_seqnum (event);
4898 /* but keep some of the upstream segment */
4899 demux->common.segment.rate = segment->rate;
4900 /* also check if need to keep some of the requested seek position */
4901 if (demux->seek_offset == segment->start) {
4902 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4903 demux->common.segment.position = demux->requested_seek_time;
4905 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4907 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4908 demux->seek_offset = -1;
4909 GST_OBJECT_UNLOCK (demux);
4911 /* chain will send initial segment after pads have been added,
4912 * or otherwise come up with one */
4913 GST_DEBUG_OBJECT (demux, "eating event");
4914 gst_event_unref (event);
4920 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4921 gst_event_unref (event);
4922 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4923 (NULL), ("got eos and didn't receive a complete header object"));
4924 } else if (demux->common.num_streams == 0) {
4925 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4926 (NULL), ("got eos but no streams (yet)"));
4928 gst_matroska_demux_send_event (demux, event);
4932 case GST_EVENT_FLUSH_STOP:
4936 gst_adapter_clear (demux->common.adapter);
4937 GST_OBJECT_LOCK (demux);
4938 gst_matroska_read_common_reset_streams (&demux->common,
4939 GST_CLOCK_TIME_NONE, TRUE);
4940 gst_flow_combiner_reset (demux->flowcombiner);
4941 dur = demux->common.segment.duration;
4942 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4943 demux->common.segment.duration = dur;
4944 demux->cluster_time = GST_CLOCK_TIME_NONE;
4945 demux->cluster_offset = 0;
4946 GST_OBJECT_UNLOCK (demux);
4950 res = gst_pad_event_default (pad, parent, event);
4958 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4960 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4962 gboolean pull_mode = FALSE;
4964 query = gst_query_new_scheduling ();
4966 if (gst_pad_peer_query (sinkpad, query))
4967 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4968 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4970 gst_query_unref (query);
4973 GST_DEBUG ("going to pull mode");
4974 demux->streaming = FALSE;
4975 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4977 GST_DEBUG ("going to push (streaming) mode");
4978 demux->streaming = TRUE;
4979 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4984 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4985 GstPadMode mode, gboolean active)
4988 case GST_PAD_MODE_PULL:
4990 /* if we have a scheduler we can start the task */
4991 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
4994 gst_pad_stop_task (sinkpad);
4997 case GST_PAD_MODE_PUSH:
5005 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
5006 videocontext, const gchar * codec_id, guint8 * data, guint size,
5007 gchar ** codec_name, guint32 * riff_fourcc)
5009 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
5010 GstCaps *caps = NULL;
5012 g_assert (videocontext != NULL);
5013 g_assert (codec_name != NULL);
5018 /* TODO: check if we have all codec types from matroska-ids.h
5019 * check if we have to do more special things with codec_private
5022 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
5023 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
5026 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
5027 gst_riff_strf_vids *vids = NULL;
5030 GstBuffer *buf = NULL;
5032 vids = (gst_riff_strf_vids *) data;
5034 /* assure size is big enough */
5036 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
5039 if (size < sizeof (gst_riff_strf_vids)) {
5040 vids = g_new (gst_riff_strf_vids, 1);
5041 memcpy (vids, data, size);
5044 context->dts_only = TRUE; /* VFW files only store DTS */
5046 /* little-endian -> byte-order */
5047 vids->size = GUINT32_FROM_LE (vids->size);
5048 vids->width = GUINT32_FROM_LE (vids->width);
5049 vids->height = GUINT32_FROM_LE (vids->height);
5050 vids->planes = GUINT16_FROM_LE (vids->planes);
5051 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
5052 vids->compression = GUINT32_FROM_LE (vids->compression);
5053 vids->image_size = GUINT32_FROM_LE (vids->image_size);
5054 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
5055 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
5056 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
5057 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
5059 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
5060 gsize offset = sizeof (gst_riff_strf_vids);
5063 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
5064 size - offset), size - offset);
5068 *riff_fourcc = vids->compression;
5070 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
5071 buf, NULL, codec_name);
5074 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
5075 GST_FOURCC_ARGS (vids->compression));
5077 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
5078 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
5079 "video/x-compressed-yuv");
5080 context->intra_only =
5081 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
5085 gst_buffer_unref (buf);
5087 if (vids != (gst_riff_strf_vids *) data)
5090 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
5092 GstVideoFormat format;
5094 gst_video_info_init (&info);
5095 switch (videocontext->fourcc) {
5096 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5097 format = GST_VIDEO_FORMAT_I420;
5099 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5100 format = GST_VIDEO_FORMAT_YUY2;
5102 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5103 format = GST_VIDEO_FORMAT_YV12;
5105 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5106 format = GST_VIDEO_FORMAT_UYVY;
5108 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5109 format = GST_VIDEO_FORMAT_AYUV;
5111 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
5112 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
5113 format = GST_VIDEO_FORMAT_GRAY8;
5115 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
5116 format = GST_VIDEO_FORMAT_RGB;
5118 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
5119 format = GST_VIDEO_FORMAT_BGR;
5122 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5123 GST_FOURCC_ARGS (videocontext->fourcc));
5127 context->intra_only = TRUE;
5129 gst_video_info_set_format (&info, format, videocontext->pixel_width,
5130 videocontext->pixel_height);
5131 caps = gst_video_info_to_caps (&info);
5132 *codec_name = gst_pb_utils_get_codec_description (caps);
5133 context->alignment = 32;
5134 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5135 caps = gst_caps_new_simple ("video/x-divx",
5136 "divxversion", G_TYPE_INT, 4, NULL);
5137 *codec_name = g_strdup ("MPEG-4 simple profile");
5138 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5139 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5140 caps = gst_caps_new_simple ("video/mpeg",
5141 "mpegversion", G_TYPE_INT, 4,
5142 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5146 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5147 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5148 gst_buffer_unref (priv);
5150 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
5152 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5153 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5155 *codec_name = g_strdup ("MPEG-4 advanced profile");
5156 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5158 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5159 "divxversion", G_TYPE_INT, 3, NULL),
5160 gst_structure_new ("video/x-msmpeg",
5161 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5163 caps = gst_caps_new_simple ("video/x-msmpeg",
5164 "msmpegversion", G_TYPE_INT, 43, NULL);
5165 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5166 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5167 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5170 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5175 caps = gst_caps_new_simple ("video/mpeg",
5176 "systemstream", G_TYPE_BOOLEAN, FALSE,
5177 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5178 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5179 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5180 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5181 caps = gst_caps_new_empty_simple ("image/jpeg");
5182 *codec_name = g_strdup ("Motion-JPEG");
5183 context->intra_only = TRUE;
5184 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5185 caps = gst_caps_new_empty_simple ("video/x-h264");
5189 /* First byte is the version, second is the profile indication, and third
5190 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5191 * level indication. */
5192 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5195 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5196 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5197 gst_buffer_unref (priv);
5199 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5200 "alignment", G_TYPE_STRING, "au", NULL);
5202 GST_WARNING ("No codec data found, assuming output is byte-stream");
5203 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5206 *codec_name = g_strdup ("H264");
5207 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
5208 caps = gst_caps_new_empty_simple ("video/x-h265");
5212 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
5215 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5216 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5217 gst_buffer_unref (priv);
5219 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
5220 "alignment", G_TYPE_STRING, "au", NULL);
5222 GST_WARNING ("No codec data found, assuming output is byte-stream");
5223 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5226 *codec_name = g_strdup ("HEVC");
5227 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5228 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5229 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5230 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5231 gint rmversion = -1;
5233 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5235 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5237 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5239 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5242 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5243 "rmversion", G_TYPE_INT, rmversion, NULL);
5244 GST_DEBUG ("data:%p, size:0x%x", data, size);
5245 /* We need to extract the extradata ! */
5246 if (data && (size >= 0x22)) {
5251 subformat = GST_READ_UINT32_BE (data + 0x1a);
5252 rformat = GST_READ_UINT32_BE (data + 0x1e);
5255 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5257 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5258 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5259 gst_buffer_unref (priv);
5262 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5263 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5264 caps = gst_caps_new_empty_simple ("video/x-theora");
5265 context->stream_headers =
5266 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5267 context->codec_priv_size);
5268 /* FIXME: mark stream as broken and skip if there are no stream headers */
5269 context->send_stream_headers = TRUE;
5270 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5271 caps = gst_caps_new_empty_simple ("video/x-dirac");
5272 *codec_name = g_strdup_printf ("Dirac");
5273 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5274 caps = gst_caps_new_empty_simple ("video/x-vp8");
5275 *codec_name = g_strdup_printf ("On2 VP8");
5276 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5277 caps = gst_caps_new_empty_simple ("video/x-vp9");
5278 *codec_name = g_strdup_printf ("On2 VP9");
5279 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
5281 const gchar *variant, *variant_descr = "";
5283 /* Expect a fourcc in the codec private data */
5284 if (!data || size < 4) {
5285 GST_WARNING ("No or too small PRORESS fourcc (%d bytes)", size);
5289 fourcc = GST_STR_FOURCC (data);
5291 case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
5292 variant_descr = " 4:2:2 LT";
5295 case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
5297 variant_descr = " 4:2:2 HQ";
5299 case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
5301 variant_descr = " 4:4:4:4";
5303 case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
5305 variant_descr = " 4:2:2 Proxy";
5307 case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
5309 variant = "standard";
5310 variant_descr = " 4:2:2 SD";
5314 GST_LOG ("Prores video, codec fourcc %" GST_FOURCC_FORMAT,
5315 GST_FOURCC_ARGS (fourcc));
5317 caps = gst_caps_new_simple ("video/x-prores",
5318 "format", G_TYPE_STRING, variant, NULL);
5319 *codec_name = g_strdup_printf ("Apple ProRes%s", variant_descr);
5320 context->postprocess_frame = gst_matroska_demux_add_prores_header;
5322 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5328 GstStructure *structure;
5330 for (i = 0; i < gst_caps_get_size (caps); i++) {
5331 structure = gst_caps_get_structure (caps, i);
5333 /* FIXME: use the real unit here! */
5334 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5335 videocontext->pixel_width,
5336 videocontext->pixel_height,
5337 videocontext->display_width, videocontext->display_height);
5339 /* pixel width and height are the w and h of the video in pixels */
5340 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5341 gint w = videocontext->pixel_width;
5342 gint h = videocontext->pixel_height;
5344 gst_structure_set (structure,
5345 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5348 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5351 if (videocontext->display_width <= 0)
5352 videocontext->display_width = videocontext->pixel_width;
5353 if (videocontext->display_height <= 0)
5354 videocontext->display_height = videocontext->pixel_height;
5356 /* calculate the pixel aspect ratio using the display and pixel w/h */
5357 n = videocontext->display_width * videocontext->pixel_height;
5358 d = videocontext->display_height * videocontext->pixel_width;
5359 GST_DEBUG ("setting PAR to %d/%d", n, d);
5360 gst_structure_set (structure, "pixel-aspect-ratio",
5362 videocontext->display_width * videocontext->pixel_height,
5363 videocontext->display_height * videocontext->pixel_width, NULL);
5366 if (videocontext->default_fps > 0.0) {
5369 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5371 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5373 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5375 } else if (context->default_duration > 0) {
5378 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5380 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5381 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5383 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5384 fps_n, fps_d, NULL);
5386 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5390 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5391 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5394 if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
5395 if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
5396 videocontext->pixel_width, videocontext->pixel_height,
5397 videocontext->display_width * videocontext->pixel_height,
5398 videocontext->display_height * videocontext->pixel_width)) {
5399 videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
5401 gst_caps_set_simple (caps,
5402 "multiview-mode", G_TYPE_STRING,
5403 gst_video_multiview_mode_to_caps_string
5404 (videocontext->multiview_mode), "multiview-flags",
5405 GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
5406 GST_FLAG_SET_MASK_EXACT, NULL);
5409 caps = gst_caps_simplify (caps);
5416 * Some AAC specific code... *sigh*
5417 * FIXME: maybe we should use '15' and code the sample rate explicitly
5418 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5422 aac_rate_idx (gint rate)
5426 else if (75132 <= rate)
5428 else if (55426 <= rate)
5430 else if (46009 <= rate)
5432 else if (37566 <= rate)
5434 else if (27713 <= rate)
5436 else if (23004 <= rate)
5438 else if (18783 <= rate)
5440 else if (13856 <= rate)
5442 else if (11502 <= rate)
5444 else if (9391 <= rate)
5451 aac_profile_idx (const gchar * codec_id)
5455 if (strlen (codec_id) <= 12)
5457 else if (!strncmp (&codec_id[12], "MAIN", 4))
5459 else if (!strncmp (&codec_id[12], "LC", 2))
5461 else if (!strncmp (&codec_id[12], "SSR", 3))
5470 round_up_pow2 (guint n)
5481 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5484 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5485 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5486 gchar ** codec_name, guint16 * riff_audio_fmt)
5488 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5489 GstCaps *caps = NULL;
5491 g_assert (audiocontext != NULL);
5492 g_assert (codec_name != NULL);
5495 *riff_audio_fmt = 0;
5497 /* TODO: check if we have all codec types from matroska-ids.h
5498 * check if we have to do more special things with codec_private
5499 * check if we need bitdepth in different places too
5500 * implement channel position magic
5502 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5503 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5504 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5505 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5508 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5509 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5510 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5513 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5515 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5520 caps = gst_caps_new_simple ("audio/mpeg",
5521 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5522 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5523 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5524 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5527 GstAudioFormat format;
5529 sign = (audiocontext->bitdepth != 8);
5530 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5531 endianness = G_BIG_ENDIAN;
5533 endianness = G_LITTLE_ENDIAN;
5535 format = gst_audio_format_build_integer (sign, endianness,
5536 audiocontext->bitdepth, audiocontext->bitdepth);
5538 /* FIXME: Channel mask and reordering */
5539 caps = gst_caps_new_simple ("audio/x-raw",
5540 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5541 "layout", G_TYPE_STRING, "interleaved",
5542 "channel-mask", GST_TYPE_BITMASK,
5543 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5545 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5546 audiocontext->bitdepth);
5547 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5548 context->alignment = round_up_pow2 (context->alignment);
5549 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5550 const gchar *format;
5551 if (audiocontext->bitdepth == 32)
5555 /* FIXME: Channel mask and reordering */
5556 caps = gst_caps_new_simple ("audio/x-raw",
5557 "format", G_TYPE_STRING, format,
5558 "layout", G_TYPE_STRING, "interleaved",
5559 "channel-mask", GST_TYPE_BITMASK,
5560 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5561 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5562 audiocontext->bitdepth);
5563 context->alignment = audiocontext->bitdepth / 8;
5564 context->alignment = round_up_pow2 (context->alignment);
5565 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5566 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5567 caps = gst_caps_new_simple ("audio/x-ac3",
5568 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5569 *codec_name = g_strdup ("AC-3 audio");
5570 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5571 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5572 caps = gst_caps_new_simple ("audio/x-eac3",
5573 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5574 *codec_name = g_strdup ("E-AC-3 audio");
5575 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5576 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5577 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5578 *codec_name = g_strdup ("Dolby TrueHD");
5579 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5580 caps = gst_caps_new_empty_simple ("audio/x-dts");
5581 *codec_name = g_strdup ("DTS audio");
5582 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5583 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5584 context->stream_headers =
5585 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5586 context->codec_priv_size);
5587 /* FIXME: mark stream as broken and skip if there are no stream headers */
5588 context->send_stream_headers = TRUE;
5589 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5590 caps = gst_caps_new_empty_simple ("audio/x-flac");
5591 context->stream_headers =
5592 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5593 context->codec_priv_size);
5594 /* FIXME: mark stream as broken and skip if there are no stream headers */
5595 context->send_stream_headers = TRUE;
5596 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5597 caps = gst_caps_new_empty_simple ("audio/x-speex");
5598 context->stream_headers =
5599 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5600 context->codec_priv_size);
5601 /* FIXME: mark stream as broken and skip if there are no stream headers */
5602 context->send_stream_headers = TRUE;
5603 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5606 if (context->codec_priv_size >= 19) {
5607 if (audiocontext->samplerate)
5608 GST_WRITE_UINT32_LE ((guint8 *) context->codec_priv + 12,
5609 audiocontext->samplerate);
5610 if (context->codec_delay) {
5612 gst_util_uint64_scale_round (context->codec_delay, 48000,
5614 GST_WRITE_UINT16_LE ((guint8 *) context->codec_priv + 10, delay);
5618 gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5619 context->codec_priv_size), context->codec_priv_size);
5620 caps = gst_codec_utils_opus_create_caps_from_header (tmp, NULL);
5621 gst_buffer_unref (tmp);
5622 *codec_name = g_strdup ("Opus");
5623 } else if (context->codec_priv_size == 0) {
5624 GST_WARNING ("No Opus codec data found, trying to create one");
5625 if (audiocontext->channels <= 2) {
5626 guint8 streams, coupled, channels;
5630 audiocontext->samplerate == 0 ? 48000 : audiocontext->samplerate;
5631 channels = audiocontext->channels == 0 ? 2 : audiocontext->channels;
5632 if (channels == 1) {
5641 gst_codec_utils_opus_create_caps (samplerate, channels, 0, streams,
5644 *codec_name = g_strdup ("Opus");
5646 GST_WARNING ("Failed to create Opus caps from audio context");
5649 GST_WARNING ("No Opus codec data, and not enough info to create one");
5652 GST_WARNING ("Invalid Opus codec data size (got %" G_GSIZE_FORMAT
5653 ", expected 19)", context->codec_priv_size);
5655 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5656 gst_riff_strf_auds auds;
5658 if (data && size >= 18) {
5659 GstBuffer *codec_data = NULL;
5661 /* little-endian -> byte-order */
5662 auds.format = GST_READ_UINT16_LE (data);
5663 auds.channels = GST_READ_UINT16_LE (data + 2);
5664 auds.rate = GST_READ_UINT32_LE (data + 4);
5665 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5666 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5667 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5669 /* 18 is the waveformatex size */
5671 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5672 data + 18, size - 18, 0, size - 18, NULL, NULL);
5676 *riff_audio_fmt = auds.format;
5678 /* FIXME: Handle reorder map */
5679 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5680 codec_data, codec_name, NULL);
5682 gst_buffer_unref (codec_data);
5685 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5688 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5690 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5691 GstBuffer *priv = NULL;
5693 gint rate_idx, profile;
5694 guint8 *data = NULL;
5696 /* unspecified AAC profile with opaque private codec data */
5697 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5698 if (context->codec_priv_size >= 2) {
5699 guint obj_type, freq_index, explicit_freq_bytes = 0;
5701 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5703 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5704 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5705 if (freq_index == 15)
5706 explicit_freq_bytes = 3;
5707 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5708 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5709 context->codec_priv_size), context->codec_priv_size);
5710 /* assume SBR if samplerate <= 24kHz */
5711 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5712 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5713 audiocontext->samplerate *= 2;
5716 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5717 /* this is pretty broken;
5718 * maybe we need to make up some default private,
5719 * or maybe ADTS data got dumped in.
5720 * Let's set up some private data now, and check actual data later */
5721 /* just try this and see what happens ... */
5722 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5723 context->postprocess_frame = gst_matroska_demux_check_aac;
5727 /* make up decoder-specific data if it is not supplied */
5731 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5732 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5734 rate_idx = aac_rate_idx (audiocontext->samplerate);
5735 profile = aac_profile_idx (codec_id);
5737 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5738 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5740 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5741 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5743 gst_buffer_unmap (priv, &map);
5744 gst_buffer_set_size (priv, 2);
5745 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5746 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5749 if (g_strrstr (codec_id, "SBR")) {
5750 /* HE-AAC (aka SBR AAC) */
5751 audiocontext->samplerate *= 2;
5752 rate_idx = aac_rate_idx (audiocontext->samplerate);
5753 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5754 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5755 data[4] = (1 << 7) | (rate_idx << 3);
5756 gst_buffer_unmap (priv, &map);
5758 gst_buffer_unmap (priv, &map);
5759 gst_buffer_set_size (priv, 2);
5762 gst_buffer_unmap (priv, &map);
5763 gst_buffer_unref (priv);
5765 GST_ERROR ("Unknown AAC profile and no codec private data");
5770 caps = gst_caps_new_simple ("audio/mpeg",
5771 "mpegversion", G_TYPE_INT, mpegversion,
5772 "framed", G_TYPE_BOOLEAN, TRUE,
5773 "stream-format", G_TYPE_STRING, "raw", NULL);
5774 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5775 if (context->codec_priv && context->codec_priv_size > 0)
5776 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5777 context->codec_priv, context->codec_priv_size);
5778 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5779 gst_buffer_unref (priv);
5781 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5782 caps = gst_caps_new_simple ("audio/x-tta",
5783 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5784 *codec_name = g_strdup ("TTA audio");
5785 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5786 caps = gst_caps_new_simple ("audio/x-wavpack",
5787 "width", G_TYPE_INT, audiocontext->bitdepth,
5788 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5789 *codec_name = g_strdup ("Wavpack audio");
5790 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5791 audiocontext->wvpk_block_index = 0;
5792 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5793 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5794 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5795 gint raversion = -1;
5797 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5799 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5804 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5805 "raversion", G_TYPE_INT, raversion, NULL);
5806 /* Extract extra information from caps, mapping varies based on codec */
5807 if (data && (size >= 0x50)) {
5814 guint extra_data_size;
5816 GST_ERROR ("real audio raversion:%d", raversion);
5817 if (raversion == 8) {
5819 flavor = GST_READ_UINT16_BE (data + 22);
5820 packet_size = GST_READ_UINT32_BE (data + 24);
5821 height = GST_READ_UINT16_BE (data + 40);
5822 leaf_size = GST_READ_UINT16_BE (data + 44);
5823 sample_width = GST_READ_UINT16_BE (data + 58);
5824 extra_data_size = GST_READ_UINT32_BE (data + 74);
5827 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5828 flavor, packet_size, height, leaf_size, sample_width,
5830 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5831 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5832 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5834 if ((size - 78) >= extra_data_size) {
5835 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5837 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5838 gst_buffer_unref (priv);
5843 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5844 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5845 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5846 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5847 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5848 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5849 *codec_name = g_strdup ("Real Audio Lossless");
5850 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5851 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5852 *codec_name = g_strdup ("Sony ATRAC3");
5854 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5859 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5862 for (i = 0; i < gst_caps_get_size (caps); i++) {
5863 gst_structure_set (gst_caps_get_structure (caps, i),
5864 "channels", G_TYPE_INT, audiocontext->channels,
5865 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5869 caps = gst_caps_simplify (caps);
5876 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5877 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5879 GstCaps *caps = NULL;
5880 GstMatroskaTrackContext *context =
5881 (GstMatroskaTrackContext *) subtitlecontext;
5883 /* for backwards compatibility */
5884 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5885 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5886 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5887 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5888 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5889 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5890 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5891 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5893 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5894 * Check if we have to do something with codec_private */
5895 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5896 /* well, plain text simply does not have a lot of markup ... */
5897 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5898 "pango-markup", NULL);
5899 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5900 subtitlecontext->check_markup = TRUE;
5901 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5902 caps = gst_caps_new_empty_simple ("application/x-ssa");
5903 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5904 subtitlecontext->check_markup = FALSE;
5905 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5906 caps = gst_caps_new_empty_simple ("application/x-ass");
5907 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5908 subtitlecontext->check_markup = FALSE;
5909 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5910 caps = gst_caps_new_empty_simple ("application/x-usf");
5911 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5912 subtitlecontext->check_markup = FALSE;
5913 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5914 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5915 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5916 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5917 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5918 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5919 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5920 context->stream_headers =
5921 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5922 context->codec_priv_size);
5923 /* FIXME: mark stream as broken and skip if there are no stream headers */
5924 context->send_stream_headers = TRUE;
5926 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5927 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5930 if (data != NULL && size > 0) {
5933 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5934 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5935 gst_buffer_unref (buf);
5943 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5945 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5947 GST_OBJECT_LOCK (demux);
5948 if (demux->common.element_index)
5949 gst_object_unref (demux->common.element_index);
5950 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5951 GST_OBJECT_UNLOCK (demux);
5952 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5953 demux->common.element_index);
5957 gst_matroska_demux_get_index (GstElement * element)
5959 GstIndex *result = NULL;
5960 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5962 GST_OBJECT_LOCK (demux);
5963 if (demux->common.element_index)
5964 result = gst_object_ref (demux->common.element_index);
5965 GST_OBJECT_UNLOCK (demux);
5967 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5973 static GstStateChangeReturn
5974 gst_matroska_demux_change_state (GstElement * element,
5975 GstStateChange transition)
5977 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5978 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5980 /* handle upwards state changes here */
5981 switch (transition) {
5986 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5988 /* handle downwards state changes */
5989 switch (transition) {
5990 case GST_STATE_CHANGE_PAUSED_TO_READY:
5991 gst_matroska_demux_reset (GST_ELEMENT (demux));
6001 gst_matroska_demux_set_property (GObject * object,
6002 guint prop_id, const GValue * value, GParamSpec * pspec)
6004 GstMatroskaDemux *demux;
6006 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6007 demux = GST_MATROSKA_DEMUX (object);
6010 case PROP_MAX_GAP_TIME:
6011 GST_OBJECT_LOCK (demux);
6012 demux->max_gap_time = g_value_get_uint64 (value);
6013 GST_OBJECT_UNLOCK (demux);
6016 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6022 gst_matroska_demux_get_property (GObject * object,
6023 guint prop_id, GValue * value, GParamSpec * pspec)
6025 GstMatroskaDemux *demux;
6027 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6028 demux = GST_MATROSKA_DEMUX (object);
6031 case PROP_MAX_GAP_TIME:
6032 GST_OBJECT_LOCK (demux);
6033 g_value_set_uint64 (value, demux->max_gap_time);
6034 GST_OBJECT_UNLOCK (demux);
6037 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6043 gst_matroska_demux_plugin_init (GstPlugin * plugin)
6047 /* parser helper separate debug */
6048 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
6049 0, "EBML stream helper class");
6051 /* create an elementfactory for the matroska_demux element */
6052 if (!gst_element_register (plugin, "matroskademux",
6053 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))