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 demux->segment_seqnum = seqnum;
2231 GST_OBJECT_UNLOCK (demux);
2233 /* restart our task since it might have been stopped when we did the
2235 gst_pad_start_task (demux->common.sinkpad,
2236 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2238 /* streaming can continue now */
2240 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2248 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2250 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2256 * Handle whether we can perform the seek event or if we have to let the chain
2257 * function handle seeks to build the seek indexes first.
2260 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2264 GstSeekType cur_type, stop_type;
2269 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2274 /* we can only seek on time */
2275 if (format != GST_FORMAT_TIME) {
2276 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2280 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2281 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2285 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2286 GST_DEBUG_OBJECT (demux,
2287 "Non-flushing seek not supported in streaming mode");
2291 if (flags & GST_SEEK_FLAG_SEGMENT) {
2292 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2296 /* check for having parsed index already */
2297 if (!demux->common.index_parsed) {
2298 gboolean building_index;
2301 if (!demux->index_offset) {
2302 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2306 GST_OBJECT_LOCK (demux);
2307 /* handle the seek event in the chain function */
2308 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2309 /* no more seek can be issued until state reset to _DATA */
2311 /* copy the event */
2312 if (demux->seek_event)
2313 gst_event_unref (demux->seek_event);
2314 demux->seek_event = gst_event_ref (event);
2316 /* set the building_index flag so that only one thread can setup the
2317 * structures for index seeking. */
2318 building_index = demux->building_index;
2319 if (!building_index) {
2320 demux->building_index = TRUE;
2321 offset = demux->index_offset;
2323 GST_OBJECT_UNLOCK (demux);
2325 if (!building_index) {
2326 /* seek to the first subindex or legacy index */
2327 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2328 return perform_seek_to_offset (demux, rate, offset,
2329 gst_event_get_seqnum (event));
2332 /* well, we are handling it already */
2336 /* delegate to tweaked regular seek */
2337 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2341 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2344 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2345 gboolean res = TRUE;
2347 switch (GST_EVENT_TYPE (event)) {
2348 case GST_EVENT_SEEK:
2349 /* no seeking until we are (safely) ready */
2350 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2351 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2352 gst_event_unref (event);
2355 if (!demux->streaming)
2356 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2358 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2359 gst_event_unref (event);
2364 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2365 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2366 GstMatroskaTrackVideoContext *videocontext =
2367 (GstMatroskaTrackVideoContext *) context;
2369 GstClockTimeDiff diff;
2370 GstClockTime timestamp;
2372 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2374 GST_OBJECT_LOCK (demux);
2375 videocontext->earliest_time = timestamp + diff;
2376 GST_OBJECT_UNLOCK (demux);
2379 gst_event_unref (event);
2383 case GST_EVENT_TOC_SELECT:
2386 GstTocEntry *entry = NULL;
2387 GstEvent *seek_event;
2390 if (!demux->common.toc) {
2391 GST_DEBUG_OBJECT (demux, "no TOC to select");
2394 gst_event_parse_toc_select (event, &uid);
2396 GST_OBJECT_LOCK (demux);
2397 entry = gst_toc_find_entry (demux->common.toc, uid);
2398 if (entry == NULL) {
2399 GST_OBJECT_UNLOCK (demux);
2400 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2403 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2404 GST_OBJECT_UNLOCK (demux);
2405 seek_event = gst_event_new_seek (1.0,
2407 GST_SEEK_FLAG_FLUSH,
2408 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2409 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2410 gst_event_unref (seek_event);
2414 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2418 gst_event_unref (event);
2422 /* events we don't need to handle */
2423 case GST_EVENT_NAVIGATION:
2424 gst_event_unref (event);
2428 case GST_EVENT_LATENCY:
2430 res = gst_pad_push_event (demux->common.sinkpad, event);
2437 static GstFlowReturn
2438 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2440 GstFlowReturn ret = GST_FLOW_EOS;
2441 gboolean done = TRUE;
2444 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2445 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2448 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2450 if (!demux->seek_entry) {
2451 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2455 for (i = 0; i < demux->common.src->len; i++) {
2456 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2458 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2459 ", stream %d at %" GST_TIME_FORMAT,
2460 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2461 GST_TIME_ARGS (stream->from_time));
2462 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2463 if (stream->from_time > demux->common.segment.start) {
2464 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2468 /* nothing pushed for this stream;
2469 * likely seek entry did not start at keyframe, so all was skipped.
2470 * So we need an earlier entry */
2476 GstMatroskaIndex *entry;
2478 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2479 --demux->seek_entry);
2480 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2490 static GstFlowReturn
2491 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2493 GstFlowReturn ret = GST_FLOW_OK;
2496 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2498 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2499 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2503 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2504 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2508 /* one track within the "all-tracks" header */
2509 case GST_MATROSKA_ID_TRACKENTRY:
2510 ret = gst_matroska_demux_add_stream (demux, ebml);
2514 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2519 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2521 demux->tracks_parsed = TRUE;
2527 * Read signed/unsigned "EBML" numbers.
2528 * Return: number of bytes processed.
2532 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2534 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2542 while (read <= 8 && !(total & len_mask)) {
2549 if ((total &= (len_mask - 1)) == len_mask - 1)
2554 if (data[n] == 0xff)
2556 total = (total << 8) | data[n];
2560 if (read == num_ffs && total != 0)
2569 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2574 /* read as unsigned number first */
2575 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2579 if (unum == G_MAXUINT64)
2582 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2588 * Mostly used for subtitles. We add void filler data for each
2589 * lagging stream to make sure we don't deadlock.
2593 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2595 GstClockTime gap_threshold;
2598 GST_OBJECT_LOCK (demux);
2600 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2601 GST_TIME_ARGS (demux->common.segment.position));
2603 g_assert (demux->common.num_streams == demux->common.src->len);
2604 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2605 GstMatroskaTrackContext *context;
2607 context = g_ptr_array_index (demux->common.src, stream_nr);
2609 GST_LOG_OBJECT (demux,
2610 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2611 GST_TIME_ARGS (context->pos));
2613 /* Only send gap events on non-subtitle streams if lagging way behind.
2614 * The 0.5 second threshold for subtitle streams is also quite random. */
2615 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
2616 gap_threshold = GST_SECOND / 2;
2618 gap_threshold = 3 * GST_SECOND;
2620 /* Lag need only be considered if we have advanced into requested segment */
2621 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2622 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2623 demux->common.segment.position > demux->common.segment.start &&
2624 context->pos + gap_threshold < demux->common.segment.position) {
2627 guint64 start = context->pos;
2628 guint64 stop = demux->common.segment.position - gap_threshold;
2630 GST_DEBUG_OBJECT (demux,
2631 "Synchronizing stream %d with other by advancing time from %"
2632 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2633 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2635 context->pos = stop;
2637 event = gst_event_new_gap (start, stop - start);
2638 GST_OBJECT_UNLOCK (demux);
2639 gst_pad_push_event (context->pad, event);
2640 GST_OBJECT_LOCK (demux);
2644 GST_OBJECT_UNLOCK (demux);
2647 static GstFlowReturn
2648 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2649 GstMatroskaTrackContext * stream)
2651 GstFlowReturn ret = GST_FLOW_OK;
2654 num = gst_buffer_list_length (stream->stream_headers);
2655 for (i = 0; i < num; ++i) {
2658 buf = gst_buffer_list_get (stream->stream_headers, i);
2659 buf = gst_buffer_copy (buf);
2661 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2663 if (stream->set_discont) {
2664 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2665 stream->set_discont = FALSE;
2667 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2670 /* push out all headers in one go and use last flow return */
2671 ret = gst_pad_push (stream->pad, buf);
2674 /* don't need these any longer */
2675 gst_buffer_list_unref (stream->stream_headers);
2676 stream->stream_headers = NULL;
2679 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2685 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2686 GstMatroskaTrackContext * stream)
2690 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2692 if (!stream->codec_priv)
2695 /* ideally, VobSub private data should be parsed and stored more convenient
2696 * elsewhere, but for now, only interested in a small part */
2698 /* make sure we have terminating 0 */
2699 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2701 /* just locate and parse palette part */
2702 start = strstr (buf, "palette:");
2707 guint8 r, g, b, y, u, v;
2710 while (g_ascii_isspace (*start))
2712 for (i = 0; i < 16; i++) {
2713 if (sscanf (start, "%06x", &col) != 1)
2716 while ((*start == ',') || g_ascii_isspace (*start))
2718 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2719 r = (col >> 16) & 0xff;
2720 g = (col >> 8) & 0xff;
2722 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2724 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2725 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2726 clut[i] = (y << 16) | (u << 8) | v;
2729 /* got them all without problems; build and send event */
2733 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2734 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2735 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2736 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2737 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
2738 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
2739 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
2740 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
2741 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
2742 G_TYPE_INT, clut[15], NULL);
2744 gst_pad_push_event (stream->pad,
2745 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
2752 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
2756 g_assert (demux->common.num_streams == demux->common.src->len);
2757 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2758 GstMatroskaTrackContext *stream;
2760 stream = g_ptr_array_index (demux->common.src, stream_nr);
2762 if (stream->send_stream_headers) {
2763 if (stream->stream_headers != NULL) {
2764 gst_matroska_demux_push_stream_headers (demux, stream);
2766 /* FIXME: perhaps we can just disable and skip this stream then */
2767 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
2768 ("Failed to extract stream headers from codec private data"));
2770 stream->send_stream_headers = FALSE;
2773 if (stream->send_dvd_event) {
2774 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
2775 /* FIXME: should we send this event again after (flushing) seek ? */
2776 stream->send_dvd_event = FALSE;
2782 static GstFlowReturn
2783 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
2784 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2787 guint seq_header_len;
2788 guint32 header, tmp;
2790 if (stream->codec_state) {
2791 seq_header = stream->codec_state;
2792 seq_header_len = stream->codec_state_size;
2793 } else if (stream->codec_priv) {
2794 seq_header = stream->codec_priv;
2795 seq_header_len = stream->codec_priv_size;
2800 /* Sequence header only needed for keyframes */
2801 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
2804 if (gst_buffer_get_size (*buf) < 4)
2807 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2808 header = GUINT32_FROM_BE (tmp);
2810 /* Sequence start code, if not found prepend */
2811 if (header != 0x000001b3) {
2814 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
2816 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
2819 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2820 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
2821 gst_buffer_get_size (*buf));
2823 gst_buffer_unref (*buf);
2830 static GstFlowReturn
2831 gst_matroska_demux_add_wvpk_header (GstElement * element,
2832 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2834 GstMatroskaTrackAudioContext *audiocontext =
2835 (GstMatroskaTrackAudioContext *) stream;
2836 GstBuffer *newbuf = NULL;
2837 GstMapInfo map, outmap;
2838 guint8 *buf_data, *data;
2846 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
2849 wvh.total_samples = -1;
2850 wvh.block_index = audiocontext->wvpk_block_index;
2852 if (audiocontext->channels <= 2) {
2853 guint32 block_samples, tmp;
2854 gsize size = gst_buffer_get_size (*buf);
2856 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
2857 block_samples = GUINT32_FROM_LE (tmp);
2858 /* we need to reconstruct the header of the wavpack block */
2860 /* -20 because ck_size is the size of the wavpack block -8
2861 * and lace_size is the size of the wavpack block + 12
2862 * (the three guint32 of the header that already are in the buffer) */
2863 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
2865 /* block_samples, flags and crc are already in the buffer */
2866 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
2868 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2874 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
2875 GST_WRITE_UINT16_LE (data + 8, wvh.version);
2876 GST_WRITE_UINT8 (data + 10, wvh.track_no);
2877 GST_WRITE_UINT8 (data + 11, wvh.index_no);
2878 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
2879 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
2880 gst_buffer_unmap (newbuf, &outmap);
2882 /* Append data from buf: */
2883 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
2884 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
2886 gst_buffer_unref (*buf);
2888 audiocontext->wvpk_block_index += block_samples;
2890 guint8 *outdata = NULL;
2892 gsize buf_size, size, out_size = 0;
2893 guint32 block_samples, flags, crc, blocksize;
2895 gst_buffer_map (*buf, &map, GST_MAP_READ);
2896 buf_data = map.data;
2897 buf_size = map.size;
2900 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
2901 gst_buffer_unmap (*buf, &map);
2902 return GST_FLOW_ERROR;
2908 block_samples = GST_READ_UINT32_LE (data);
2913 flags = GST_READ_UINT32_LE (data);
2916 crc = GST_READ_UINT32_LE (data);
2919 blocksize = GST_READ_UINT32_LE (data);
2923 if (blocksize == 0 || size < blocksize)
2926 g_assert ((newbuf == NULL) == (outdata == NULL));
2928 if (newbuf == NULL) {
2929 out_size = sizeof (Wavpack4Header) + blocksize;
2930 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
2932 gst_buffer_copy_into (newbuf, *buf,
2933 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
2936 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2937 outdata = outmap.data;
2939 gst_buffer_unmap (newbuf, &outmap);
2940 out_size += sizeof (Wavpack4Header) + blocksize;
2941 gst_buffer_set_size (newbuf, out_size);
2942 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
2943 outdata = outmap.data;
2946 outdata[outpos] = 'w';
2947 outdata[outpos + 1] = 'v';
2948 outdata[outpos + 2] = 'p';
2949 outdata[outpos + 3] = 'k';
2952 GST_WRITE_UINT32_LE (outdata + outpos,
2953 blocksize + sizeof (Wavpack4Header) - 8);
2954 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
2955 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
2956 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
2957 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
2958 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
2959 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
2960 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
2961 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
2964 memmove (outdata + outpos, data, blocksize);
2965 outpos += blocksize;
2969 gst_buffer_unmap (*buf, &map);
2970 gst_buffer_unref (*buf);
2973 gst_buffer_unmap (newbuf, &outmap);
2976 audiocontext->wvpk_block_index += block_samples;
2982 static GstFlowReturn
2983 gst_matroska_demux_add_prores_header (GstElement * element,
2984 GstMatroskaTrackContext * stream, GstBuffer ** buf)
2986 GstBuffer *newbuf = gst_buffer_new_allocate (NULL, 8, NULL);
2990 if (!gst_buffer_map (newbuf, &map, GST_MAP_WRITE)) {
2991 GST_ERROR ("Failed to map newly allocated buffer");
2992 return GST_FLOW_ERROR;
2995 frame_size = gst_buffer_get_size (*buf);
2997 GST_WRITE_UINT32_BE (map.data, frame_size);
3003 gst_buffer_unmap (newbuf, &map);
3004 *buf = gst_buffer_append (newbuf, *buf);
3009 /* @text must be null-terminated */
3011 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
3016 g_return_val_if_fail (text != NULL, FALSE);
3018 /* yes, this might all lead to false positives ... */
3019 tag = (gchar *) text;
3020 while ((tag = strchr (tag, '<'))) {
3022 if (*tag != '\0' && *(tag + 1) == '>') {
3023 /* some common convenience ones */
3024 /* maybe any character will do here ? */
3037 if (strstr (text, "<span"))
3043 static GstFlowReturn
3044 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
3045 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3047 GstMatroskaTrackSubtitleContext *sub_stream;
3048 const gchar *encoding;
3053 gboolean needs_unmap = TRUE;
3055 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3057 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
3060 /* The subtitle buffer we push out should not include a NUL terminator as
3061 * part of the data. */
3062 if (map.data[map.size - 1] == '\0') {
3063 gst_buffer_set_size (*buf, map.size - 1);
3064 gst_buffer_unmap (*buf, &map);
3065 gst_buffer_map (*buf, &map, GST_MAP_READ);
3068 if (!sub_stream->invalid_utf8) {
3069 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
3072 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
3073 " is not valid UTF-8, this is broken according to the matroska"
3074 " specification", stream->num);
3075 sub_stream->invalid_utf8 = TRUE;
3078 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3079 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3080 if (encoding == NULL || *encoding == '\0') {
3081 /* if local encoding is UTF-8 and no encoding specified
3082 * via the environment variable, assume ISO-8859-15 */
3083 if (g_get_charset (&encoding)) {
3084 encoding = "ISO-8859-15";
3089 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3090 (char *) "*", NULL, NULL, &err);
3093 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3094 encoding, err->message);
3098 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3099 encoding = "ISO-8859-15";
3101 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3102 encoding, (char *) "*", NULL, NULL, NULL);
3105 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3106 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3109 utf8 = g_strdup ("invalid subtitle");
3111 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3112 gst_buffer_unmap (*buf, &map);
3113 gst_buffer_copy_into (newbuf, *buf,
3114 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3116 gst_buffer_unref (*buf);
3119 gst_buffer_map (*buf, &map, GST_MAP_READ);
3123 if (sub_stream->check_markup) {
3124 /* caps claim markup text, so we need to escape text,
3125 * except if text is already markup and then needs no further escaping */
3126 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3127 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3129 if (!sub_stream->seen_markup_tag) {
3130 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3132 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3133 gst_buffer_unmap (*buf, &map);
3134 gst_buffer_copy_into (newbuf, *buf,
3135 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3136 GST_BUFFER_COPY_META, 0, -1);
3137 gst_buffer_unref (*buf);
3140 needs_unmap = FALSE;
3145 gst_buffer_unmap (*buf, &map);
3150 static GstFlowReturn
3151 gst_matroska_demux_check_aac (GstElement * element,
3152 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3157 gst_buffer_extract (*buf, 0, data, 2);
3158 size = gst_buffer_get_size (*buf);
3160 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3163 /* tss, ADTS data, remove codec_data
3164 * still assume it is at least parsed */
3165 stream->caps = gst_caps_make_writable (stream->caps);
3166 s = gst_caps_get_structure (stream->caps, 0);
3168 gst_structure_remove_field (s, "codec_data");
3169 gst_pad_set_caps (stream->pad, stream->caps);
3170 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3171 "new caps: %" GST_PTR_FORMAT, stream->caps);
3174 /* disable subsequent checking */
3175 stream->postprocess_frame = NULL;
3181 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3182 GstBuffer * buffer, gsize alignment)
3186 gst_buffer_map (buffer, &map, GST_MAP_READ);
3188 if (map.size < sizeof (guintptr)) {
3189 gst_buffer_unmap (buffer, &map);
3193 if (((guintptr) map.data) & (alignment - 1)) {
3194 GstBuffer *new_buffer;
3195 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3197 new_buffer = gst_buffer_new_allocate (NULL,
3198 gst_buffer_get_size (buffer), ¶ms);
3200 /* Copy data "by hand", so ensure alignment is kept: */
3201 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3203 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3204 GST_DEBUG_OBJECT (demux,
3205 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3208 gst_buffer_unmap (buffer, &map);
3209 gst_buffer_unref (buffer);
3214 gst_buffer_unmap (buffer, &map);
3218 static GstFlowReturn
3219 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3220 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3221 gboolean is_simpleblock)
3223 GstMatroskaTrackContext *stream = NULL;
3224 GstFlowReturn ret = GST_FLOW_OK;
3225 gboolean readblock = FALSE;
3227 guint64 block_duration = -1;
3228 gint64 block_discardpadding = 0;
3229 GstBuffer *buf = NULL;
3231 gint stream_num = -1, n, laces = 0;
3233 gint *lace_size = NULL;
3236 gint64 referenceblock = 0;
3238 GstClockTime buffer_timestamp;
3240 offset = gst_ebml_read_get_offset (ebml);
3242 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3243 if (!is_simpleblock) {
3244 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3248 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3252 /* one block inside the group. Note, block parsing is one
3253 * of the harder things, so this code is a bit complicated.
3254 * See http://www.matroska.org/ for documentation. */
3255 case GST_MATROSKA_ID_SIMPLEBLOCK:
3256 case GST_MATROSKA_ID_BLOCK:
3262 gst_buffer_unmap (buf, &map);
3263 gst_buffer_unref (buf);
3266 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3269 gst_buffer_map (buf, &map, GST_MAP_READ);
3273 /* first byte(s): blocknum */
3274 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3279 /* fetch stream from num */
3280 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3282 if (G_UNLIKELY (size < 3)) {
3283 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3284 /* non-fatal, try next block(group) */
3287 } else if (G_UNLIKELY (stream_num < 0 ||
3288 stream_num >= demux->common.num_streams)) {
3289 /* let's not give up on a stray invalid track number */
3290 GST_WARNING_OBJECT (demux,
3291 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3292 "; ignoring block", stream_num, num);
3296 stream = g_ptr_array_index (demux->common.src, stream_num);
3298 /* time (relative to cluster time) */
3299 time = ((gint16) GST_READ_UINT16_BE (data));
3302 flags = GST_READ_UINT8 (data);
3306 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3309 switch ((flags & 0x06) >> 1) {
3310 case 0x0: /* no lacing */
3312 lace_size = g_new (gint, 1);
3313 lace_size[0] = size;
3316 case 0x1: /* xiph lacing */
3317 case 0x2: /* fixed-size lacing */
3318 case 0x3: /* EBML lacing */
3320 goto invalid_lacing;
3321 laces = GST_READ_UINT8 (data) + 1;
3324 lace_size = g_new0 (gint, laces);
3326 switch ((flags & 0x06) >> 1) {
3327 case 0x1: /* xiph lacing */ {
3328 guint temp, total = 0;
3330 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3333 goto invalid_lacing;
3334 temp = GST_READ_UINT8 (data);
3335 lace_size[n] += temp;
3341 total += lace_size[n];
3343 lace_size[n] = size - total;
3347 case 0x2: /* fixed-size lacing */
3348 for (n = 0; n < laces; n++)
3349 lace_size[n] = size / laces;
3352 case 0x3: /* EBML lacing */ {
3355 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3359 total = lace_size[0] = num;
3360 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3364 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3368 lace_size[n] = lace_size[n - 1] + snum;
3369 total += lace_size[n];
3372 lace_size[n] = size - total;
3379 if (ret != GST_FLOW_OK)
3386 case GST_MATROSKA_ID_BLOCKDURATION:{
3387 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3388 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3393 case GST_MATROSKA_ID_DISCARDPADDING:{
3394 ret = gst_ebml_read_sint (ebml, &id, &block_discardpadding);
3395 GST_DEBUG_OBJECT (demux, "DiscardPadding: %" GST_STIME_FORMAT,
3396 GST_STIME_ARGS (block_discardpadding));
3400 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3401 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3402 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3407 case GST_MATROSKA_ID_CODECSTATE:{
3409 guint64 data_len = 0;
3412 gst_ebml_read_binary (ebml, &id, &data,
3413 &data_len)) != GST_FLOW_OK)
3416 if (G_UNLIKELY (stream == NULL)) {
3417 GST_WARNING_OBJECT (demux,
3418 "Unexpected CodecState subelement - ignoring");
3422 g_free (stream->codec_state);
3423 stream->codec_state = data;
3424 stream->codec_state_size = data_len;
3426 /* Decode if necessary */
3427 if (stream->encodings && stream->encodings->len > 0
3428 && stream->codec_state && stream->codec_state_size > 0) {
3429 if (!gst_matroska_decode_data (stream->encodings,
3430 &stream->codec_state, &stream->codec_state_size,
3431 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3432 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3436 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3437 stream->codec_state_size);
3442 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3446 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3447 case GST_MATROSKA_ID_BLOCKADDITIONS:
3448 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3449 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3450 case GST_MATROSKA_ID_SLICES:
3451 GST_DEBUG_OBJECT (demux,
3452 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3453 ret = gst_ebml_read_skip (ebml);
3461 /* reading a number or so could have failed */
3462 if (ret != GST_FLOW_OK)
3465 if (ret == GST_FLOW_OK && readblock) {
3466 gboolean invisible_frame = FALSE;
3467 gboolean delta_unit = FALSE;
3468 guint64 duration = 0;
3469 gint64 lace_time = 0;
3471 stream = g_ptr_array_index (demux->common.src, stream_num);
3473 if (cluster_time != GST_CLOCK_TIME_NONE) {
3474 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3475 * Drop unless the lace contains timestamp 0? */
3476 if (time < 0 && (-time) > cluster_time) {
3479 if (stream->timecodescale == 1.0)
3480 lace_time = (cluster_time + time) * demux->common.time_scale;
3483 gst_util_guint64_to_gdouble ((cluster_time + time) *
3484 demux->common.time_scale) * stream->timecodescale;
3487 lace_time = GST_CLOCK_TIME_NONE;
3490 /* need to refresh segment info ASAP */
3491 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3492 GstSegment *segment = &demux->common.segment;
3494 GstEvent *segment_event;
3496 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3497 demux->stream_start_time = lace_time;
3498 GST_DEBUG_OBJECT (demux,
3499 "Setting stream start time to %" GST_TIME_FORMAT,
3500 GST_TIME_ARGS (lace_time));
3502 clace_time = MAX (lace_time, demux->stream_start_time);
3503 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3504 demux->common.segment.position != 0) {
3505 GST_DEBUG_OBJECT (demux,
3506 "using stored seek position %" GST_TIME_FORMAT,
3507 GST_TIME_ARGS (demux->common.segment.position));
3508 clace_time = demux->common.segment.position + demux->stream_start_time;
3509 segment->position = GST_CLOCK_TIME_NONE;
3511 segment->start = clace_time;
3512 segment->stop = GST_CLOCK_TIME_NONE;
3513 segment->time = segment->start - demux->stream_start_time;
3514 segment->position = segment->start - demux->stream_start_time;
3515 GST_DEBUG_OBJECT (demux,
3516 "generated segment starting at %" GST_TIME_FORMAT ": %"
3517 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3518 /* now convey our segment notion downstream */
3519 segment_event = gst_event_new_segment (segment);
3520 if (demux->segment_seqnum)
3521 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3522 gst_matroska_demux_send_event (demux, segment_event);
3523 demux->need_segment = FALSE;
3524 demux->segment_seqnum = 0;
3527 /* send pending codec data headers for all streams,
3528 * before we perform sync across all streams */
3529 gst_matroska_demux_push_codec_data_all (demux);
3531 if (block_duration != -1) {
3532 if (stream->timecodescale == 1.0)
3533 duration = gst_util_uint64_scale (block_duration,
3534 demux->common.time_scale, 1);
3537 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3538 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3539 1)) * stream->timecodescale);
3540 } else if (stream->default_duration) {
3541 duration = stream->default_duration * laces;
3543 /* else duration is diff between timecode of this and next block */
3545 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3546 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3547 a ReferenceBlock implies that this is not a keyframe. In either
3548 case, it only makes sense for video streams. */
3549 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3551 invisible_frame = ((flags & 0x08)) &&
3552 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3553 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9));
3556 /* If we're doing a keyframe-only trickmode, only push keyframes on video
3560 segment.flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) {
3561 GST_LOG_OBJECT (demux, "Skipping non-keyframe on stream %d",
3568 for (n = 0; n < laces; n++) {
3571 if (G_UNLIKELY (lace_size[n] > size)) {
3572 GST_WARNING_OBJECT (demux, "Invalid lace size");
3576 /* QoS for video track with an index. the assumption is that
3577 index entries point to keyframes, but if that is not true we
3578 will instad skip until the next keyframe. */
3579 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3580 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3581 stream->index_table && demux->common.segment.rate > 0.0) {
3582 GstMatroskaTrackVideoContext *videocontext =
3583 (GstMatroskaTrackVideoContext *) stream;
3584 GstClockTime earliest_time;
3585 GstClockTime earliest_stream_time;
3587 GST_OBJECT_LOCK (demux);
3588 earliest_time = videocontext->earliest_time;
3589 GST_OBJECT_UNLOCK (demux);
3590 earliest_stream_time =
3591 gst_segment_position_from_running_time (&demux->common.segment,
3592 GST_FORMAT_TIME, earliest_time);
3594 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3595 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3596 lace_time <= earliest_stream_time) {
3597 /* find index entry (keyframe) <= earliest_stream_time */
3598 GstMatroskaIndex *entry =
3599 gst_util_array_binary_search (stream->index_table->data,
3600 stream->index_table->len, sizeof (GstMatroskaIndex),
3601 (GCompareDataFunc) gst_matroska_index_seek_find,
3602 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3604 /* if that entry (keyframe) is after the current the current
3605 buffer, we can skip pushing (and thus decoding) all
3606 buffers until that keyframe. */
3607 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3608 entry->time > lace_time) {
3609 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3610 stream->set_discont = TRUE;
3616 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3617 gst_buffer_get_size (buf) - size, lace_size[n]);
3618 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3621 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3623 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3625 if (invisible_frame)
3626 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3628 if (stream->encodings != NULL && stream->encodings->len > 0)
3629 sub = gst_matroska_decode_buffer (stream, sub);
3632 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3636 if (!stream->dts_only) {
3637 GST_BUFFER_PTS (sub) = lace_time;
3639 GST_BUFFER_DTS (sub) = lace_time;
3640 if (stream->intra_only)
3641 GST_BUFFER_PTS (sub) = lace_time;
3644 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
3646 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3647 GstClockTime last_stop_end;
3649 /* Check if this stream is after segment stop */
3650 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3651 lace_time >= demux->common.segment.stop) {
3652 GST_DEBUG_OBJECT (demux,
3653 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3654 GST_TIME_ARGS (demux->common.segment.stop));
3655 gst_buffer_unref (sub);
3658 if (offset >= stream->to_offset
3659 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3660 && lace_time > demux->to_time)) {
3661 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3663 gst_buffer_unref (sub);
3667 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3668 * that landed us with timestamps not quite intended */
3669 GST_OBJECT_LOCK (demux);
3670 if (demux->max_gap_time &&
3671 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3672 demux->common.segment.rate > 0.0) {
3673 GstClockTimeDiff diff;
3675 /* only send segments with increasing start times,
3676 * otherwise if these go back and forth downstream (sinks) increase
3677 * accumulated time and running_time */
3678 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3679 if (diff > 0 && diff > demux->max_gap_time
3680 && lace_time > demux->common.segment.start
3681 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3682 || lace_time < demux->common.segment.stop)) {
3684 GST_DEBUG_OBJECT (demux,
3685 "Gap of %" G_GINT64_FORMAT " ns detected in"
3686 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3687 "Sending updated SEGMENT events", diff,
3688 stream->index, GST_TIME_ARGS (stream->pos),
3689 GST_TIME_ARGS (lace_time));
3691 event = gst_event_new_gap (demux->last_stop_end, diff);
3692 GST_OBJECT_UNLOCK (demux);
3693 gst_pad_push_event (stream->pad, event);
3694 GST_OBJECT_LOCK (demux);
3698 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3699 || demux->common.segment.position < lace_time) {
3700 demux->common.segment.position = lace_time;
3702 GST_OBJECT_UNLOCK (demux);
3704 last_stop_end = lace_time;
3706 GST_BUFFER_DURATION (sub) = duration / laces;
3707 last_stop_end += GST_BUFFER_DURATION (sub);
3710 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3711 demux->last_stop_end < last_stop_end)
3712 demux->last_stop_end = last_stop_end;
3714 GST_OBJECT_LOCK (demux);
3715 if (demux->common.segment.duration == -1 ||
3716 demux->stream_start_time + demux->common.segment.duration <
3718 demux->common.segment.duration =
3719 last_stop_end - demux->stream_start_time;
3720 GST_OBJECT_UNLOCK (demux);
3721 if (!demux->invalid_duration) {
3722 gst_element_post_message (GST_ELEMENT_CAST (demux),
3723 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3724 demux->invalid_duration = TRUE;
3727 GST_OBJECT_UNLOCK (demux);
3731 stream->pos = lace_time;
3733 gst_matroska_demux_sync_streams (demux);
3735 if (stream->set_discont) {
3736 GST_DEBUG_OBJECT (demux, "marking DISCONT");
3737 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
3738 stream->set_discont = FALSE;
3740 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
3743 /* reverse playback book-keeping */
3744 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
3745 stream->from_time = lace_time;
3746 if (stream->from_offset == -1)
3747 stream->from_offset = offset;
3749 GST_DEBUG_OBJECT (demux,
3750 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
3751 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
3752 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
3753 GST_TIME_ARGS (buffer_timestamp),
3754 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
3757 if (demux->common.element_index) {
3758 if (stream->index_writer_id == -1)
3759 gst_index_get_writer_id (demux->common.element_index,
3760 GST_OBJECT (stream->pad), &stream->index_writer_id);
3762 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3763 G_GUINT64_FORMAT " for writer id %d",
3764 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
3765 stream->index_writer_id);
3766 gst_index_add_association (demux->common.element_index,
3767 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
3768 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
3769 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
3774 /* Postprocess the buffers depending on the codec used */
3775 if (stream->postprocess_frame) {
3776 GST_LOG_OBJECT (demux, "running post process");
3777 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
3780 /* At this point, we have a sub-buffer pointing at data within a larger
3781 buffer. This data might not be aligned with anything. If the data is
3782 raw samples though, we want it aligned to the raw type (eg, 4 bytes
3783 for 32 bit samples, etc), or bad things will happen downstream as
3784 elements typically assume minimal alignment.
3785 Therefore, create an aligned copy if necessary. */
3786 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
3788 if (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
3789 guint64 start_clip = 0, end_clip = 0;
3791 /* Codec delay is part of the timestamps */
3792 if (GST_BUFFER_PTS_IS_VALID (sub) && stream->codec_delay) {
3793 if (GST_BUFFER_PTS (sub) > stream->codec_delay) {
3794 GST_BUFFER_PTS (sub) -= stream->codec_delay;
3796 GST_BUFFER_PTS (sub) = 0;
3798 gst_util_uint64_scale_round (stream->codec_delay, 48000,
3801 if (GST_BUFFER_DURATION_IS_VALID (sub)) {
3802 if (GST_BUFFER_DURATION (sub) > stream->codec_delay)
3803 GST_BUFFER_DURATION (sub) -= stream->codec_delay;
3805 GST_BUFFER_DURATION (sub) = 0;
3810 if (block_discardpadding) {
3812 gst_util_uint64_scale_round (block_discardpadding, 48000,
3816 if (start_clip || end_clip) {
3817 gst_buffer_add_audio_clipping_meta (sub, GST_FORMAT_DEFAULT,
3818 start_clip, end_clip);
3822 if (GST_BUFFER_PTS_IS_VALID (sub)) {
3823 stream->pos = GST_BUFFER_PTS (sub);
3824 if (GST_BUFFER_DURATION_IS_VALID (sub))
3825 stream->pos += GST_BUFFER_DURATION (sub);
3826 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
3827 stream->pos = GST_BUFFER_DTS (sub);
3828 if (GST_BUFFER_DURATION_IS_VALID (sub))
3829 stream->pos += GST_BUFFER_DURATION (sub);
3832 ret = gst_pad_push (stream->pad, sub);
3834 if (demux->common.segment.rate < 0) {
3835 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
3836 /* In reverse playback we can get a GST_FLOW_EOS when
3837 * we are at the end of the segment, so we just need to jump
3838 * back to the previous section. */
3839 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
3844 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
3848 size -= lace_size[n];
3849 if (lace_time != GST_CLOCK_TIME_NONE && duration)
3850 lace_time += duration / laces;
3852 lace_time = GST_CLOCK_TIME_NONE;
3858 gst_buffer_unmap (buf, &map);
3859 gst_buffer_unref (buf);
3871 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
3877 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
3878 /* non-fatal, try next block(group) */
3884 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
3885 /* non-fatal, try next block(group) */
3891 /* return FALSE if block(group) should be skipped (due to a seek) */
3892 static inline gboolean
3893 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
3895 if (G_UNLIKELY (demux->seek_block)) {
3896 if (!(--demux->seek_block)) {
3899 GST_LOG_OBJECT (demux, "should skip block due to seek");
3907 static GstFlowReturn
3908 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
3912 guint64 seek_pos = (guint64) - 1;
3913 guint32 seek_id = 0;
3916 DEBUG_ELEMENT_START (demux, ebml, "Seek");
3918 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3919 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
3923 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3924 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3928 case GST_MATROSKA_ID_SEEKID:
3932 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3935 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
3940 case GST_MATROSKA_ID_SEEKPOSITION:
3944 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
3947 if (t > G_MAXINT64) {
3948 GST_WARNING_OBJECT (demux,
3949 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
3953 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
3959 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3965 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
3968 if (!seek_id || seek_pos == (guint64) - 1) {
3969 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
3970 G_GUINT64_FORMAT ")", seek_id, seek_pos);
3975 case GST_MATROSKA_ID_SEEKHEAD:
3978 case GST_MATROSKA_ID_CUES:
3979 case GST_MATROSKA_ID_TAGS:
3980 case GST_MATROSKA_ID_TRACKS:
3981 case GST_MATROSKA_ID_SEGMENTINFO:
3982 case GST_MATROSKA_ID_ATTACHMENTS:
3983 case GST_MATROSKA_ID_CHAPTERS:
3985 guint64 before_pos, length;
3989 length = gst_matroska_read_common_get_length (&demux->common);
3990 before_pos = demux->common.offset;
3992 if (length == (guint64) - 1) {
3993 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
3997 /* check for validity */
3998 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
3999 GST_WARNING_OBJECT (demux,
4000 "SeekHead reference lies outside file!" " (%"
4001 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
4002 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
4007 /* only pick up index location when streaming */
4008 if (demux->streaming) {
4009 if (seek_id == GST_MATROSKA_ID_CUES) {
4010 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
4011 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
4012 demux->index_offset);
4018 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
4021 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4022 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
4026 if (id != seek_id) {
4027 GST_WARNING_OBJECT (demux,
4028 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
4029 seek_id, id, seek_pos + demux->common.ebml_segment_start);
4032 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4037 demux->common.offset = before_pos;
4041 case GST_MATROSKA_ID_CLUSTER:
4043 guint64 pos = seek_pos + demux->common.ebml_segment_start;
4045 GST_LOG_OBJECT (demux, "Cluster position");
4046 if (G_UNLIKELY (!demux->clusters))
4047 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
4048 g_array_append_val (demux->clusters, pos);
4053 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
4056 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4061 static GstFlowReturn
4062 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4064 GstFlowReturn ret = GST_FLOW_OK;
4067 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4069 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4070 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4074 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4075 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4079 case GST_MATROSKA_ID_SEEKENTRY:
4081 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
4082 /* Ignore EOS and errors here */
4083 if (ret != GST_FLOW_OK) {
4084 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4091 ret = gst_matroska_read_common_parse_skip (&demux->common,
4092 ebml, "SeekHead", id);
4097 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4099 /* Sort clusters by position for easier searching */
4100 if (demux->clusters)
4101 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4106 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
4108 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4110 static inline GstFlowReturn
4111 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4113 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4114 /* only a few blocks are expected/allowed to be large,
4115 * and will be recursed into, whereas others will be read and must fit */
4116 if (demux->streaming) {
4117 /* fatal in streaming case, as we can't step over easily */
4118 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4119 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4120 "file might be corrupt.", bytes));
4121 return GST_FLOW_ERROR;
4123 /* indicate higher level to quietly give up */
4124 GST_DEBUG_OBJECT (demux,
4125 "too large block of size %" G_GUINT64_FORMAT, bytes);
4126 return GST_FLOW_ERROR;
4133 /* returns TRUE if we truely are in error state, and should give up */
4134 static inline GstFlowReturn
4135 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4137 if (!demux->streaming && demux->next_cluster_offset > 0) {
4138 /* just repositioning to where next cluster should be and try from there */
4139 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4140 G_GUINT64_FORMAT, demux->next_cluster_offset);
4141 demux->common.offset = demux->next_cluster_offset;
4142 demux->next_cluster_offset = 0;
4148 /* sigh, one last attempt above and beyond call of duty ...;
4149 * search for cluster mark following current pos */
4150 pos = demux->common.offset;
4151 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4152 if ((ret = gst_matroska_demux_search_cluster (demux, &pos)) != GST_FLOW_OK) {
4153 /* did not work, give up */
4156 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4157 /* try that position */
4158 demux->common.offset = pos;
4164 static inline GstFlowReturn
4165 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4167 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4168 demux->common.offset += flush;
4169 if (demux->streaming) {
4172 /* hard to skip large blocks when streaming */
4173 ret = gst_matroska_demux_check_read_size (demux, flush);
4174 if (ret != GST_FLOW_OK)
4176 if (flush <= gst_adapter_available (demux->common.adapter))
4177 gst_adapter_flush (demux->common.adapter, flush);
4179 return GST_FLOW_EOS;
4184 /* initializes @ebml with @bytes from input stream at current offset.
4185 * Returns EOS if insufficient available,
4186 * ERROR if too much was attempted to read. */
4187 static inline GstFlowReturn
4188 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4191 GstBuffer *buffer = NULL;
4192 GstFlowReturn ret = GST_FLOW_OK;
4194 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4196 ret = gst_matroska_demux_check_read_size (demux, bytes);
4197 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4198 if (!demux->streaming) {
4199 /* in pull mode, we can skip */
4200 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4201 ret = GST_FLOW_OVERFLOW;
4203 /* otherwise fatal */
4204 ret = GST_FLOW_ERROR;
4208 if (demux->streaming) {
4209 if (gst_adapter_available (demux->common.adapter) >= bytes)
4210 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4214 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4215 demux->common.offset, bytes, &buffer, NULL);
4216 if (G_LIKELY (buffer)) {
4217 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4218 demux->common.offset);
4219 demux->common.offset += bytes;
4226 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4229 gboolean seekable = FALSE;
4230 gint64 start = -1, stop = -1;
4232 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4233 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4234 GST_DEBUG_OBJECT (demux, "seeking query failed");
4238 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4240 /* try harder to query upstream size if we didn't get it the first time */
4241 if (seekable && stop == -1) {
4242 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4243 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4247 /* if upstream doesn't know the size, it's likely that it's not seekable in
4248 * practice even if it technically may be seekable */
4249 if (seekable && (start != 0 || stop <= start)) {
4250 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4255 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4256 G_GUINT64_FORMAT ")", seekable, start, stop);
4257 demux->seekable = seekable;
4259 gst_query_unref (query);
4262 static GstFlowReturn
4263 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4269 GstFlowReturn ret = GST_FLOW_OK;
4271 GST_WARNING_OBJECT (demux,
4272 "Found Cluster element before Tracks, searching Tracks");
4275 before_pos = demux->common.offset;
4277 /* Search Tracks element */
4279 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4280 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4281 if (ret != GST_FLOW_OK)
4284 if (id != GST_MATROSKA_ID_TRACKS) {
4285 /* we may be skipping large cluster here, so forego size check etc */
4286 /* ... but we can't skip undefined size; force error */
4287 if (length == G_MAXUINT64) {
4288 ret = gst_matroska_demux_check_read_size (demux, length);
4291 demux->common.offset += needed;
4292 demux->common.offset += length;
4297 /* will lead to track parsing ... */
4298 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4303 demux->common.offset = before_pos;
4308 #define GST_READ_CHECK(stmt) \
4310 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4311 if (ret == GST_FLOW_OVERFLOW) { \
4312 ret = GST_FLOW_OK; \
4318 static GstFlowReturn
4319 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4320 guint64 length, guint needed)
4322 GstEbmlRead ebml = { 0, };
4323 GstFlowReturn ret = GST_FLOW_OK;
4326 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4327 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4329 /* if we plan to read and parse this element, we need prefix (id + length)
4330 * and the contents */
4331 /* mind about overflow wrap-around when dealing with undefined size */
4333 if (G_LIKELY (length != G_MAXUINT64))
4336 switch (demux->common.state) {
4337 case GST_MATROSKA_READ_STATE_START:
4339 case GST_EBML_ID_HEADER:
4340 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4341 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4342 if (ret != GST_FLOW_OK)
4344 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4345 gst_matroska_demux_check_seekability (demux);
4348 goto invalid_header;
4352 case GST_MATROSKA_READ_STATE_SEGMENT:
4354 case GST_MATROSKA_ID_SEGMENT:
4355 /* eat segment prefix */
4356 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4357 GST_DEBUG_OBJECT (demux,
4358 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4359 G_GUINT64_FORMAT, demux->common.offset, length);
4360 /* seeks are from the beginning of the segment,
4361 * after the segment ID/length */
4362 demux->common.ebml_segment_start = demux->common.offset;
4364 length = G_MAXUINT64;
4365 demux->common.ebml_segment_length = length;
4366 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4369 GST_WARNING_OBJECT (demux,
4370 "Expected a Segment ID (0x%x), but received 0x%x!",
4371 GST_MATROSKA_ID_SEGMENT, id);
4372 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4376 case GST_MATROSKA_READ_STATE_SCANNING:
4377 if (id != GST_MATROSKA_ID_CLUSTER &&
4378 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
4381 case GST_MATROSKA_READ_STATE_HEADER:
4382 case GST_MATROSKA_READ_STATE_DATA:
4383 case GST_MATROSKA_READ_STATE_SEEK:
4385 case GST_MATROSKA_ID_SEGMENTINFO:
4386 if (!demux->common.segmentinfo_parsed) {
4387 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4388 ret = gst_matroska_read_common_parse_info (&demux->common,
4389 GST_ELEMENT_CAST (demux), &ebml);
4390 if (ret == GST_FLOW_OK)
4391 gst_matroska_demux_send_tags (demux);
4393 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4396 case GST_MATROSKA_ID_TRACKS:
4397 if (!demux->tracks_parsed) {
4398 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4399 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4401 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4404 case GST_MATROSKA_ID_CLUSTER:
4405 if (G_UNLIKELY (!demux->tracks_parsed)) {
4406 if (demux->streaming) {
4407 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4408 goto not_streamable;
4410 ret = gst_matroska_demux_find_tracks (demux);
4411 if (!demux->tracks_parsed)
4415 if (G_UNLIKELY (demux->common.state
4416 == GST_MATROSKA_READ_STATE_HEADER)) {
4417 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4418 demux->first_cluster_offset = demux->common.offset;
4419 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4420 gst_element_no_more_pads (GST_ELEMENT (demux));
4421 /* send initial segment - we wait till we know the first
4422 incoming timestamp, so we can properly set the start of
4424 demux->need_segment = TRUE;
4426 demux->cluster_time = GST_CLOCK_TIME_NONE;
4427 demux->cluster_offset = demux->common.offset;
4428 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4429 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4430 " not found in Cluster, trying next Cluster's first block instead",
4432 demux->seek_block = 0;
4434 demux->seek_first = FALSE;
4435 /* record next cluster for recovery */
4436 if (read != G_MAXUINT64)
4437 demux->next_cluster_offset = demux->cluster_offset + read;
4438 /* eat cluster prefix */
4439 gst_matroska_demux_flush (demux, needed);
4441 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4445 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4446 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4448 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4449 demux->cluster_time = num;
4451 if (demux->common.element_index) {
4452 if (demux->common.element_index_writer_id == -1)
4453 gst_index_get_writer_id (demux->common.element_index,
4454 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4455 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4456 G_GUINT64_FORMAT " for writer id %d",
4457 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4458 demux->common.element_index_writer_id);
4459 gst_index_add_association (demux->common.element_index,
4460 demux->common.element_index_writer_id,
4461 GST_ASSOCIATION_FLAG_KEY_UNIT,
4462 GST_FORMAT_TIME, demux->cluster_time,
4463 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4468 case GST_MATROSKA_ID_BLOCKGROUP:
4469 if (!gst_matroska_demux_seek_block (demux))
4471 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4472 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4473 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4474 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4475 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4477 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4479 case GST_MATROSKA_ID_SIMPLEBLOCK:
4480 if (!gst_matroska_demux_seek_block (demux))
4482 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4483 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4484 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4485 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4486 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4488 case GST_MATROSKA_ID_ATTACHMENTS:
4489 if (!demux->common.attachments_parsed) {
4490 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4491 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4492 GST_ELEMENT_CAST (demux), &ebml);
4493 if (ret == GST_FLOW_OK)
4494 gst_matroska_demux_send_tags (demux);
4496 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4499 case GST_MATROSKA_ID_TAGS:
4500 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4501 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4502 GST_ELEMENT_CAST (demux), &ebml);
4503 if (ret == GST_FLOW_OK)
4504 gst_matroska_demux_send_tags (demux);
4506 case GST_MATROSKA_ID_CHAPTERS:
4507 if (!demux->common.chapters_parsed) {
4508 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4510 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4512 if (demux->common.toc) {
4513 gst_matroska_demux_send_event (demux,
4514 gst_event_new_toc (demux->common.toc, FALSE));
4517 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4519 case GST_MATROSKA_ID_SEEKHEAD:
4520 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4521 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4523 case GST_MATROSKA_ID_CUES:
4524 if (demux->common.index_parsed) {
4525 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4528 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4529 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4530 /* only push based; delayed index building */
4531 if (ret == GST_FLOW_OK
4532 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4535 GST_OBJECT_LOCK (demux);
4536 event = demux->seek_event;
4537 demux->seek_event = NULL;
4538 GST_OBJECT_UNLOCK (demux);
4541 /* unlikely to fail, since we managed to seek to this point */
4542 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
4543 gst_event_unref (event);
4546 gst_event_unref (event);
4547 /* resume data handling, main thread clear to seek again */
4548 GST_OBJECT_LOCK (demux);
4549 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4550 GST_OBJECT_UNLOCK (demux);
4553 case GST_MATROSKA_ID_POSITION:
4554 case GST_MATROSKA_ID_PREVSIZE:
4555 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4556 case GST_MATROSKA_ID_SILENTTRACKS:
4557 GST_DEBUG_OBJECT (demux,
4558 "Skipping Cluster subelement 0x%x - ignoring", id);
4562 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4563 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4569 if (ret == GST_FLOW_PARSE)
4573 gst_ebml_read_clear (&ebml);
4579 /* simply exit, maybe not enough data yet */
4580 /* no ebml to clear if read error */
4585 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4586 ("Failed to parse Element 0x%x", id));
4587 ret = GST_FLOW_ERROR;
4592 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4593 ("File layout does not permit streaming"));
4594 ret = GST_FLOW_ERROR;
4599 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4600 ("No Tracks element found"));
4601 ret = GST_FLOW_ERROR;
4606 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4607 ret = GST_FLOW_ERROR;
4612 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4613 ret = GST_FLOW_ERROR;
4619 gst_matroska_demux_loop (GstPad * pad)
4621 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4627 /* If we have to close a segment, send a new segment to do this now */
4628 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4629 if (G_UNLIKELY (demux->new_segment)) {
4630 gst_matroska_demux_send_event (demux, demux->new_segment);
4631 demux->new_segment = NULL;
4635 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4636 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4637 if (ret == GST_FLOW_EOS) {
4639 } else if (ret == GST_FLOW_FLUSHING) {
4641 } else if (ret != GST_FLOW_OK) {
4642 ret = gst_matroska_demux_check_parse_error (demux);
4644 /* Only handle EOS as no error if we're outside the segment already */
4645 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4646 && demux->common.offset >=
4647 demux->common.ebml_segment_start +
4648 demux->common.ebml_segment_length))
4650 else if (ret != GST_FLOW_OK)
4656 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4657 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4660 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4661 if (ret == GST_FLOW_EOS)
4663 if (ret != GST_FLOW_OK)
4666 /* check if we're at the end of a configured segment */
4667 if (G_LIKELY (demux->common.src->len)) {
4670 g_assert (demux->common.num_streams == demux->common.src->len);
4671 for (i = 0; i < demux->common.src->len; i++) {
4672 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4674 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4675 GST_TIME_ARGS (context->pos));
4676 if (context->eos == FALSE)
4680 GST_INFO_OBJECT (demux, "All streams are EOS");
4686 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4687 demux->common.offset >= demux->cached_length)) {
4688 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4689 if (demux->common.offset == demux->cached_length) {
4690 GST_LOG_OBJECT (demux, "Reached end of stream");
4701 if (demux->common.segment.rate < 0.0) {
4702 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
4703 if (ret == GST_FLOW_OK)
4710 const gchar *reason = gst_flow_get_name (ret);
4711 gboolean push_eos = FALSE;
4713 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
4714 gst_pad_pause_task (demux->common.sinkpad);
4716 if (ret == GST_FLOW_EOS) {
4717 /* perform EOS logic */
4719 /* If we were in the headers, make sure we send no-more-pads.
4720 This will ensure decodebin does not get stuck thinking
4721 the chain is not complete yet, and waiting indefinitely. */
4722 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
4723 if (demux->common.src->len == 0) {
4724 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4725 ("No pads created"));
4727 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
4728 ("Failed to finish reading headers"));
4730 gst_element_no_more_pads (GST_ELEMENT (demux));
4733 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 msg = gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
4746 if (demux->segment_seqnum)
4747 gst_message_set_seqnum (msg, demux->segment_seqnum);
4748 gst_element_post_message (GST_ELEMENT (demux), msg);
4750 event = gst_event_new_segment_done (GST_FORMAT_TIME, stop);
4751 if (demux->segment_seqnum)
4752 gst_event_set_seqnum (event, demux->segment_seqnum);
4753 gst_matroska_demux_send_event (demux, event);
4757 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
4758 /* for fatal errors we post an error message */
4759 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
4760 ("stream stopped, reason %s", reason));
4766 /* send EOS, and prevent hanging if no streams yet */
4767 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
4768 event = gst_event_new_eos ();
4769 if (demux->segment_seqnum)
4770 gst_event_set_seqnum (event, demux->segment_seqnum);
4771 if (!gst_matroska_demux_send_event (demux, event) &&
4772 (ret == GST_FLOW_EOS)) {
4773 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4774 (NULL), ("got eos but no streams (yet)"));
4782 * Create and push a flushing seek event upstream
4785 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
4791 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
4794 gst_event_new_seek (rate, GST_FORMAT_BYTES,
4795 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
4796 GST_SEEK_TYPE_NONE, -1);
4797 gst_event_set_seqnum (event, seqnum);
4799 res = gst_pad_push_event (demux->common.sinkpad, event);
4801 /* segment event will update offset */
4805 static GstFlowReturn
4806 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
4808 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4810 GstFlowReturn ret = GST_FLOW_OK;
4815 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
4816 GST_DEBUG_OBJECT (demux, "got DISCONT");
4817 gst_adapter_clear (demux->common.adapter);
4818 GST_OBJECT_LOCK (demux);
4819 gst_matroska_read_common_reset_streams (&demux->common,
4820 GST_CLOCK_TIME_NONE, FALSE);
4821 GST_OBJECT_UNLOCK (demux);
4824 gst_adapter_push (demux->common.adapter, buffer);
4828 available = gst_adapter_available (demux->common.adapter);
4830 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
4831 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4832 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
4833 if (demux->common.ebml_segment_length != G_MAXUINT64
4834 && demux->common.offset >=
4835 demux->common.ebml_segment_start + demux->common.ebml_segment_length)
4840 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4841 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
4842 demux->common.offset, id, length, needed, available);
4844 if (needed > available)
4847 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4848 if (ret == GST_FLOW_EOS) {
4849 /* need more data */
4851 } else if (ret != GST_FLOW_OK) {
4858 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
4861 gboolean res = TRUE;
4862 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4864 GST_DEBUG_OBJECT (demux,
4865 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
4867 switch (GST_EVENT_TYPE (event)) {
4868 case GST_EVENT_SEGMENT:
4870 const GstSegment *segment;
4872 /* some debug output */
4873 gst_event_parse_segment (event, &segment);
4874 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
4875 GST_DEBUG_OBJECT (demux,
4876 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
4879 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
4880 GST_DEBUG_OBJECT (demux, "still starting");
4884 /* we only expect a BYTE segment, e.g. following a seek */
4885 if (segment->format != GST_FORMAT_BYTES) {
4886 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
4890 GST_DEBUG_OBJECT (demux, "clearing segment state");
4891 GST_OBJECT_LOCK (demux);
4892 /* clear current segment leftover */
4893 gst_adapter_clear (demux->common.adapter);
4894 /* and some streaming setup */
4895 demux->common.offset = segment->start;
4896 /* accumulate base based on current position */
4897 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
4898 demux->common.segment.base +=
4899 (MAX (demux->common.segment.position, demux->stream_start_time)
4900 - demux->stream_start_time) / fabs (demux->common.segment.rate);
4901 /* do not know where we are;
4902 * need to come across a cluster and generate segment */
4903 demux->common.segment.position = GST_CLOCK_TIME_NONE;
4904 demux->cluster_time = GST_CLOCK_TIME_NONE;
4905 demux->cluster_offset = 0;
4906 demux->need_segment = TRUE;
4907 demux->segment_seqnum = gst_event_get_seqnum (event);
4908 /* but keep some of the upstream segment */
4909 demux->common.segment.rate = segment->rate;
4910 /* also check if need to keep some of the requested seek position */
4911 if (demux->seek_offset == segment->start) {
4912 GST_DEBUG_OBJECT (demux, "position matches requested seek");
4913 demux->common.segment.position = demux->requested_seek_time;
4915 GST_DEBUG_OBJECT (demux, "unexpected segment position");
4917 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
4918 demux->seek_offset = -1;
4919 GST_OBJECT_UNLOCK (demux);
4921 /* chain will send initial segment after pads have been added,
4922 * or otherwise come up with one */
4923 GST_DEBUG_OBJECT (demux, "eating event");
4924 gst_event_unref (event);
4930 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
4931 gst_event_unref (event);
4932 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4933 (NULL), ("got eos and didn't receive a complete header object"));
4934 } else if (demux->common.num_streams == 0) {
4935 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
4936 (NULL), ("got eos but no streams (yet)"));
4938 gst_matroska_demux_send_event (demux, event);
4942 case GST_EVENT_FLUSH_STOP:
4946 gst_adapter_clear (demux->common.adapter);
4947 GST_OBJECT_LOCK (demux);
4948 gst_matroska_read_common_reset_streams (&demux->common,
4949 GST_CLOCK_TIME_NONE, TRUE);
4950 gst_flow_combiner_reset (demux->flowcombiner);
4951 dur = demux->common.segment.duration;
4952 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
4953 demux->common.segment.duration = dur;
4954 demux->cluster_time = GST_CLOCK_TIME_NONE;
4955 demux->cluster_offset = 0;
4956 GST_OBJECT_UNLOCK (demux);
4960 res = gst_pad_event_default (pad, parent, event);
4968 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
4970 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
4972 gboolean pull_mode = FALSE;
4974 query = gst_query_new_scheduling ();
4976 if (gst_pad_peer_query (sinkpad, query))
4977 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
4978 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
4980 gst_query_unref (query);
4983 GST_DEBUG ("going to pull mode");
4984 demux->streaming = FALSE;
4985 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
4987 GST_DEBUG ("going to push (streaming) mode");
4988 demux->streaming = TRUE;
4989 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
4994 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
4995 GstPadMode mode, gboolean active)
4998 case GST_PAD_MODE_PULL:
5000 /* if we have a scheduler we can start the task */
5001 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
5004 gst_pad_stop_task (sinkpad);
5007 case GST_PAD_MODE_PUSH:
5015 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
5016 videocontext, const gchar * codec_id, guint8 * data, guint size,
5017 gchar ** codec_name, guint32 * riff_fourcc)
5019 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
5020 GstCaps *caps = NULL;
5022 g_assert (videocontext != NULL);
5023 g_assert (codec_name != NULL);
5028 /* TODO: check if we have all codec types from matroska-ids.h
5029 * check if we have to do more special things with codec_private
5032 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
5033 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
5036 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
5037 gst_riff_strf_vids *vids = NULL;
5040 GstBuffer *buf = NULL;
5042 vids = (gst_riff_strf_vids *) data;
5044 /* assure size is big enough */
5046 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
5049 if (size < sizeof (gst_riff_strf_vids)) {
5050 vids = g_new (gst_riff_strf_vids, 1);
5051 memcpy (vids, data, size);
5054 context->dts_only = TRUE; /* VFW files only store DTS */
5056 /* little-endian -> byte-order */
5057 vids->size = GUINT32_FROM_LE (vids->size);
5058 vids->width = GUINT32_FROM_LE (vids->width);
5059 vids->height = GUINT32_FROM_LE (vids->height);
5060 vids->planes = GUINT16_FROM_LE (vids->planes);
5061 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
5062 vids->compression = GUINT32_FROM_LE (vids->compression);
5063 vids->image_size = GUINT32_FROM_LE (vids->image_size);
5064 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
5065 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
5066 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
5067 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
5069 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
5070 gsize offset = sizeof (gst_riff_strf_vids);
5073 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
5074 size - offset), size - offset);
5078 *riff_fourcc = vids->compression;
5080 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
5081 buf, NULL, codec_name);
5084 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
5085 GST_FOURCC_ARGS (vids->compression));
5087 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
5088 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
5089 "video/x-compressed-yuv");
5090 context->intra_only =
5091 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
5095 gst_buffer_unref (buf);
5097 if (vids != (gst_riff_strf_vids *) data)
5100 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
5102 GstVideoFormat format;
5104 gst_video_info_init (&info);
5105 switch (videocontext->fourcc) {
5106 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5107 format = GST_VIDEO_FORMAT_I420;
5109 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5110 format = GST_VIDEO_FORMAT_YUY2;
5112 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5113 format = GST_VIDEO_FORMAT_YV12;
5115 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5116 format = GST_VIDEO_FORMAT_UYVY;
5118 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5119 format = GST_VIDEO_FORMAT_AYUV;
5121 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
5122 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
5123 format = GST_VIDEO_FORMAT_GRAY8;
5125 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
5126 format = GST_VIDEO_FORMAT_RGB;
5128 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
5129 format = GST_VIDEO_FORMAT_BGR;
5132 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5133 GST_FOURCC_ARGS (videocontext->fourcc));
5137 context->intra_only = TRUE;
5139 gst_video_info_set_format (&info, format, videocontext->pixel_width,
5140 videocontext->pixel_height);
5141 caps = gst_video_info_to_caps (&info);
5142 *codec_name = gst_pb_utils_get_codec_description (caps);
5143 context->alignment = 32;
5144 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5145 caps = gst_caps_new_simple ("video/x-divx",
5146 "divxversion", G_TYPE_INT, 4, NULL);
5147 *codec_name = g_strdup ("MPEG-4 simple profile");
5148 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5149 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5150 caps = gst_caps_new_simple ("video/mpeg",
5151 "mpegversion", G_TYPE_INT, 4,
5152 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5156 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5157 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5158 gst_buffer_unref (priv);
5160 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
5162 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5163 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5165 *codec_name = g_strdup ("MPEG-4 advanced profile");
5166 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5168 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5169 "divxversion", G_TYPE_INT, 3, NULL),
5170 gst_structure_new ("video/x-msmpeg",
5171 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5173 caps = gst_caps_new_simple ("video/x-msmpeg",
5174 "msmpegversion", G_TYPE_INT, 43, NULL);
5175 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5176 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5177 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5180 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5185 caps = gst_caps_new_simple ("video/mpeg",
5186 "systemstream", G_TYPE_BOOLEAN, FALSE,
5187 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5188 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5189 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5190 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5191 caps = gst_caps_new_empty_simple ("image/jpeg");
5192 *codec_name = g_strdup ("Motion-JPEG");
5193 context->intra_only = TRUE;
5194 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5195 caps = gst_caps_new_empty_simple ("video/x-h264");
5199 /* First byte is the version, second is the profile indication, and third
5200 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5201 * level indication. */
5202 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5205 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5206 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5207 gst_buffer_unref (priv);
5209 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5210 "alignment", G_TYPE_STRING, "au", NULL);
5212 GST_WARNING ("No codec data found, assuming output is byte-stream");
5213 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5216 *codec_name = g_strdup ("H264");
5217 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
5218 caps = gst_caps_new_empty_simple ("video/x-h265");
5222 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
5225 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5226 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5227 gst_buffer_unref (priv);
5229 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
5230 "alignment", G_TYPE_STRING, "au", NULL);
5232 GST_WARNING ("No codec data found, assuming output is byte-stream");
5233 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5236 *codec_name = g_strdup ("HEVC");
5237 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5238 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5239 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5240 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5241 gint rmversion = -1;
5243 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5245 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5247 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5249 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5252 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5253 "rmversion", G_TYPE_INT, rmversion, NULL);
5254 GST_DEBUG ("data:%p, size:0x%x", data, size);
5255 /* We need to extract the extradata ! */
5256 if (data && (size >= 0x22)) {
5261 subformat = GST_READ_UINT32_BE (data + 0x1a);
5262 rformat = GST_READ_UINT32_BE (data + 0x1e);
5265 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5267 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5268 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5269 gst_buffer_unref (priv);
5272 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5273 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5274 caps = gst_caps_new_empty_simple ("video/x-theora");
5275 context->stream_headers =
5276 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5277 context->codec_priv_size);
5278 /* FIXME: mark stream as broken and skip if there are no stream headers */
5279 context->send_stream_headers = TRUE;
5280 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5281 caps = gst_caps_new_empty_simple ("video/x-dirac");
5282 *codec_name = g_strdup_printf ("Dirac");
5283 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5284 caps = gst_caps_new_empty_simple ("video/x-vp8");
5285 *codec_name = g_strdup_printf ("On2 VP8");
5286 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5287 caps = gst_caps_new_empty_simple ("video/x-vp9");
5288 *codec_name = g_strdup_printf ("On2 VP9");
5289 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
5291 const gchar *variant, *variant_descr = "";
5293 /* Expect a fourcc in the codec private data */
5294 if (!data || size < 4) {
5295 GST_WARNING ("No or too small PRORESS fourcc (%d bytes)", size);
5299 fourcc = GST_STR_FOURCC (data);
5301 case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
5302 variant_descr = " 4:2:2 LT";
5305 case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
5307 variant_descr = " 4:2:2 HQ";
5309 case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
5311 variant_descr = " 4:4:4:4";
5313 case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
5315 variant_descr = " 4:2:2 Proxy";
5317 case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
5319 variant = "standard";
5320 variant_descr = " 4:2:2 SD";
5324 GST_LOG ("Prores video, codec fourcc %" GST_FOURCC_FORMAT,
5325 GST_FOURCC_ARGS (fourcc));
5327 caps = gst_caps_new_simple ("video/x-prores",
5328 "format", G_TYPE_STRING, variant, NULL);
5329 *codec_name = g_strdup_printf ("Apple ProRes%s", variant_descr);
5330 context->postprocess_frame = gst_matroska_demux_add_prores_header;
5332 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5338 GstStructure *structure;
5340 for (i = 0; i < gst_caps_get_size (caps); i++) {
5341 structure = gst_caps_get_structure (caps, i);
5343 /* FIXME: use the real unit here! */
5344 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5345 videocontext->pixel_width,
5346 videocontext->pixel_height,
5347 videocontext->display_width, videocontext->display_height);
5349 /* pixel width and height are the w and h of the video in pixels */
5350 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5351 gint w = videocontext->pixel_width;
5352 gint h = videocontext->pixel_height;
5354 gst_structure_set (structure,
5355 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5358 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5361 if (videocontext->display_width <= 0)
5362 videocontext->display_width = videocontext->pixel_width;
5363 if (videocontext->display_height <= 0)
5364 videocontext->display_height = videocontext->pixel_height;
5366 /* calculate the pixel aspect ratio using the display and pixel w/h */
5367 n = videocontext->display_width * videocontext->pixel_height;
5368 d = videocontext->display_height * videocontext->pixel_width;
5369 GST_DEBUG ("setting PAR to %d/%d", n, d);
5370 gst_structure_set (structure, "pixel-aspect-ratio",
5372 videocontext->display_width * videocontext->pixel_height,
5373 videocontext->display_height * videocontext->pixel_width, NULL);
5376 if (videocontext->default_fps > 0.0) {
5379 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5381 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5383 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5385 } else if (context->default_duration > 0) {
5388 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5390 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5391 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5393 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5394 fps_n, fps_d, NULL);
5396 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5400 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5401 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5404 if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
5405 if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
5406 videocontext->pixel_width, videocontext->pixel_height,
5407 videocontext->display_width * videocontext->pixel_height,
5408 videocontext->display_height * videocontext->pixel_width)) {
5409 videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
5411 gst_caps_set_simple (caps,
5412 "multiview-mode", G_TYPE_STRING,
5413 gst_video_multiview_mode_to_caps_string
5414 (videocontext->multiview_mode), "multiview-flags",
5415 GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
5416 GST_FLAG_SET_MASK_EXACT, NULL);
5419 caps = gst_caps_simplify (caps);
5426 * Some AAC specific code... *sigh*
5427 * FIXME: maybe we should use '15' and code the sample rate explicitly
5428 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5432 aac_rate_idx (gint rate)
5436 else if (75132 <= rate)
5438 else if (55426 <= rate)
5440 else if (46009 <= rate)
5442 else if (37566 <= rate)
5444 else if (27713 <= rate)
5446 else if (23004 <= rate)
5448 else if (18783 <= rate)
5450 else if (13856 <= rate)
5452 else if (11502 <= rate)
5454 else if (9391 <= rate)
5461 aac_profile_idx (const gchar * codec_id)
5465 if (strlen (codec_id) <= 12)
5467 else if (!strncmp (&codec_id[12], "MAIN", 4))
5469 else if (!strncmp (&codec_id[12], "LC", 2))
5471 else if (!strncmp (&codec_id[12], "SSR", 3))
5480 round_up_pow2 (guint n)
5491 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5494 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5495 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5496 gchar ** codec_name, guint16 * riff_audio_fmt)
5498 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5499 GstCaps *caps = NULL;
5501 g_assert (audiocontext != NULL);
5502 g_assert (codec_name != NULL);
5505 *riff_audio_fmt = 0;
5507 /* TODO: check if we have all codec types from matroska-ids.h
5508 * check if we have to do more special things with codec_private
5509 * check if we need bitdepth in different places too
5510 * implement channel position magic
5512 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5513 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5514 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5515 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5518 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5519 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5520 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5523 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5525 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5530 caps = gst_caps_new_simple ("audio/mpeg",
5531 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5532 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5533 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5534 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5537 GstAudioFormat format;
5539 sign = (audiocontext->bitdepth != 8);
5540 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5541 endianness = G_BIG_ENDIAN;
5543 endianness = G_LITTLE_ENDIAN;
5545 format = gst_audio_format_build_integer (sign, endianness,
5546 audiocontext->bitdepth, audiocontext->bitdepth);
5548 /* FIXME: Channel mask and reordering */
5549 caps = gst_caps_new_simple ("audio/x-raw",
5550 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5551 "layout", G_TYPE_STRING, "interleaved",
5552 "channel-mask", GST_TYPE_BITMASK,
5553 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5555 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5556 audiocontext->bitdepth);
5557 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5558 context->alignment = round_up_pow2 (context->alignment);
5559 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5560 const gchar *format;
5561 if (audiocontext->bitdepth == 32)
5565 /* FIXME: Channel mask and reordering */
5566 caps = gst_caps_new_simple ("audio/x-raw",
5567 "format", G_TYPE_STRING, format,
5568 "layout", G_TYPE_STRING, "interleaved",
5569 "channel-mask", GST_TYPE_BITMASK,
5570 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5571 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5572 audiocontext->bitdepth);
5573 context->alignment = audiocontext->bitdepth / 8;
5574 context->alignment = round_up_pow2 (context->alignment);
5575 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5576 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5577 caps = gst_caps_new_simple ("audio/x-ac3",
5578 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5579 *codec_name = g_strdup ("AC-3 audio");
5580 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5581 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5582 caps = gst_caps_new_simple ("audio/x-eac3",
5583 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5584 *codec_name = g_strdup ("E-AC-3 audio");
5585 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5586 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5587 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5588 *codec_name = g_strdup ("Dolby TrueHD");
5589 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5590 caps = gst_caps_new_empty_simple ("audio/x-dts");
5591 *codec_name = g_strdup ("DTS audio");
5592 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5593 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5594 context->stream_headers =
5595 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5596 context->codec_priv_size);
5597 /* FIXME: mark stream as broken and skip if there are no stream headers */
5598 context->send_stream_headers = TRUE;
5599 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5600 caps = gst_caps_new_empty_simple ("audio/x-flac");
5601 context->stream_headers =
5602 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5603 context->codec_priv_size);
5604 /* FIXME: mark stream as broken and skip if there are no stream headers */
5605 context->send_stream_headers = TRUE;
5606 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5607 caps = gst_caps_new_empty_simple ("audio/x-speex");
5608 context->stream_headers =
5609 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5610 context->codec_priv_size);
5611 /* FIXME: mark stream as broken and skip if there are no stream headers */
5612 context->send_stream_headers = TRUE;
5613 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5616 if (context->codec_priv_size >= 19) {
5617 if (audiocontext->samplerate)
5618 GST_WRITE_UINT32_LE ((guint8 *) context->codec_priv + 12,
5619 audiocontext->samplerate);
5620 if (context->codec_delay) {
5622 gst_util_uint64_scale_round (context->codec_delay, 48000,
5624 GST_WRITE_UINT16_LE ((guint8 *) context->codec_priv + 10, delay);
5628 gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5629 context->codec_priv_size), context->codec_priv_size);
5630 caps = gst_codec_utils_opus_create_caps_from_header (tmp, NULL);
5631 gst_buffer_unref (tmp);
5632 *codec_name = g_strdup ("Opus");
5633 } else if (context->codec_priv_size == 0) {
5634 GST_WARNING ("No Opus codec data found, trying to create one");
5635 if (audiocontext->channels <= 2) {
5636 guint8 streams, coupled, channels;
5640 audiocontext->samplerate == 0 ? 48000 : audiocontext->samplerate;
5641 channels = audiocontext->channels == 0 ? 2 : audiocontext->channels;
5642 if (channels == 1) {
5651 gst_codec_utils_opus_create_caps (samplerate, channels, 0, streams,
5654 *codec_name = g_strdup ("Opus");
5656 GST_WARNING ("Failed to create Opus caps from audio context");
5659 GST_WARNING ("No Opus codec data, and not enough info to create one");
5662 GST_WARNING ("Invalid Opus codec data size (got %" G_GSIZE_FORMAT
5663 ", expected 19)", context->codec_priv_size);
5665 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
5666 gst_riff_strf_auds auds;
5668 if (data && size >= 18) {
5669 GstBuffer *codec_data = NULL;
5671 /* little-endian -> byte-order */
5672 auds.format = GST_READ_UINT16_LE (data);
5673 auds.channels = GST_READ_UINT16_LE (data + 2);
5674 auds.rate = GST_READ_UINT32_LE (data + 4);
5675 auds.av_bps = GST_READ_UINT32_LE (data + 8);
5676 auds.blockalign = GST_READ_UINT16_LE (data + 12);
5677 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
5679 /* 18 is the waveformatex size */
5681 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
5682 data + 18, size - 18, 0, size - 18, NULL, NULL);
5686 *riff_audio_fmt = auds.format;
5688 /* FIXME: Handle reorder map */
5689 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
5690 codec_data, codec_name, NULL);
5692 gst_buffer_unref (codec_data);
5695 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
5698 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
5700 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
5701 GstBuffer *priv = NULL;
5703 gint rate_idx, profile;
5704 guint8 *data = NULL;
5706 /* unspecified AAC profile with opaque private codec data */
5707 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
5708 if (context->codec_priv_size >= 2) {
5709 guint obj_type, freq_index, explicit_freq_bytes = 0;
5711 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5713 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
5714 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
5715 if (freq_index == 15)
5716 explicit_freq_bytes = 3;
5717 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
5718 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5719 context->codec_priv_size), context->codec_priv_size);
5720 /* assume SBR if samplerate <= 24kHz */
5721 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
5722 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
5723 audiocontext->samplerate *= 2;
5726 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
5727 /* this is pretty broken;
5728 * maybe we need to make up some default private,
5729 * or maybe ADTS data got dumped in.
5730 * Let's set up some private data now, and check actual data later */
5731 /* just try this and see what happens ... */
5732 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
5733 context->postprocess_frame = gst_matroska_demux_check_aac;
5737 /* make up decoder-specific data if it is not supplied */
5741 priv = gst_buffer_new_allocate (NULL, 5, NULL);
5742 gst_buffer_map (priv, &map, GST_MAP_WRITE);
5744 rate_idx = aac_rate_idx (audiocontext->samplerate);
5745 profile = aac_profile_idx (codec_id);
5747 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
5748 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
5750 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
5751 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
5753 gst_buffer_unmap (priv, &map);
5754 gst_buffer_set_size (priv, 2);
5755 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
5756 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
5759 if (g_strrstr (codec_id, "SBR")) {
5760 /* HE-AAC (aka SBR AAC) */
5761 audiocontext->samplerate *= 2;
5762 rate_idx = aac_rate_idx (audiocontext->samplerate);
5763 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
5764 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
5765 data[4] = (1 << 7) | (rate_idx << 3);
5766 gst_buffer_unmap (priv, &map);
5768 gst_buffer_unmap (priv, &map);
5769 gst_buffer_set_size (priv, 2);
5772 gst_buffer_unmap (priv, &map);
5773 gst_buffer_unref (priv);
5775 GST_ERROR ("Unknown AAC profile and no codec private data");
5780 caps = gst_caps_new_simple ("audio/mpeg",
5781 "mpegversion", G_TYPE_INT, mpegversion,
5782 "framed", G_TYPE_BOOLEAN, TRUE,
5783 "stream-format", G_TYPE_STRING, "raw", NULL);
5784 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5785 if (context->codec_priv && context->codec_priv_size > 0)
5786 gst_codec_utils_aac_caps_set_level_and_profile (caps,
5787 context->codec_priv, context->codec_priv_size);
5788 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
5789 gst_buffer_unref (priv);
5791 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
5792 caps = gst_caps_new_simple ("audio/x-tta",
5793 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
5794 *codec_name = g_strdup ("TTA audio");
5795 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
5796 caps = gst_caps_new_simple ("audio/x-wavpack",
5797 "width", G_TYPE_INT, audiocontext->bitdepth,
5798 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5799 *codec_name = g_strdup ("Wavpack audio");
5800 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
5801 audiocontext->wvpk_block_index = 0;
5802 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
5803 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
5804 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
5805 gint raversion = -1;
5807 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
5809 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
5814 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
5815 "raversion", G_TYPE_INT, raversion, NULL);
5816 /* Extract extra information from caps, mapping varies based on codec */
5817 if (data && (size >= 0x50)) {
5824 guint extra_data_size;
5826 GST_ERROR ("real audio raversion:%d", raversion);
5827 if (raversion == 8) {
5829 flavor = GST_READ_UINT16_BE (data + 22);
5830 packet_size = GST_READ_UINT32_BE (data + 24);
5831 height = GST_READ_UINT16_BE (data + 40);
5832 leaf_size = GST_READ_UINT16_BE (data + 44);
5833 sample_width = GST_READ_UINT16_BE (data + 58);
5834 extra_data_size = GST_READ_UINT32_BE (data + 74);
5837 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
5838 flavor, packet_size, height, leaf_size, sample_width,
5840 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
5841 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
5842 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
5844 if ((size - 78) >= extra_data_size) {
5845 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
5847 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5848 gst_buffer_unref (priv);
5853 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
5854 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
5855 caps = gst_caps_new_empty_simple ("audio/x-sipro");
5856 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
5857 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
5858 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
5859 *codec_name = g_strdup ("Real Audio Lossless");
5860 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
5861 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
5862 *codec_name = g_strdup ("Sony ATRAC3");
5864 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5869 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
5872 for (i = 0; i < gst_caps_get_size (caps); i++) {
5873 gst_structure_set (gst_caps_get_structure (caps, i),
5874 "channels", G_TYPE_INT, audiocontext->channels,
5875 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
5879 caps = gst_caps_simplify (caps);
5886 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
5887 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
5889 GstCaps *caps = NULL;
5890 GstMatroskaTrackContext *context =
5891 (GstMatroskaTrackContext *) subtitlecontext;
5893 /* for backwards compatibility */
5894 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
5895 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
5896 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
5897 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
5898 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
5899 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
5900 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
5901 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
5903 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
5904 * Check if we have to do something with codec_private */
5905 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
5906 /* well, plain text simply does not have a lot of markup ... */
5907 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
5908 "pango-markup", NULL);
5909 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5910 subtitlecontext->check_markup = TRUE;
5911 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
5912 caps = gst_caps_new_empty_simple ("application/x-ssa");
5913 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5914 subtitlecontext->check_markup = FALSE;
5915 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
5916 caps = gst_caps_new_empty_simple ("application/x-ass");
5917 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5918 subtitlecontext->check_markup = FALSE;
5919 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
5920 caps = gst_caps_new_empty_simple ("application/x-usf");
5921 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
5922 subtitlecontext->check_markup = FALSE;
5923 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
5924 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
5925 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
5926 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
5927 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
5928 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
5929 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
5930 context->stream_headers =
5931 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5932 context->codec_priv_size);
5933 /* FIXME: mark stream as broken and skip if there are no stream headers */
5934 context->send_stream_headers = TRUE;
5936 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
5937 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
5940 if (data != NULL && size > 0) {
5943 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
5944 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
5945 gst_buffer_unref (buf);
5953 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
5955 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5957 GST_OBJECT_LOCK (demux);
5958 if (demux->common.element_index)
5959 gst_object_unref (demux->common.element_index);
5960 demux->common.element_index = index ? gst_object_ref (index) : NULL;
5961 GST_OBJECT_UNLOCK (demux);
5962 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
5963 demux->common.element_index);
5967 gst_matroska_demux_get_index (GstElement * element)
5969 GstIndex *result = NULL;
5970 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5972 GST_OBJECT_LOCK (demux);
5973 if (demux->common.element_index)
5974 result = gst_object_ref (demux->common.element_index);
5975 GST_OBJECT_UNLOCK (demux);
5977 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
5983 static GstStateChangeReturn
5984 gst_matroska_demux_change_state (GstElement * element,
5985 GstStateChange transition)
5987 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
5988 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
5990 /* handle upwards state changes here */
5991 switch (transition) {
5996 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
5998 /* handle downwards state changes */
5999 switch (transition) {
6000 case GST_STATE_CHANGE_PAUSED_TO_READY:
6001 gst_matroska_demux_reset (GST_ELEMENT (demux));
6011 gst_matroska_demux_set_property (GObject * object,
6012 guint prop_id, const GValue * value, GParamSpec * pspec)
6014 GstMatroskaDemux *demux;
6016 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6017 demux = GST_MATROSKA_DEMUX (object);
6020 case PROP_MAX_GAP_TIME:
6021 GST_OBJECT_LOCK (demux);
6022 demux->max_gap_time = g_value_get_uint64 (value);
6023 GST_OBJECT_UNLOCK (demux);
6026 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6032 gst_matroska_demux_get_property (GObject * object,
6033 guint prop_id, GValue * value, GParamSpec * pspec)
6035 GstMatroskaDemux *demux;
6037 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6038 demux = GST_MATROSKA_DEMUX (object);
6041 case PROP_MAX_GAP_TIME:
6042 GST_OBJECT_LOCK (demux);
6043 g_value_set_uint64 (value, demux->max_gap_time);
6044 GST_OBJECT_UNLOCK (demux);
6047 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6053 gst_matroska_demux_plugin_init (GstPlugin * plugin)
6057 /* parser helper separate debug */
6058 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
6059 0, "EBML stream helper class");
6061 /* create an elementfactory for the matroska_demux element */
6062 if (!gst_element_register (plugin, "matroskademux",
6063 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))