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)
90 #define INVALID_DATA_THRESHOLD (2 * 1024 * 1024)
92 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
95 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
96 "video/x-matroska-3d; audio/webm; video/webm")
99 /* TODO: fill in caps! */
101 static GstStaticPadTemplate audio_src_templ =
102 GST_STATIC_PAD_TEMPLATE ("audio_%u",
105 GST_STATIC_CAPS ("ANY")
108 static GstStaticPadTemplate video_src_templ =
109 GST_STATIC_PAD_TEMPLATE ("video_%u",
112 GST_STATIC_CAPS ("ANY")
115 static GstStaticPadTemplate subtitle_src_templ =
116 GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
119 GST_STATIC_CAPS ("text/x-raw, format=pango-markup; application/x-ssa; "
120 "application/x-ass;application/x-usf; subpicture/x-dvd; "
121 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
124 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
125 guint32 id, guint64 length, guint needed);
127 /* element functions */
128 static void gst_matroska_demux_loop (GstPad * pad);
130 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
132 static gboolean gst_matroska_demux_element_query (GstElement * element,
136 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad,
138 static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
139 GstObject * parent, GstPadMode mode, gboolean active);
141 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
142 GstPad * pad, GstEvent * event);
143 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
144 GstObject * parent, GstEvent * event);
145 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
146 GstObject * parent, GstQuery * query);
148 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
149 GstObject * parent, GstEvent * event);
150 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
151 GstObject * object, GstBuffer * buffer);
153 static GstStateChangeReturn
154 gst_matroska_demux_change_state (GstElement * element,
155 GstStateChange transition);
158 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
159 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
163 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
164 * videocontext, const gchar * codec_id, guint8 * data, guint size,
165 gchar ** codec_name, guint32 * riff_fourcc);
166 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
167 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
168 gchar ** codec_name, guint16 * riff_audio_fmt);
170 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
171 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
174 static void gst_matroska_demux_reset (GstElement * element);
175 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
176 gdouble rate, guint64 offset, guint32 seqnum, GstSeekFlags flags);
178 /* gobject functions */
179 static void gst_matroska_demux_set_property (GObject * object,
180 guint prop_id, const GValue * value, GParamSpec * pspec);
181 static void gst_matroska_demux_get_property (GObject * object,
182 guint prop_id, GValue * value, GParamSpec * pspec);
184 GType gst_matroska_demux_get_type (void);
185 #define parent_class gst_matroska_demux_parent_class
186 G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
189 gst_matroska_demux_finalize (GObject * object)
191 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
193 gst_matroska_read_common_finalize (&demux->common);
194 gst_flow_combiner_free (demux->flowcombiner);
195 G_OBJECT_CLASS (parent_class)->finalize (object);
199 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
201 GObjectClass *gobject_class = (GObjectClass *) klass;
202 GstElementClass *gstelement_class = (GstElementClass *) klass;
204 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
207 gobject_class->finalize = gst_matroska_demux_finalize;
209 gobject_class->get_property = gst_matroska_demux_get_property;
210 gobject_class->set_property = gst_matroska_demux_set_property;
212 g_object_class_install_property (gobject_class, PROP_MAX_GAP_TIME,
213 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
214 "The demuxer sends out segment events for skipping "
215 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
216 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
218 gstelement_class->change_state =
219 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
220 gstelement_class->send_event =
221 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
222 gstelement_class->query =
223 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
225 gstelement_class->set_index =
226 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
227 gstelement_class->get_index =
228 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
231 gst_element_class_add_static_pad_template (gstelement_class,
233 gst_element_class_add_static_pad_template (gstelement_class,
235 gst_element_class_add_static_pad_template (gstelement_class,
236 &subtitle_src_templ);
237 gst_element_class_add_static_pad_template (gstelement_class, &sink_templ);
239 gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
241 "Demuxes Matroska/WebM streams into video/audio/subtitles",
242 "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
246 gst_matroska_demux_init (GstMatroskaDemux * demux)
248 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
250 gst_pad_set_activate_function (demux->common.sinkpad,
251 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
252 gst_pad_set_activatemode_function (demux->common.sinkpad,
253 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
254 gst_pad_set_chain_function (demux->common.sinkpad,
255 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
256 gst_pad_set_event_function (demux->common.sinkpad,
257 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
258 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
260 /* init defaults for common read context */
261 gst_matroska_read_common_init (&demux->common);
263 /* property defaults */
264 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
266 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
268 demux->flowcombiner = gst_flow_combiner_new ();
271 gst_matroska_demux_reset (GST_ELEMENT (demux));
275 gst_matroska_demux_reset (GstElement * element)
277 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
279 GST_DEBUG_OBJECT (demux, "Resetting state");
281 gst_matroska_read_common_reset (GST_ELEMENT (demux), &demux->common);
283 demux->num_a_streams = 0;
284 demux->num_t_streams = 0;
285 demux->num_v_streams = 0;
287 demux->have_group_id = FALSE;
288 demux->group_id = G_MAXUINT;
291 demux->tracks_parsed = FALSE;
293 if (demux->clusters) {
294 g_array_free (demux->clusters, TRUE);
295 demux->clusters = NULL;
298 g_list_foreach (demux->seek_parsed,
299 (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
300 g_list_free (demux->seek_parsed);
301 demux->seek_parsed = NULL;
303 demux->last_stop_end = GST_CLOCK_TIME_NONE;
304 demux->seek_block = 0;
305 demux->stream_start_time = GST_CLOCK_TIME_NONE;
306 demux->to_time = GST_CLOCK_TIME_NONE;
307 demux->cluster_time = GST_CLOCK_TIME_NONE;
308 demux->cluster_offset = 0;
309 demux->next_cluster_offset = 0;
310 demux->stream_last_time = GST_CLOCK_TIME_NONE;
311 demux->last_cluster_offset = 0;
312 demux->index_offset = 0;
313 demux->seekable = FALSE;
314 demux->need_segment = FALSE;
315 demux->segment_seqnum = 0;
316 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
317 demux->seek_offset = -1;
318 demux->building_index = FALSE;
319 if (demux->seek_event) {
320 gst_event_unref (demux->seek_event);
321 demux->seek_event = NULL;
324 demux->seek_index = NULL;
325 demux->seek_entry = 0;
327 if (demux->new_segment) {
328 gst_event_unref (demux->new_segment);
329 demux->new_segment = NULL;
332 demux->invalid_duration = FALSE;
334 demux->cached_length = G_MAXUINT64;
336 gst_flow_combiner_clear (demux->flowcombiner);
340 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
346 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
348 GST_DEBUG ("decoding buffer %p", buf);
350 gst_buffer_map (buf, &map, GST_MAP_READ);
354 g_return_val_if_fail (size > 0, buf);
356 if (gst_matroska_decode_data (context->encodings, &data, &size,
357 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
358 gst_buffer_unmap (buf, &map);
359 gst_buffer_unref (buf);
360 return gst_buffer_new_wrapped (data, size);
362 GST_DEBUG ("decode data failed");
363 gst_buffer_unmap (buf, &map);
364 gst_buffer_unref (buf);
370 gst_matroska_demux_add_stream_headers_to_caps (GstMatroskaDemux * demux,
371 GstBufferList * list, GstCaps * caps)
374 GValue arr_val = G_VALUE_INIT;
375 GValue buf_val = G_VALUE_INIT;
378 g_assert (gst_caps_is_writable (caps));
380 g_value_init (&arr_val, GST_TYPE_ARRAY);
381 g_value_init (&buf_val, GST_TYPE_BUFFER);
383 num = gst_buffer_list_length (list);
384 for (i = 0; i < num; ++i) {
385 g_value_set_boxed (&buf_val, gst_buffer_list_get (list, i));
386 gst_value_array_append_value (&arr_val, &buf_val);
389 s = gst_caps_get_structure (caps, 0);
390 gst_structure_take_value (s, "streamheader", &arr_val);
391 g_value_unset (&buf_val);
395 gst_matroska_demux_parse_colour (GstMatroskaDemux * demux, GstEbmlRead * ebml,
396 GstMatroskaTrackVideoContext * video_context)
399 GstVideoColorimetry colorimetry;
403 colorimetry.range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
404 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
405 colorimetry.transfer = GST_VIDEO_TRANSFER_UNKNOWN;
406 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
408 DEBUG_ELEMENT_START (demux, ebml, "TrackVideoColour");
410 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
413 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
414 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
418 case GST_MATROSKA_ID_VIDEOMATRIXCOEFFICIENTS:{
419 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
424 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
427 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT709;
430 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
433 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_FCC;
435 /* FIXME: "5: BT470BG" is undefined in GstVideoColorMatrix
436 * but it's functionally same as "6: BT601" */
439 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT601;
442 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_SMPTE240M;
445 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
448 GST_FIXME_OBJECT (demux, "Unsupported color matrix coefficients %"
449 G_GUINT64_FORMAT, num);
455 case GST_MATROSKA_ID_VIDEORANGE:{
456 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
461 colorimetry.range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
464 colorimetry.range = GST_VIDEO_COLOR_RANGE_16_235;
467 colorimetry.range = GST_VIDEO_COLOR_RANGE_0_255;
470 GST_FIXME_OBJECT (demux, "Unsupported color range %"
471 G_GUINT64_FORMAT, num);
477 case GST_MATROSKA_ID_VIDEOTRANSFERCHARACTERISTICS:{
478 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
482 /* FIXME: "6: BT601" and "14: BT2020_10" are undefined in
483 * GstVideoTransferFunction, but functionally same as "1: BT709" */
487 colorimetry.transfer = GST_VIDEO_TRANSFER_BT709;
490 colorimetry.transfer = GST_VIDEO_TRANSFER_UNKNOWN;
493 colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA22;
496 colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA28;
499 colorimetry.transfer = GST_VIDEO_TRANSFER_SMPTE240M;
502 colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA10;
505 colorimetry.transfer = GST_VIDEO_TRANSFER_LOG100;
508 colorimetry.transfer = GST_VIDEO_TRANSFER_LOG316;
511 colorimetry.transfer = GST_VIDEO_TRANSFER_SRGB;
514 colorimetry.transfer = GST_VIDEO_TRANSFER_BT2020_12;
517 GST_FIXME_OBJECT (demux,
518 "Unsupported color transfer characteristics %"
519 G_GUINT64_FORMAT, num);
525 case GST_MATROSKA_ID_VIDEOPRIMARIES:{
526 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
531 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
534 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
537 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT470M;
540 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT470BG;
543 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE170M;
546 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE240M;
549 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_FILM;
552 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
555 GST_FIXME_OBJECT (demux, "Unsupported color primaries %"
556 G_GUINT64_FORMAT, num);
563 GST_FIXME_OBJECT (demux, "Unsupported subelement 0x%x in Colour", id);
564 ret = gst_ebml_read_skip (ebml);
569 memcpy (&video_context->colorimetry, &colorimetry,
570 sizeof (GstVideoColorimetry));
573 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideoColour", ret);
578 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
580 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
581 GstMatroskaTrackContext *context;
582 GstPadTemplate *templ = NULL;
583 GstStreamFlags stream_flags;
584 GstCaps *caps = NULL;
585 GstTagList *cached_taglist;
586 gchar *padname = NULL;
588 guint32 id, riff_fourcc = 0;
589 guint16 riff_audio_fmt = 0;
590 GstEvent *stream_start;
594 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
596 /* start with the master */
597 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
598 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
602 /* allocate generic... if we know the type, we'll g_renew()
603 * with the precise type */
604 context = g_new0 (GstMatroskaTrackContext, 1);
605 g_ptr_array_add (demux->common.src, context);
606 context->index = demux->common.num_streams;
607 context->index_writer_id = -1;
608 context->type = 0; /* no type yet */
609 context->default_duration = 0;
611 context->set_discont = TRUE;
612 context->timecodescale = 1.0;
614 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
615 GST_MATROSKA_TRACK_LACING;
616 context->from_time = GST_CLOCK_TIME_NONE;
617 context->from_offset = -1;
618 context->to_offset = G_MAXINT64;
619 context->alignment = 1;
620 context->dts_only = FALSE;
621 context->intra_only = FALSE;
622 context->tags = gst_tag_list_new_empty ();
623 demux->common.num_streams++;
624 g_assert (demux->common.src->len == demux->common.num_streams);
626 GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
628 /* try reading the trackentry headers */
629 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
630 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
634 /* track number (unique stream ID) */
635 case GST_MATROSKA_ID_TRACKNUMBER:{
638 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
642 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
643 ret = GST_FLOW_ERROR;
645 } else if (!gst_matroska_read_common_tracknumber_unique (&demux->common,
647 GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
648 " is not unique", num);
649 ret = GST_FLOW_ERROR;
653 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
657 /* track UID (unique identifier) */
658 case GST_MATROSKA_ID_TRACKUID:{
661 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
665 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
666 ret = GST_FLOW_ERROR;
670 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
675 /* track type (video, audio, combined, subtitle, etc.) */
676 case GST_MATROSKA_ID_TRACKTYPE:{
679 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
683 if (context->type != 0 && context->type != track_type) {
684 GST_WARNING_OBJECT (demux,
685 "More than one tracktype defined in a TrackEntry - skipping");
687 } else if (track_type < 1 || track_type > 254) {
688 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
693 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
695 /* ok, so we're actually going to reallocate this thing */
696 switch (track_type) {
697 case GST_MATROSKA_TRACK_TYPE_VIDEO:
698 gst_matroska_track_init_video_context (&context);
700 case GST_MATROSKA_TRACK_TYPE_AUDIO:
701 gst_matroska_track_init_audio_context (&context);
703 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
704 gst_matroska_track_init_subtitle_context (&context);
706 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
707 case GST_MATROSKA_TRACK_TYPE_LOGO:
708 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
709 case GST_MATROSKA_TRACK_TYPE_CONTROL:
711 GST_WARNING_OBJECT (demux,
712 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
717 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
722 /* tracktype specific stuff for video */
723 case GST_MATROSKA_ID_TRACKVIDEO:{
724 GstMatroskaTrackVideoContext *videocontext;
726 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
728 if (!gst_matroska_track_init_video_context (&context)) {
729 GST_WARNING_OBJECT (demux,
730 "TrackVideo element in non-video track - ignoring track");
731 ret = GST_FLOW_ERROR;
733 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
736 videocontext = (GstMatroskaTrackVideoContext *) context;
737 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
740 while (ret == GST_FLOW_OK &&
741 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
742 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
746 /* Should be one level up but some broken muxers write it here. */
747 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
750 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
754 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
758 GST_DEBUG_OBJECT (demux,
759 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
760 context->default_duration = num;
764 /* video framerate */
765 /* NOTE: This one is here only for backward compatibility.
766 * Use _TRACKDEFAULDURATION one level up. */
767 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
770 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
774 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
778 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
779 if (context->default_duration == 0)
780 context->default_duration =
781 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
782 videocontext->default_fps = num;
786 /* width of the size to display the video at */
787 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
790 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
794 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
798 GST_DEBUG_OBJECT (demux,
799 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
800 videocontext->display_width = num;
804 /* height of the size to display the video at */
805 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
808 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
812 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
816 GST_DEBUG_OBJECT (demux,
817 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
818 videocontext->display_height = num;
822 /* width of the video in the file */
823 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
826 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
830 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
834 GST_DEBUG_OBJECT (demux,
835 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
836 videocontext->pixel_width = num;
840 /* height of the video in the file */
841 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
844 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
848 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
852 GST_DEBUG_OBJECT (demux,
853 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
854 videocontext->pixel_height = num;
858 /* whether the video is interlaced */
859 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
862 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
866 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
868 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
869 GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
870 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
875 /* aspect ratio behaviour */
876 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
879 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
882 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
883 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
884 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
885 GST_WARNING_OBJECT (demux,
886 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
889 GST_DEBUG_OBJECT (demux,
890 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
891 videocontext->asr_mode = num;
895 /* colourspace (only matters for raw video) fourcc */
896 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
901 gst_ebml_read_binary (ebml, &id, &data,
902 &datalen)) != GST_FLOW_OK)
907 GST_WARNING_OBJECT (demux,
908 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
913 memcpy (&videocontext->fourcc, data, 4);
914 GST_DEBUG_OBJECT (demux,
915 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
916 GST_FOURCC_ARGS (videocontext->fourcc));
922 case GST_MATROSKA_ID_VIDEOCOLOUR:{
923 ret = gst_matroska_demux_parse_colour (demux, ebml, videocontext);
927 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
931 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
934 GST_DEBUG_OBJECT (demux, "StereoMode: %" G_GUINT64_FORMAT, num);
937 case GST_MATROSKA_STEREO_MODE_SBS_RL:
938 videocontext->multiview_flags =
939 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
941 case GST_MATROSKA_STEREO_MODE_SBS_LR:
942 videocontext->multiview_mode =
943 GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
945 case GST_MATROSKA_STEREO_MODE_TB_RL:
946 videocontext->multiview_flags =
947 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
949 case GST_MATROSKA_STEREO_MODE_TB_LR:
950 videocontext->multiview_mode =
951 GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM;
953 case GST_MATROSKA_STEREO_MODE_CHECKER_RL:
954 videocontext->multiview_flags =
955 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
957 case GST_MATROSKA_STEREO_MODE_CHECKER_LR:
958 videocontext->multiview_mode =
959 GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD;
961 case GST_MATROSKA_STEREO_MODE_FBF_RL:
962 videocontext->multiview_flags =
963 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
965 case GST_MATROSKA_STEREO_MODE_FBF_LR:
966 videocontext->multiview_mode =
967 GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
968 /* FIXME: In frame-by-frame mode, left/right frame buffers are
969 * laced within one block, and we'll need to apply FIRST_IN_BUNDLE
970 * accordingly. See http://www.matroska.org/technical/specs/index.html#StereoMode */
971 GST_FIXME_OBJECT (demux,
972 "Frame-by-frame stereoscopic mode not fully implemented");
979 GST_WARNING_OBJECT (demux,
980 "Unknown TrackVideo subelement 0x%x - ignoring", id);
982 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
983 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
984 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
985 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
986 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
987 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
988 ret = gst_ebml_read_skip (ebml);
993 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
997 /* tracktype specific stuff for audio */
998 case GST_MATROSKA_ID_TRACKAUDIO:{
999 GstMatroskaTrackAudioContext *audiocontext;
1001 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
1003 if (!gst_matroska_track_init_audio_context (&context)) {
1004 GST_WARNING_OBJECT (demux,
1005 "TrackAudio element in non-audio track - ignoring track");
1006 ret = GST_FLOW_ERROR;
1010 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
1013 audiocontext = (GstMatroskaTrackAudioContext *) context;
1014 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1)
1017 while (ret == GST_FLOW_OK &&
1018 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1019 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1024 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
1027 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1032 GST_WARNING_OBJECT (demux,
1033 "Invalid TrackAudioSamplingFrequency %lf", num);
1037 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
1038 audiocontext->samplerate = num;
1043 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
1046 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1050 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
1054 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
1056 audiocontext->bitdepth = num;
1061 case GST_MATROSKA_ID_AUDIOCHANNELS:{
1064 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1068 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
1072 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
1074 audiocontext->channels = num;
1079 GST_WARNING_OBJECT (demux,
1080 "Unknown TrackAudio subelement 0x%x - ignoring", id);
1082 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
1083 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
1084 ret = gst_ebml_read_skip (ebml);
1089 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
1094 /* codec identifier */
1095 case GST_MATROSKA_ID_CODECID:{
1098 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
1101 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
1102 context->codec_id = text;
1106 /* codec private data */
1107 case GST_MATROSKA_ID_CODECPRIVATE:{
1112 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
1115 context->codec_priv = data;
1116 context->codec_priv_size = size;
1118 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1123 /* name of the codec */
1124 case GST_MATROSKA_ID_CODECNAME:{
1127 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1130 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1131 context->codec_name = text;
1136 case GST_MATROSKA_ID_CODECDELAY:{
1139 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1142 context->codec_delay = num;
1144 GST_DEBUG_OBJECT (demux, "CodecDelay: %" GST_TIME_FORMAT,
1145 GST_TIME_ARGS (num));
1150 case GST_MATROSKA_ID_SEEKPREROLL:{
1153 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1156 context->seek_preroll = num;
1158 GST_DEBUG_OBJECT (demux, "SeekPreroll: %" GST_TIME_FORMAT,
1159 GST_TIME_ARGS (num));
1163 /* name of this track */
1164 case GST_MATROSKA_ID_TRACKNAME:{
1167 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1170 context->name = text;
1171 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1175 /* language (matters for audio/subtitles, mostly) */
1176 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1179 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1183 context->language = text;
1186 if (strlen (context->language) >= 4 && context->language[3] == '-')
1187 context->language[3] = '\0';
1189 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1190 GST_STR_NULL (context->language));
1194 /* whether this is actually used */
1195 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1198 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1202 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1204 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1206 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1207 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1211 /* whether it's the default for this track type */
1212 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1215 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1219 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1221 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1223 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1224 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
1228 /* whether the track must be used during playback */
1229 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1232 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1236 context->flags |= GST_MATROSKA_TRACK_FORCED;
1238 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1240 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1241 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
1245 /* lacing (like MPEG, where blocks don't end/start on frame
1247 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1250 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1254 context->flags |= GST_MATROSKA_TRACK_LACING;
1256 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1258 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1259 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
1263 /* default length (in time) of one data block in this track */
1264 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1267 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1272 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1276 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1278 context->default_duration = num;
1282 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1283 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1288 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1291 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1295 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1299 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1300 context->timecodescale = num;
1305 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1308 /* we ignore these because they're nothing useful (i.e. crap)
1309 * or simply not implemented yet. */
1310 case GST_MATROSKA_ID_TRACKMINCACHE:
1311 case GST_MATROSKA_ID_TRACKMAXCACHE:
1312 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1313 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1314 case GST_MATROSKA_ID_TRACKOVERLAY:
1315 case GST_MATROSKA_ID_TRACKTRANSLATE:
1316 case GST_MATROSKA_ID_TRACKOFFSET:
1317 case GST_MATROSKA_ID_CODECSETTINGS:
1318 case GST_MATROSKA_ID_CODECINFOURL:
1319 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1320 case GST_MATROSKA_ID_CODECDECODEALL:
1321 ret = gst_ebml_read_skip (ebml);
1326 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1328 /* Decode codec private data if necessary */
1329 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1330 && context->codec_priv_size > 0) {
1331 if (!gst_matroska_decode_data (context->encodings,
1332 &context->codec_priv, &context->codec_priv_size,
1333 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1334 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1335 ret = GST_FLOW_ERROR;
1339 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1340 && ret != GST_FLOW_EOS)) {
1341 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1342 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1344 demux->common.num_streams--;
1345 g_ptr_array_remove_index (demux->common.src, demux->common.num_streams);
1346 g_assert (demux->common.src->len == demux->common.num_streams);
1347 gst_matroska_track_free (context);
1352 /* check for a cached track taglist */
1354 (GstTagList *) g_hash_table_lookup (demux->common.cached_track_taglists,
1355 GUINT_TO_POINTER (context->uid));
1357 gst_tag_list_insert (context->tags, cached_taglist, GST_TAG_MERGE_APPEND);
1359 /* now create the GStreamer connectivity */
1360 switch (context->type) {
1361 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1362 GstMatroskaTrackVideoContext *videocontext =
1363 (GstMatroskaTrackVideoContext *) context;
1365 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1366 templ = gst_element_class_get_pad_template (klass, "video_%u");
1367 caps = gst_matroska_demux_video_caps (videocontext,
1368 context->codec_id, context->codec_priv,
1369 context->codec_priv_size, &codec, &riff_fourcc);
1372 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1373 GST_TAG_VIDEO_CODEC, codec, NULL);
1374 context->tags_changed = TRUE;
1380 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1381 GstMatroskaTrackAudioContext *audiocontext =
1382 (GstMatroskaTrackAudioContext *) context;
1384 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1385 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1386 caps = gst_matroska_demux_audio_caps (audiocontext,
1387 context->codec_id, context->codec_priv, context->codec_priv_size,
1388 &codec, &riff_audio_fmt);
1391 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1392 GST_TAG_AUDIO_CODEC, codec, NULL);
1393 context->tags_changed = TRUE;
1399 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1400 GstMatroskaTrackSubtitleContext *subtitlecontext =
1401 (GstMatroskaTrackSubtitleContext *) context;
1403 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1404 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1405 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1406 context->codec_id, context->codec_priv, context->codec_priv_size);
1410 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1411 case GST_MATROSKA_TRACK_TYPE_LOGO:
1412 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1413 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1415 /* we should already have quit by now */
1416 g_assert_not_reached ();
1419 if ((context->language == NULL || *context->language == '\0') &&
1420 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1421 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1422 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1423 context->language = g_strdup ("eng");
1426 if (context->language) {
1429 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1430 lang = gst_tag_get_language_code (context->language);
1431 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1432 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1433 context->tags_changed = TRUE;
1437 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1438 "codec_id='%s'", context->codec_id);
1439 switch (context->type) {
1440 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1441 caps = gst_caps_new_empty_simple ("video/x-unknown");
1443 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1444 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1446 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1447 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1449 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1451 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1454 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1457 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1458 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1459 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1460 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1461 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1462 GST_FOURCC_ARGS (riff_fourcc));
1463 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1466 } else if (context->stream_headers != NULL) {
1467 gst_matroska_demux_add_stream_headers_to_caps (demux,
1468 context->stream_headers, caps);
1471 /* the pad in here */
1472 context->pad = gst_pad_new_from_template (templ, padname);
1473 context->caps = caps;
1475 gst_pad_set_event_function (context->pad,
1476 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1477 gst_pad_set_query_function (context->pad,
1478 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1480 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1483 gst_pad_set_element_private (context->pad, context);
1485 gst_pad_use_fixed_caps (context->pad);
1486 gst_pad_set_active (context->pad, TRUE);
1489 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1490 "%03" G_GUINT64_FORMAT ":%03" G_GUINT64_FORMAT,
1491 context->num, context->uid);
1493 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1496 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1497 demux->have_group_id = TRUE;
1499 demux->have_group_id = FALSE;
1500 gst_event_unref (stream_start);
1501 } else if (!demux->have_group_id) {
1502 demux->have_group_id = TRUE;
1503 demux->group_id = gst_util_group_id_next ();
1506 stream_start = gst_event_new_stream_start (stream_id);
1508 if (demux->have_group_id)
1509 gst_event_set_group_id (stream_start, demux->group_id);
1510 stream_flags = GST_STREAM_FLAG_NONE;
1511 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1512 stream_flags |= GST_STREAM_FLAG_SPARSE;
1513 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1514 stream_flags |= GST_STREAM_FLAG_SELECT;
1515 gst_event_set_stream_flags (stream_start, stream_flags);
1516 gst_pad_push_event (context->pad, stream_start);
1517 gst_pad_set_caps (context->pad, context->caps);
1520 if (demux->common.global_tags) {
1521 GstEvent *tag_event;
1523 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1524 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1525 GST_DEBUG_OBJECT (context->pad, "Sending global_tags %p: %" GST_PTR_FORMAT,
1526 demux->common.global_tags, demux->common.global_tags);
1529 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1531 gst_pad_push_event (context->pad, tag_event);
1534 if (G_UNLIKELY (context->tags_changed)) {
1535 GST_DEBUG_OBJECT (context->pad, "Sending tags %p: %"
1536 GST_PTR_FORMAT, context->tags, context->tags);
1537 gst_pad_push_event (context->pad,
1538 gst_event_new_tag (gst_tag_list_copy (context->tags)));
1539 context->tags_changed = FALSE;
1542 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1543 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1552 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1555 gboolean res = FALSE;
1556 GstMatroskaTrackContext *context = NULL;
1559 context = gst_pad_get_element_private (pad);
1562 switch (GST_QUERY_TYPE (query)) {
1563 case GST_QUERY_POSITION:
1567 gst_query_parse_position (query, &format, NULL);
1570 if (format == GST_FORMAT_TIME) {
1571 GST_OBJECT_LOCK (demux);
1573 gst_query_set_position (query, GST_FORMAT_TIME,
1574 MAX (context->pos, demux->stream_start_time) -
1575 demux->stream_start_time);
1577 gst_query_set_position (query, GST_FORMAT_TIME,
1578 MAX (demux->common.segment.position, demux->stream_start_time) -
1579 demux->stream_start_time);
1580 GST_OBJECT_UNLOCK (demux);
1581 } else if (format == GST_FORMAT_DEFAULT && context
1582 && context->default_duration) {
1583 GST_OBJECT_LOCK (demux);
1584 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1585 context->pos / context->default_duration);
1586 GST_OBJECT_UNLOCK (demux);
1588 GST_DEBUG_OBJECT (demux,
1589 "only position query in TIME and DEFAULT format is supported");
1595 case GST_QUERY_DURATION:
1599 gst_query_parse_duration (query, &format, NULL);
1602 if (format == GST_FORMAT_TIME) {
1603 GST_OBJECT_LOCK (demux);
1604 gst_query_set_duration (query, GST_FORMAT_TIME,
1605 demux->common.segment.duration);
1606 GST_OBJECT_UNLOCK (demux);
1607 } else if (format == GST_FORMAT_DEFAULT && context
1608 && context->default_duration) {
1609 GST_OBJECT_LOCK (demux);
1610 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1611 demux->common.segment.duration / context->default_duration);
1612 GST_OBJECT_UNLOCK (demux);
1614 GST_DEBUG_OBJECT (demux,
1615 "only duration query in TIME and DEFAULT format is supported");
1621 case GST_QUERY_SEEKING:
1625 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1626 GST_OBJECT_LOCK (demux);
1627 if (fmt == GST_FORMAT_TIME) {
1630 if (demux->streaming) {
1631 /* assuming we'll be able to get an index ... */
1632 seekable = demux->seekable;
1637 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1638 0, demux->common.segment.duration);
1641 GST_OBJECT_UNLOCK (demux);
1644 case GST_QUERY_SEGMENT:
1649 format = demux->common.segment.format;
1652 gst_segment_to_stream_time (&demux->common.segment, format,
1653 demux->common.segment.start);
1654 if ((stop = demux->common.segment.stop) == -1)
1655 stop = demux->common.segment.duration;
1658 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1660 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1667 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1670 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1679 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1681 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1685 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1688 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1690 return gst_matroska_demux_query (demux, pad, query);
1693 /* returns FALSE if there are no pads to deliver event to,
1694 * otherwise TRUE (whatever the outcome of event sending),
1695 * takes ownership of the passed event! */
1697 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1699 gboolean ret = FALSE;
1702 g_return_val_if_fail (event != NULL, FALSE);
1704 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1705 GST_EVENT_TYPE_NAME (event));
1707 g_assert (demux->common.src->len == demux->common.num_streams);
1708 for (i = 0; i < demux->common.src->len; i++) {
1709 GstMatroskaTrackContext *stream;
1711 stream = g_ptr_array_index (demux->common.src, i);
1712 gst_event_ref (event);
1713 gst_pad_push_event (stream->pad, event);
1717 gst_event_unref (event);
1722 gst_matroska_demux_send_tags (GstMatroskaDemux * demux)
1726 if (G_UNLIKELY (demux->common.global_tags_changed)) {
1727 GstEvent *tag_event;
1728 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1729 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1730 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1731 demux->common.global_tags, demux->common.global_tags);
1734 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1736 for (i = 0; i < demux->common.src->len; i++) {
1737 GstMatroskaTrackContext *stream;
1739 stream = g_ptr_array_index (demux->common.src, i);
1740 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1743 gst_event_unref (tag_event);
1744 demux->common.global_tags_changed = FALSE;
1747 g_assert (demux->common.src->len == demux->common.num_streams);
1748 for (i = 0; i < demux->common.src->len; i++) {
1749 GstMatroskaTrackContext *stream;
1751 stream = g_ptr_array_index (demux->common.src, i);
1753 if (G_UNLIKELY (stream->tags_changed)) {
1754 GST_DEBUG_OBJECT (demux, "Sending tags %p for pad %s:%s : %"
1755 GST_PTR_FORMAT, stream->tags,
1756 GST_DEBUG_PAD_NAME (stream->pad), stream->tags);
1757 gst_pad_push_event (stream->pad,
1758 gst_event_new_tag (gst_tag_list_copy (stream->tags)));
1759 stream->tags_changed = FALSE;
1765 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1767 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1770 g_return_val_if_fail (event != NULL, FALSE);
1772 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1773 /* no seeking until we are (safely) ready */
1774 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
1775 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
1776 gst_event_unref (event);
1779 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1781 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1782 GST_EVENT_TYPE_NAME (event));
1785 gst_event_unref (event);
1790 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1791 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1795 GST_OBJECT_LOCK (demux);
1798 /* seek (relative to matroska segment) */
1799 /* position might be invalid; will error when streaming resumes ... */
1800 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1801 demux->next_cluster_offset = 0;
1803 GST_DEBUG_OBJECT (demux,
1804 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1805 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1806 entry->block, GST_TIME_ARGS (entry->time));
1808 /* update the time */
1809 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1810 gst_flow_combiner_reset (demux->flowcombiner);
1811 demux->common.segment.position = entry->time;
1812 demux->seek_block = entry->block;
1813 demux->seek_first = TRUE;
1814 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1817 for (i = 0; i < demux->common.src->len; i++) {
1818 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1821 stream->to_offset = G_MAXINT64;
1823 if (stream->from_offset != -1)
1824 stream->to_offset = stream->from_offset;
1826 stream->from_offset = -1;
1827 stream->from_time = GST_CLOCK_TIME_NONE;
1830 GST_OBJECT_UNLOCK (demux);
1836 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1846 /* searches for a cluster start from @pos,
1847 * return GST_FLOW_OK and cluster position in @pos if found */
1848 static GstFlowReturn
1849 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos,
1852 gint64 newpos = *pos;
1854 GstFlowReturn ret = GST_FLOW_OK;
1855 const guint chunk = 128 * 1024;
1856 GstBuffer *buf = NULL;
1858 gpointer data = NULL;
1863 gint64 oldpos, oldlength;
1865 orig_offset = demux->common.offset;
1867 GST_LOG_OBJECT (demux, "searching cluster %s offset %" G_GINT64_FORMAT,
1868 forward ? "following" : "preceding", *pos);
1870 if (demux->clusters) {
1873 cpos = gst_util_array_binary_search (demux->clusters->data,
1874 demux->clusters->len, sizeof (gint64),
1875 (GCompareDataFunc) gst_matroska_cluster_compare,
1876 forward ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE, pos, NULL);
1879 GST_DEBUG_OBJECT (demux,
1880 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1881 demux->common.offset = *cpos;
1882 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1883 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1884 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1891 /* read in at newpos and scan for ebml cluster id */
1892 oldpos = oldlength = -1;
1894 GstByteReader reader;
1896 guint toread = chunk;
1899 /* never read beyond the requested target */
1900 if (G_UNLIKELY (newpos < chunk)) {
1908 gst_buffer_unmap (buf, &map);
1909 gst_buffer_unref (buf);
1912 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, toread, &buf);
1913 if (ret != GST_FLOW_OK)
1915 GST_DEBUG_OBJECT (demux,
1916 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1917 gst_buffer_get_size (buf), newpos);
1918 gst_buffer_map (buf, &map, GST_MAP_READ);
1921 if (oldpos == newpos && oldlength == map.size) {
1922 GST_ERROR_OBJECT (demux, "Stuck at same position");
1923 ret = GST_FLOW_ERROR;
1927 oldlength = map.size;
1930 gst_byte_reader_init (&reader, data, size);
1933 gint found = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1934 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1936 cluster_pos = found;
1939 /* need last occurrence when searching backwards */
1941 cluster_pos = gst_byte_reader_get_pos (&reader) + found;
1942 gst_byte_reader_skip (&reader, found + 4);
1948 if (cluster_pos >= 0) {
1949 newpos += cluster_pos;
1950 GST_DEBUG_OBJECT (demux,
1951 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1952 /* extra checks whether we really sync'ed to a cluster:
1953 * - either it is the first and only cluster
1954 * - either there is a cluster after this one
1955 * - either cluster length is undefined
1957 /* ok if first cluster (there may not a subsequent one) */
1958 if (newpos == demux->first_cluster_offset) {
1959 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
1962 demux->common.offset = newpos;
1963 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1964 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1965 if (ret != GST_FLOW_OK) {
1966 GST_DEBUG_OBJECT (demux, "need more data -> continue");
1969 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1970 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1972 /* ok if undefined length or first cluster */
1973 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
1974 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
1978 demux->common.offset += length + needed;
1979 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1980 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1981 if (ret != GST_FLOW_OK)
1983 GST_DEBUG_OBJECT (demux, "next element is %scluster",
1984 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1985 if (id == GST_MATROSKA_ID_CLUSTER)
1991 /* partial cluster id may have been in tail of buffer */
1993 forward ? MAX (gst_byte_reader_get_remaining (&reader), 4) - 3 : 3;
1998 gst_buffer_unmap (buf, &map);
1999 gst_buffer_unref (buf);
2004 demux->common.offset = orig_offset;
2009 /* bisect and scan through file for cluster starting before @time,
2010 * returns fake index entry with corresponding info on cluster */
2011 static GstMatroskaIndex *
2012 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
2014 GstMatroskaIndex *entry = NULL;
2015 GstMatroskaReadState current_state;
2016 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
2018 gint64 opos, newpos, current_offset;
2019 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
2020 gint64 apos, maxpos;
2021 guint64 cluster_size = 0;
2027 /* estimate new position, resync using cluster ebml id,
2028 * and bisect further or scan forward to appropriate cluster */
2030 /* store some current state */
2031 current_state = demux->common.state;
2032 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
2034 current_cluster_offset = demux->cluster_offset;
2035 current_cluster_time = demux->cluster_time;
2036 current_offset = demux->common.offset;
2038 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
2040 /* estimate using start and last known cluster */
2041 GST_OBJECT_LOCK (demux);
2042 apos = demux->first_cluster_offset;
2043 atime = demux->stream_start_time;
2044 opos = demux->last_cluster_offset;
2045 otime = demux->stream_last_time;
2046 GST_OBJECT_UNLOCK (demux);
2049 time = MAX (time, atime);
2050 otime = MAX (otime, atime);
2051 opos = MAX (opos, apos);
2053 maxpos = gst_matroska_read_common_get_length (&demux->common);
2058 * apos always refer to a cluster before target time;
2059 * opos may or may not be after target time, but if it is once so,
2060 * then also in next iteration
2064 GST_LOG_OBJECT (demux,
2065 "apos: %" G_GUINT64_FORMAT ", atime: %" GST_TIME_FORMAT ", %"
2066 GST_TIME_FORMAT " in stream time, "
2067 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
2068 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
2069 GST_TIME_FORMAT, apos, GST_TIME_ARGS (atime),
2070 GST_TIME_ARGS (atime - demux->stream_start_time), opos,
2071 GST_TIME_ARGS (otime), GST_TIME_ARGS (otime - demux->stream_start_time),
2072 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
2074 g_assert (atime <= otime);
2075 g_assert (apos <= opos);
2076 if (time == GST_CLOCK_TIME_NONE) {
2077 GST_DEBUG_OBJECT (demux, "searching last cluster");
2080 GST_DEBUG_OBJECT (demux, "unknown file size; bailing out");
2083 } else if (otime <= atime) {
2087 gst_util_uint64_scale (opos - apos, time - atime, otime - atime);
2088 if (maxpos != -1 && newpos > maxpos)
2092 GST_DEBUG_OBJECT (demux,
2093 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
2094 GST_TIME_ARGS (time), newpos);
2096 /* search backwards */
2097 if (newpos > apos) {
2098 ret = gst_matroska_demux_search_cluster (demux, &newpos, FALSE);
2099 if (ret != GST_FLOW_OK)
2103 /* then start scanning and parsing for cluster time,
2104 * re-estimate if possible, otherwise next cluster and so on */
2105 /* note that each re-estimate is entered with a change in apos or opos,
2106 * avoiding infinite loop */
2107 demux->common.offset = newpos;
2108 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
2110 prev_cluster_time = GST_CLOCK_TIME_NONE;
2112 /* peek and parse some elements */
2113 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2114 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2115 if (ret != GST_FLOW_OK)
2117 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2118 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
2120 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
2121 if (ret != GST_FLOW_OK)
2124 if (id == GST_MATROSKA_ID_CLUSTER) {
2125 cluster_time = GST_CLOCK_TIME_NONE;
2126 if (length == G_MAXUINT64)
2129 cluster_size = length + needed;
2131 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
2132 cluster_time == GST_CLOCK_TIME_NONE) {
2133 cluster_time = demux->cluster_time * demux->common.time_scale;
2134 cluster_offset = demux->cluster_offset;
2135 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
2136 " with time %" GST_TIME_FORMAT, cluster_offset,
2137 GST_TIME_ARGS (cluster_time));
2138 if (time == GST_CLOCK_TIME_NONE) {
2139 GST_DEBUG_OBJECT (demux, "found last cluster");
2140 prev_cluster_time = cluster_time;
2141 prev_cluster_offset = cluster_offset;
2144 if (cluster_time > time) {
2145 GST_DEBUG_OBJECT (demux, "overshot target");
2146 /* cluster overshoots */
2147 if (cluster_offset == demux->first_cluster_offset) {
2148 /* but no prev one */
2149 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
2150 prev_cluster_time = cluster_time;
2151 prev_cluster_offset = cluster_offset;
2154 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
2155 /* prev cluster did not overshoot, so prev cluster is target */
2158 /* re-estimate using this new position info */
2159 opos = cluster_offset;
2160 otime = cluster_time;
2164 /* cluster undershoots */
2165 GST_DEBUG_OBJECT (demux, "undershot target");
2166 /* ok if close enough */
2167 if (GST_CLOCK_DIFF (cluster_time, time) < 5 * GST_SECOND) {
2168 GST_DEBUG_OBJECT (demux, "target close enough");
2169 prev_cluster_time = cluster_time;
2170 prev_cluster_offset = cluster_offset;
2174 /* we are in between atime and otime => can bisect if worthwhile */
2175 if (prev_cluster_time != GST_CLOCK_TIME_NONE &&
2176 cluster_time > prev_cluster_time &&
2177 (GST_CLOCK_DIFF (prev_cluster_time, cluster_time) * 10 <
2178 GST_CLOCK_DIFF (cluster_time, time))) {
2179 /* we moved at least one cluster forward,
2180 * and it looks like target is still far away,
2181 * let's estimate again */
2182 GST_DEBUG_OBJECT (demux, "bisecting with new apos");
2183 apos = cluster_offset;
2184 atime = cluster_time;
2188 /* cluster undershoots, goto next one */
2189 prev_cluster_time = cluster_time;
2190 prev_cluster_offset = cluster_offset;
2191 /* skip cluster if length is defined,
2192 * otherwise will be skippingly parsed into */
2194 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
2195 demux->common.offset = cluster_offset + cluster_size;
2196 demux->cluster_time = GST_CLOCK_TIME_NONE;
2198 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
2205 if (ret == GST_FLOW_EOS) {
2206 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
2212 entry = g_new0 (GstMatroskaIndex, 1);
2213 entry->time = prev_cluster_time;
2214 entry->pos = prev_cluster_offset - demux->common.ebml_segment_start;
2215 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
2216 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
2220 /* restore some state */
2221 demux->cluster_offset = current_cluster_offset;
2222 demux->cluster_time = current_cluster_time;
2223 demux->common.offset = current_offset;
2224 demux->common.state = current_state;
2230 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
2231 GstPad * pad, GstEvent * event)
2233 GstMatroskaIndex *entry = NULL;
2234 GstMatroskaIndex scan_entry;
2236 GstSeekType cur_type, stop_type;
2238 gboolean flush, keyunit, before, after, snap_next;
2241 GstMatroskaTrackContext *track = NULL;
2242 GstSegment seeksegment = { 0, };
2243 gboolean update = TRUE;
2244 gboolean pad_locked = FALSE;
2246 GstSearchMode snap_dir;
2248 g_return_val_if_fail (event != NULL, FALSE);
2251 track = gst_pad_get_element_private (pad);
2253 GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
2255 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2257 seqnum = gst_event_get_seqnum (event);
2259 /* we can only seek on time */
2260 if (format != GST_FORMAT_TIME) {
2261 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2265 /* copy segment, we need this because we still need the old
2266 * segment when we close the current segment. */
2267 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
2269 /* pull mode without index means that the actual duration is not known,
2270 * we might be playing a file that's still being recorded
2271 * so, invalidate our current duration, which is only a moving target,
2272 * and should not be used to clamp anything */
2273 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
2274 seeksegment.duration = GST_CLOCK_TIME_NONE;
2277 GST_DEBUG_OBJECT (demux, "configuring seek");
2278 /* Subtract stream_start_time so we always seek on a segment
2280 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2281 seeksegment.start -= demux->stream_start_time;
2282 seeksegment.position -= demux->stream_start_time;
2283 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2284 seeksegment.stop -= demux->stream_start_time;
2286 seeksegment.stop = seeksegment.duration;
2289 gst_segment_do_seek (&seeksegment, rate, format, flags,
2290 cur_type, cur, stop_type, stop, &update);
2292 /* Restore the clip timestamp offset */
2293 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2294 seeksegment.position += demux->stream_start_time;
2295 seeksegment.start += demux->stream_start_time;
2296 if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2297 seeksegment.stop = seeksegment.duration;
2298 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2299 seeksegment.stop += demux->stream_start_time;
2302 /* restore segment duration (if any effect),
2303 * would be determined again when parsing, but anyway ... */
2304 seeksegment.duration = demux->common.segment.duration;
2306 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2307 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2308 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
2309 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
2311 /* always do full update if flushing,
2312 * otherwise problems might arise downstream with missing keyframes etc */
2313 update = update || flush;
2315 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2317 /* check sanity before we start flushing and all that */
2318 snap_next = after && !before;
2319 if (seeksegment.rate < 0)
2320 snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
2322 snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
2324 GST_OBJECT_LOCK (demux);
2325 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2326 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2327 seeksegment.position, &demux->seek_index, &demux->seek_entry,
2328 snap_dir)) == NULL) {
2329 /* pull mode without index can scan later on */
2330 if (demux->streaming) {
2331 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2332 GST_OBJECT_UNLOCK (demux);
2334 } else if (rate < 0.0) {
2335 /* FIXME: We should build an index during playback or when scanning
2336 * that can be used here. The reverse playback code requires seek_index
2337 * and seek_entry to be set!
2339 GST_DEBUG_OBJECT (demux,
2340 "No matching seek entry in index, needed for reverse playback");
2341 GST_OBJECT_UNLOCK (demux);
2345 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2346 GST_OBJECT_UNLOCK (demux);
2349 /* only have to update some segment,
2350 * but also still have to honour flush and so on */
2351 GST_DEBUG_OBJECT (demux, "... no update");
2352 /* bad goto, bad ... */
2356 if (demux->streaming)
2361 GstEvent *flush_event = gst_event_new_flush_start ();
2362 gst_event_set_seqnum (flush_event, seqnum);
2363 GST_DEBUG_OBJECT (demux, "Starting flush");
2364 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2365 gst_matroska_demux_send_event (demux, flush_event);
2367 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2368 gst_pad_pause_task (demux->common.sinkpad);
2372 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2377 /* now grab the stream lock so that streaming cannot continue, for
2378 * non flushing seeks when the element is in PAUSED this could block
2380 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2381 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2384 /* pull mode without index can do some scanning */
2385 if (!demux->streaming && !entry) {
2386 GstEvent *flush_event;
2388 /* need to stop flushing upstream as we need it next */
2390 flush_event = gst_event_new_flush_stop (TRUE);
2391 gst_event_set_seqnum (flush_event, seqnum);
2392 gst_pad_push_event (demux->common.sinkpad, flush_event);
2394 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2395 /* keep local copy */
2397 scan_entry = *entry;
2399 entry = &scan_entry;
2401 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2403 flush_event = gst_event_new_flush_stop (TRUE);
2404 gst_event_set_seqnum (flush_event, seqnum);
2405 gst_matroska_demux_send_event (demux, flush_event);
2412 if (keyunit && seeksegment.rate > 0) {
2413 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2414 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2415 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2416 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2417 seeksegment.position = seeksegment.start;
2418 seeksegment.time = seeksegment.start - demux->stream_start_time;
2419 } else if (keyunit) {
2420 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment stop from %"
2421 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2422 GST_TIME_ARGS (seeksegment.stop), GST_TIME_ARGS (entry->time));
2423 seeksegment.stop = MAX (entry->time, demux->stream_start_time);
2424 seeksegment.position = seeksegment.stop;
2427 if (demux->streaming) {
2428 GST_OBJECT_LOCK (demux);
2429 /* track real position we should start at */
2430 GST_DEBUG_OBJECT (demux, "storing segment start");
2431 demux->requested_seek_time = seeksegment.position;
2432 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2433 GST_OBJECT_UNLOCK (demux);
2434 /* need to seek to cluster start to pick up cluster time */
2435 /* upstream takes care of flushing and all that
2436 * ... and newsegment event handling takes care of the rest */
2437 return perform_seek_to_offset (demux, rate,
2438 entry->pos + demux->common.ebml_segment_start, seqnum, flags);
2443 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2444 gst_event_set_seqnum (flush_event, seqnum);
2445 GST_DEBUG_OBJECT (demux, "Stopping flush");
2446 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2447 gst_matroska_demux_send_event (demux, flush_event);
2450 GST_OBJECT_LOCK (demux);
2451 /* now update the real segment info */
2452 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2453 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2454 GST_OBJECT_UNLOCK (demux);
2456 /* update some (segment) state */
2457 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2460 /* notify start of new segment */
2461 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2464 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2465 GST_FORMAT_TIME, demux->common.segment.start);
2466 gst_message_set_seqnum (msg, seqnum);
2467 gst_element_post_message (GST_ELEMENT (demux), msg);
2470 GST_OBJECT_LOCK (demux);
2471 if (demux->new_segment)
2472 gst_event_unref (demux->new_segment);
2474 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2475 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2476 gst_event_set_seqnum (demux->new_segment, seqnum);
2477 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2478 demux->to_time = demux->common.segment.position;
2480 demux->to_time = GST_CLOCK_TIME_NONE;
2481 demux->segment_seqnum = seqnum;
2482 GST_OBJECT_UNLOCK (demux);
2484 /* restart our task since it might have been stopped when we did the
2486 gst_pad_start_task (demux->common.sinkpad,
2487 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2489 /* streaming can continue now */
2491 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2499 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2501 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2507 * Handle whether we can perform the seek event or if we have to let the chain
2508 * function handle seeks to build the seek indexes first.
2511 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2515 GstSeekType cur_type, stop_type;
2520 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2525 /* we can only seek on time */
2526 if (format != GST_FORMAT_TIME) {
2527 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2531 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2532 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2536 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2537 GST_DEBUG_OBJECT (demux,
2538 "Non-flushing seek not supported in streaming mode");
2542 if (flags & GST_SEEK_FLAG_SEGMENT) {
2543 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2547 /* check for having parsed index already */
2548 if (!demux->common.index_parsed) {
2549 gboolean building_index;
2552 if (!demux->index_offset) {
2553 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2557 GST_OBJECT_LOCK (demux);
2558 /* handle the seek event in the chain function */
2559 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2560 /* no more seek can be issued until state reset to _DATA */
2562 /* copy the event */
2563 if (demux->seek_event)
2564 gst_event_unref (demux->seek_event);
2565 demux->seek_event = gst_event_ref (event);
2567 /* set the building_index flag so that only one thread can setup the
2568 * structures for index seeking. */
2569 building_index = demux->building_index;
2570 if (!building_index) {
2571 demux->building_index = TRUE;
2572 offset = demux->index_offset;
2574 GST_OBJECT_UNLOCK (demux);
2576 if (!building_index) {
2577 /* seek to the first subindex or legacy index */
2578 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2579 return perform_seek_to_offset (demux, rate, offset,
2580 gst_event_get_seqnum (event), GST_SEEK_FLAG_NONE);
2583 /* well, we are handling it already */
2587 /* delegate to tweaked regular seek */
2588 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2592 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2595 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2596 gboolean res = TRUE;
2598 switch (GST_EVENT_TYPE (event)) {
2599 case GST_EVENT_SEEK:
2600 /* no seeking until we are (safely) ready */
2601 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2602 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2603 gst_event_unref (event);
2608 guint32 seqnum = gst_event_get_seqnum (event);
2609 if (seqnum == demux->segment_seqnum) {
2610 GST_LOG_OBJECT (pad,
2611 "Drop duplicated SEEK event seqnum %" G_GUINT32_FORMAT, seqnum);
2612 gst_event_unref (event);
2617 if (!demux->streaming)
2618 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2620 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2621 gst_event_unref (event);
2626 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2627 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2628 GstMatroskaTrackVideoContext *videocontext =
2629 (GstMatroskaTrackVideoContext *) context;
2631 GstClockTimeDiff diff;
2632 GstClockTime timestamp;
2634 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2636 GST_OBJECT_LOCK (demux);
2637 videocontext->earliest_time = timestamp + diff;
2638 GST_OBJECT_UNLOCK (demux);
2641 gst_event_unref (event);
2645 case GST_EVENT_TOC_SELECT:
2648 GstTocEntry *entry = NULL;
2649 GstEvent *seek_event;
2652 if (!demux->common.toc) {
2653 GST_DEBUG_OBJECT (demux, "no TOC to select");
2656 gst_event_parse_toc_select (event, &uid);
2658 GST_OBJECT_LOCK (demux);
2659 entry = gst_toc_find_entry (demux->common.toc, uid);
2660 if (entry == NULL) {
2661 GST_OBJECT_UNLOCK (demux);
2662 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2665 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2666 GST_OBJECT_UNLOCK (demux);
2667 seek_event = gst_event_new_seek (1.0,
2669 GST_SEEK_FLAG_FLUSH,
2670 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
2671 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
2672 gst_event_unref (seek_event);
2676 GST_WARNING_OBJECT (demux, "received empty TOC select event");
2680 gst_event_unref (event);
2684 /* events we don't need to handle */
2685 case GST_EVENT_NAVIGATION:
2686 gst_event_unref (event);
2690 case GST_EVENT_LATENCY:
2692 res = gst_pad_push_event (demux->common.sinkpad, event);
2699 static GstFlowReturn
2700 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
2702 GstFlowReturn ret = GST_FLOW_EOS;
2703 gboolean done = TRUE;
2706 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
2707 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
2710 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
2712 if (!demux->seek_entry) {
2713 GST_DEBUG_OBJECT (demux, "no earlier index entry");
2717 for (i = 0; i < demux->common.src->len; i++) {
2718 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
2720 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
2721 ", stream %d at %" GST_TIME_FORMAT,
2722 GST_TIME_ARGS (demux->common.segment.start), stream->index,
2723 GST_TIME_ARGS (stream->from_time));
2724 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
2725 if (stream->from_time > demux->common.segment.start) {
2726 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
2730 /* nothing pushed for this stream;
2731 * likely seek entry did not start at keyframe, so all was skipped.
2732 * So we need an earlier entry */
2738 GstMatroskaIndex *entry;
2740 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
2741 --demux->seek_entry);
2742 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
2752 static GstFlowReturn
2753 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
2755 GstFlowReturn ret = GST_FLOW_OK;
2758 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
2760 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2761 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2765 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2766 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2770 /* one track within the "all-tracks" header */
2771 case GST_MATROSKA_ID_TRACKENTRY:
2772 ret = gst_matroska_demux_add_stream (demux, ebml);
2776 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
2781 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
2783 demux->tracks_parsed = TRUE;
2789 * Read signed/unsigned "EBML" numbers.
2790 * Return: number of bytes processed.
2794 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
2796 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
2804 while (read <= 8 && !(total & len_mask)) {
2811 if ((total &= (len_mask - 1)) == len_mask - 1)
2816 if (data[n] == 0xff)
2818 total = (total << 8) | data[n];
2822 if (read == num_ffs && total != 0)
2831 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
2836 /* read as unsigned number first */
2837 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
2841 if (unum == G_MAXUINT64)
2844 *num = unum - ((1 << ((7 * res) - 1)) - 1);
2850 * Mostly used for subtitles. We add void filler data for each
2851 * lagging stream to make sure we don't deadlock.
2855 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
2857 GstClockTime gap_threshold;
2860 GST_OBJECT_LOCK (demux);
2862 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
2863 GST_TIME_ARGS (demux->common.segment.position));
2865 g_assert (demux->common.num_streams == demux->common.src->len);
2866 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
2867 GstMatroskaTrackContext *context;
2869 context = g_ptr_array_index (demux->common.src, stream_nr);
2871 GST_LOG_OBJECT (demux,
2872 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
2873 GST_TIME_ARGS (context->pos));
2875 /* Only send gap events on non-subtitle streams if lagging way behind.
2876 * The 0.5 second threshold for subtitle streams is also quite random. */
2877 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
2878 gap_threshold = GST_SECOND / 2;
2880 gap_threshold = 3 * GST_SECOND;
2882 /* Lag need only be considered if we have advanced into requested segment */
2883 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
2884 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
2885 demux->common.segment.position > demux->common.segment.start &&
2886 context->pos + gap_threshold < demux->common.segment.position) {
2889 guint64 start = context->pos;
2890 guint64 stop = demux->common.segment.position - gap_threshold;
2892 GST_DEBUG_OBJECT (demux,
2893 "Synchronizing stream %d with other by advancing time from %"
2894 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
2895 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2897 context->pos = stop;
2899 event = gst_event_new_gap (start, stop - start);
2900 GST_OBJECT_UNLOCK (demux);
2901 gst_pad_push_event (context->pad, event);
2902 GST_OBJECT_LOCK (demux);
2906 GST_OBJECT_UNLOCK (demux);
2909 static GstFlowReturn
2910 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
2911 GstMatroskaTrackContext * stream)
2913 GstFlowReturn ret = GST_FLOW_OK;
2916 num = gst_buffer_list_length (stream->stream_headers);
2917 for (i = 0; i < num; ++i) {
2920 buf = gst_buffer_list_get (stream->stream_headers, i);
2921 buf = gst_buffer_copy (buf);
2923 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2925 if (stream->set_discont) {
2926 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2927 stream->set_discont = FALSE;
2929 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
2932 /* push out all headers in one go and use last flow return */
2933 ret = gst_pad_push (stream->pad, buf);
2936 /* don't need these any longer */
2937 gst_buffer_list_unref (stream->stream_headers);
2938 stream->stream_headers = NULL;
2941 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
2947 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
2948 GstMatroskaTrackContext * stream)
2952 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
2954 if (!stream->codec_priv)
2957 /* ideally, VobSub private data should be parsed and stored more convenient
2958 * elsewhere, but for now, only interested in a small part */
2960 /* make sure we have terminating 0 */
2961 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
2963 /* just locate and parse palette part */
2964 start = strstr (buf, "palette:");
2969 guint8 r, g, b, y, u, v;
2972 while (g_ascii_isspace (*start))
2974 for (i = 0; i < 16; i++) {
2975 if (sscanf (start, "%06x", &col) != 1)
2978 while ((*start == ',') || g_ascii_isspace (*start))
2980 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
2981 r = (col >> 16) & 0xff;
2982 g = (col >> 8) & 0xff;
2984 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
2986 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
2987 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
2988 clut[i] = (y << 16) | (u << 8) | v;
2991 /* got them all without problems; build and send event */
2995 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
2996 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
2997 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
2998 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
2999 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
3000 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
3001 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
3002 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
3003 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
3004 G_TYPE_INT, clut[15], NULL);
3006 gst_pad_push_event (stream->pad,
3007 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
3014 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
3018 g_assert (demux->common.num_streams == demux->common.src->len);
3019 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
3020 GstMatroskaTrackContext *stream;
3022 stream = g_ptr_array_index (demux->common.src, stream_nr);
3024 if (stream->send_stream_headers) {
3025 if (stream->stream_headers != NULL) {
3026 gst_matroska_demux_push_stream_headers (demux, stream);
3028 /* FIXME: perhaps we can just disable and skip this stream then */
3029 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
3030 ("Failed to extract stream headers from codec private data"));
3032 stream->send_stream_headers = FALSE;
3035 if (stream->send_dvd_event) {
3036 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
3037 /* FIXME: should we send this event again after (flushing) seek ? */
3038 stream->send_dvd_event = FALSE;
3044 static GstFlowReturn
3045 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
3046 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3049 guint seq_header_len;
3050 guint32 header, tmp;
3052 if (stream->codec_state) {
3053 seq_header = stream->codec_state;
3054 seq_header_len = stream->codec_state_size;
3055 } else if (stream->codec_priv) {
3056 seq_header = stream->codec_priv;
3057 seq_header_len = stream->codec_priv_size;
3062 /* Sequence header only needed for keyframes */
3063 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
3066 if (gst_buffer_get_size (*buf) < 4)
3069 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
3070 header = GUINT32_FROM_BE (tmp);
3072 /* Sequence start code, if not found prepend */
3073 if (header != 0x000001b3) {
3076 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
3078 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
3081 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
3082 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
3083 gst_buffer_get_size (*buf));
3085 gst_buffer_unref (*buf);
3092 static GstFlowReturn
3093 gst_matroska_demux_add_wvpk_header (GstElement * element,
3094 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3096 GstMatroskaTrackAudioContext *audiocontext =
3097 (GstMatroskaTrackAudioContext *) stream;
3098 GstBuffer *newbuf = NULL;
3099 GstMapInfo map, outmap;
3100 guint8 *buf_data, *data;
3108 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
3111 wvh.total_samples = -1;
3112 wvh.block_index = audiocontext->wvpk_block_index;
3114 if (audiocontext->channels <= 2) {
3115 guint32 block_samples, tmp;
3116 gsize size = gst_buffer_get_size (*buf);
3118 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
3119 block_samples = GUINT32_FROM_LE (tmp);
3120 /* we need to reconstruct the header of the wavpack block */
3122 /* -20 because ck_size is the size of the wavpack block -8
3123 * and lace_size is the size of the wavpack block + 12
3124 * (the three guint32 of the header that already are in the buffer) */
3125 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
3127 /* block_samples, flags and crc are already in the buffer */
3128 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
3130 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3136 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
3137 GST_WRITE_UINT16_LE (data + 8, wvh.version);
3138 GST_WRITE_UINT8 (data + 10, wvh.track_no);
3139 GST_WRITE_UINT8 (data + 11, wvh.index_no);
3140 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
3141 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
3142 gst_buffer_unmap (newbuf, &outmap);
3144 /* Append data from buf: */
3145 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
3146 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
3148 gst_buffer_unref (*buf);
3150 audiocontext->wvpk_block_index += block_samples;
3152 guint8 *outdata = NULL;
3154 gsize buf_size, size, out_size = 0;
3155 guint32 block_samples, flags, crc, blocksize;
3157 gst_buffer_map (*buf, &map, GST_MAP_READ);
3158 buf_data = map.data;
3159 buf_size = map.size;
3162 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
3163 gst_buffer_unmap (*buf, &map);
3164 return GST_FLOW_ERROR;
3170 block_samples = GST_READ_UINT32_LE (data);
3175 flags = GST_READ_UINT32_LE (data);
3178 crc = GST_READ_UINT32_LE (data);
3181 blocksize = GST_READ_UINT32_LE (data);
3185 if (blocksize == 0 || size < blocksize)
3188 g_assert ((newbuf == NULL) == (outdata == NULL));
3190 if (newbuf == NULL) {
3191 out_size = sizeof (Wavpack4Header) + blocksize;
3192 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
3194 gst_buffer_copy_into (newbuf, *buf,
3195 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
3198 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3199 outdata = outmap.data;
3201 gst_buffer_unmap (newbuf, &outmap);
3202 out_size += sizeof (Wavpack4Header) + blocksize;
3203 gst_buffer_set_size (newbuf, out_size);
3204 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3205 outdata = outmap.data;
3208 outdata[outpos] = 'w';
3209 outdata[outpos + 1] = 'v';
3210 outdata[outpos + 2] = 'p';
3211 outdata[outpos + 3] = 'k';
3214 GST_WRITE_UINT32_LE (outdata + outpos,
3215 blocksize + sizeof (Wavpack4Header) - 8);
3216 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
3217 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
3218 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
3219 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
3220 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
3221 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
3222 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
3223 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
3226 memmove (outdata + outpos, data, blocksize);
3227 outpos += blocksize;
3231 gst_buffer_unmap (*buf, &map);
3232 gst_buffer_unref (*buf);
3235 gst_buffer_unmap (newbuf, &outmap);
3238 audiocontext->wvpk_block_index += block_samples;
3244 static GstFlowReturn
3245 gst_matroska_demux_add_prores_header (GstElement * element,
3246 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3248 GstBuffer *newbuf = gst_buffer_new_allocate (NULL, 8, NULL);
3252 if (!gst_buffer_map (newbuf, &map, GST_MAP_WRITE)) {
3253 GST_ERROR ("Failed to map newly allocated buffer");
3254 return GST_FLOW_ERROR;
3257 frame_size = gst_buffer_get_size (*buf);
3259 GST_WRITE_UINT32_BE (map.data, frame_size);
3265 gst_buffer_unmap (newbuf, &map);
3266 *buf = gst_buffer_append (newbuf, *buf);
3271 /* @text must be null-terminated */
3273 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
3278 g_return_val_if_fail (text != NULL, FALSE);
3280 /* yes, this might all lead to false positives ... */
3281 tag = (gchar *) text;
3282 while ((tag = strchr (tag, '<'))) {
3284 if (*tag != '\0' && *(tag + 1) == '>') {
3285 /* some common convenience ones */
3286 /* maybe any character will do here ? */
3299 if (strstr (text, "<span"))
3305 static GstFlowReturn
3306 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
3307 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3309 GstMatroskaTrackSubtitleContext *sub_stream;
3310 const gchar *encoding;
3315 gboolean needs_unmap = TRUE;
3317 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3319 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
3322 /* The subtitle buffer we push out should not include a NUL terminator as
3323 * part of the data. */
3324 if (map.data[map.size - 1] == '\0') {
3325 gst_buffer_set_size (*buf, map.size - 1);
3326 gst_buffer_unmap (*buf, &map);
3327 gst_buffer_map (*buf, &map, GST_MAP_READ);
3330 if (!sub_stream->invalid_utf8) {
3331 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
3334 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
3335 " is not valid UTF-8, this is broken according to the matroska"
3336 " specification", stream->num);
3337 sub_stream->invalid_utf8 = TRUE;
3340 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3341 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3342 if (encoding == NULL || *encoding == '\0') {
3343 /* if local encoding is UTF-8 and no encoding specified
3344 * via the environment variable, assume ISO-8859-15 */
3345 if (g_get_charset (&encoding)) {
3346 encoding = "ISO-8859-15";
3351 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3352 (char *) "*", NULL, NULL, &err);
3355 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3356 encoding, err->message);
3360 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3361 encoding = "ISO-8859-15";
3363 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3364 encoding, (char *) "*", NULL, NULL, NULL);
3367 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3368 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3371 utf8 = g_strdup ("invalid subtitle");
3373 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3374 gst_buffer_unmap (*buf, &map);
3375 gst_buffer_copy_into (newbuf, *buf,
3376 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3378 gst_buffer_unref (*buf);
3381 gst_buffer_map (*buf, &map, GST_MAP_READ);
3385 if (sub_stream->check_markup) {
3386 /* caps claim markup text, so we need to escape text,
3387 * except if text is already markup and then needs no further escaping */
3388 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3389 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3391 if (!sub_stream->seen_markup_tag) {
3392 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3394 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3395 gst_buffer_unmap (*buf, &map);
3396 gst_buffer_copy_into (newbuf, *buf,
3397 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3398 GST_BUFFER_COPY_META, 0, -1);
3399 gst_buffer_unref (*buf);
3402 needs_unmap = FALSE;
3407 gst_buffer_unmap (*buf, &map);
3412 static GstFlowReturn
3413 gst_matroska_demux_check_aac (GstElement * element,
3414 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3419 gst_buffer_extract (*buf, 0, data, 2);
3420 size = gst_buffer_get_size (*buf);
3422 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3425 /* tss, ADTS data, remove codec_data
3426 * still assume it is at least parsed */
3427 stream->caps = gst_caps_make_writable (stream->caps);
3428 s = gst_caps_get_structure (stream->caps, 0);
3430 gst_structure_remove_field (s, "codec_data");
3431 gst_pad_set_caps (stream->pad, stream->caps);
3432 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3433 "new caps: %" GST_PTR_FORMAT, stream->caps);
3436 /* disable subsequent checking */
3437 stream->postprocess_frame = NULL;
3443 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3444 GstBuffer * buffer, gsize alignment)
3448 gst_buffer_map (buffer, &map, GST_MAP_READ);
3450 if (map.size < sizeof (guintptr)) {
3451 gst_buffer_unmap (buffer, &map);
3455 if (((guintptr) map.data) & (alignment - 1)) {
3456 GstBuffer *new_buffer;
3457 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3459 new_buffer = gst_buffer_new_allocate (NULL,
3460 gst_buffer_get_size (buffer), ¶ms);
3462 /* Copy data "by hand", so ensure alignment is kept: */
3463 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3465 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3466 GST_DEBUG_OBJECT (demux,
3467 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3470 gst_buffer_unmap (buffer, &map);
3471 gst_buffer_unref (buffer);
3476 gst_buffer_unmap (buffer, &map);
3480 static GstFlowReturn
3481 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3482 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3483 gboolean is_simpleblock)
3485 GstMatroskaTrackContext *stream = NULL;
3486 GstFlowReturn ret = GST_FLOW_OK;
3487 gboolean readblock = FALSE;
3489 guint64 block_duration = -1;
3490 gint64 block_discardpadding = 0;
3491 GstBuffer *buf = NULL;
3493 gint stream_num = -1, n, laces = 0;
3495 gint *lace_size = NULL;
3498 gint64 referenceblock = 0;
3500 GstClockTime buffer_timestamp;
3502 offset = gst_ebml_read_get_offset (ebml);
3504 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3505 if (!is_simpleblock) {
3506 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3510 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3514 /* one block inside the group. Note, block parsing is one
3515 * of the harder things, so this code is a bit complicated.
3516 * See http://www.matroska.org/ for documentation. */
3517 case GST_MATROSKA_ID_SIMPLEBLOCK:
3518 case GST_MATROSKA_ID_BLOCK:
3524 gst_buffer_unmap (buf, &map);
3525 gst_buffer_unref (buf);
3528 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3531 gst_buffer_map (buf, &map, GST_MAP_READ);
3535 /* first byte(s): blocknum */
3536 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3541 /* fetch stream from num */
3542 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3544 if (G_UNLIKELY (size < 3)) {
3545 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
3546 /* non-fatal, try next block(group) */
3549 } else if (G_UNLIKELY (stream_num < 0 ||
3550 stream_num >= demux->common.num_streams)) {
3551 /* let's not give up on a stray invalid track number */
3552 GST_WARNING_OBJECT (demux,
3553 "Invalid stream %d for track number %" G_GUINT64_FORMAT
3554 "; ignoring block", stream_num, num);
3558 stream = g_ptr_array_index (demux->common.src, stream_num);
3560 /* time (relative to cluster time) */
3561 time = ((gint16) GST_READ_UINT16_BE (data));
3564 flags = GST_READ_UINT8 (data);
3568 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
3571 switch ((flags & 0x06) >> 1) {
3572 case 0x0: /* no lacing */
3574 lace_size = g_new (gint, 1);
3575 lace_size[0] = size;
3578 case 0x1: /* xiph lacing */
3579 case 0x2: /* fixed-size lacing */
3580 case 0x3: /* EBML lacing */
3582 goto invalid_lacing;
3583 laces = GST_READ_UINT8 (data) + 1;
3586 lace_size = g_new0 (gint, laces);
3588 switch ((flags & 0x06) >> 1) {
3589 case 0x1: /* xiph lacing */ {
3590 guint temp, total = 0;
3592 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
3595 goto invalid_lacing;
3596 temp = GST_READ_UINT8 (data);
3597 lace_size[n] += temp;
3603 total += lace_size[n];
3605 lace_size[n] = size - total;
3609 case 0x2: /* fixed-size lacing */
3610 for (n = 0; n < laces; n++)
3611 lace_size[n] = size / laces;
3614 case 0x3: /* EBML lacing */ {
3617 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3621 total = lace_size[0] = num;
3622 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
3626 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
3630 lace_size[n] = lace_size[n - 1] + snum;
3631 total += lace_size[n];
3634 lace_size[n] = size - total;
3641 if (ret != GST_FLOW_OK)
3648 case GST_MATROSKA_ID_BLOCKDURATION:{
3649 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
3650 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
3655 case GST_MATROSKA_ID_DISCARDPADDING:{
3656 ret = gst_ebml_read_sint (ebml, &id, &block_discardpadding);
3657 GST_DEBUG_OBJECT (demux, "DiscardPadding: %" GST_STIME_FORMAT,
3658 GST_STIME_ARGS (block_discardpadding));
3662 case GST_MATROSKA_ID_REFERENCEBLOCK:{
3663 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
3664 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
3669 case GST_MATROSKA_ID_CODECSTATE:{
3671 guint64 data_len = 0;
3674 gst_ebml_read_binary (ebml, &id, &data,
3675 &data_len)) != GST_FLOW_OK)
3678 if (G_UNLIKELY (stream == NULL)) {
3679 GST_WARNING_OBJECT (demux,
3680 "Unexpected CodecState subelement - ignoring");
3684 g_free (stream->codec_state);
3685 stream->codec_state = data;
3686 stream->codec_state_size = data_len;
3688 /* Decode if necessary */
3689 if (stream->encodings && stream->encodings->len > 0
3690 && stream->codec_state && stream->codec_state_size > 0) {
3691 if (!gst_matroska_decode_data (stream->encodings,
3692 &stream->codec_state, &stream->codec_state_size,
3693 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
3694 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
3698 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
3699 stream->codec_state_size);
3704 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3708 case GST_MATROSKA_ID_BLOCKVIRTUAL:
3709 case GST_MATROSKA_ID_BLOCKADDITIONS:
3710 case GST_MATROSKA_ID_REFERENCEPRIORITY:
3711 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
3712 case GST_MATROSKA_ID_SLICES:
3713 GST_DEBUG_OBJECT (demux,
3714 "Skipping BlockGroup subelement 0x%x - ignoring", id);
3715 ret = gst_ebml_read_skip (ebml);
3723 /* reading a number or so could have failed */
3724 if (ret != GST_FLOW_OK)
3727 if (ret == GST_FLOW_OK && readblock) {
3728 gboolean invisible_frame = FALSE;
3729 gboolean delta_unit = FALSE;
3730 guint64 duration = 0;
3731 gint64 lace_time = 0;
3733 stream = g_ptr_array_index (demux->common.src, stream_num);
3735 if (cluster_time != GST_CLOCK_TIME_NONE) {
3736 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
3737 * Drop unless the lace contains timestamp 0? */
3738 if (time < 0 && (-time) > cluster_time) {
3741 if (stream->timecodescale == 1.0)
3742 lace_time = (cluster_time + time) * demux->common.time_scale;
3745 gst_util_guint64_to_gdouble ((cluster_time + time) *
3746 demux->common.time_scale) * stream->timecodescale;
3749 lace_time = GST_CLOCK_TIME_NONE;
3752 /* need to refresh segment info ASAP */
3753 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
3754 GstSegment *segment = &demux->common.segment;
3756 GstEvent *segment_event;
3758 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
3759 demux->stream_start_time = lace_time;
3760 GST_DEBUG_OBJECT (demux,
3761 "Setting stream start time to %" GST_TIME_FORMAT,
3762 GST_TIME_ARGS (lace_time));
3764 clace_time = MAX (lace_time, demux->stream_start_time);
3765 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3766 demux->common.segment.position != 0) {
3767 GST_DEBUG_OBJECT (demux,
3768 "using stored seek position %" GST_TIME_FORMAT,
3769 GST_TIME_ARGS (demux->common.segment.position));
3770 clace_time = demux->common.segment.position;
3771 segment->position = GST_CLOCK_TIME_NONE;
3773 segment->start = clace_time;
3774 segment->stop = GST_CLOCK_TIME_NONE;
3775 segment->time = segment->start - demux->stream_start_time;
3776 segment->position = segment->start - demux->stream_start_time;
3777 GST_DEBUG_OBJECT (demux,
3778 "generated segment starting at %" GST_TIME_FORMAT ": %"
3779 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
3780 /* now convey our segment notion downstream */
3781 segment_event = gst_event_new_segment (segment);
3782 if (demux->segment_seqnum)
3783 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
3784 gst_matroska_demux_send_event (demux, segment_event);
3785 demux->need_segment = FALSE;
3786 demux->segment_seqnum = 0;
3789 /* send pending codec data headers for all streams,
3790 * before we perform sync across all streams */
3791 gst_matroska_demux_push_codec_data_all (demux);
3793 if (block_duration != -1) {
3794 if (stream->timecodescale == 1.0)
3795 duration = gst_util_uint64_scale (block_duration,
3796 demux->common.time_scale, 1);
3799 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
3800 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
3801 1)) * stream->timecodescale);
3802 } else if (stream->default_duration) {
3803 duration = stream->default_duration * laces;
3805 /* else duration is diff between timecode of this and next block */
3807 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3808 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
3809 a ReferenceBlock implies that this is not a keyframe. In either
3810 case, it only makes sense for video streams. */
3811 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
3813 invisible_frame = ((flags & 0x08)) &&
3814 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
3815 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9) ||
3816 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_AV1));
3819 /* If we're doing a keyframe-only trickmode, only push keyframes on video
3823 segment.flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) {
3824 GST_LOG_OBJECT (demux, "Skipping non-keyframe on stream %d",
3831 for (n = 0; n < laces; n++) {
3834 if (G_UNLIKELY (lace_size[n] > size)) {
3835 GST_WARNING_OBJECT (demux, "Invalid lace size");
3839 /* QoS for video track with an index. the assumption is that
3840 index entries point to keyframes, but if that is not true we
3841 will instad skip until the next keyframe. */
3842 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3843 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
3844 stream->index_table && demux->common.segment.rate > 0.0) {
3845 GstMatroskaTrackVideoContext *videocontext =
3846 (GstMatroskaTrackVideoContext *) stream;
3847 GstClockTime earliest_time;
3848 GstClockTime earliest_stream_time;
3850 GST_OBJECT_LOCK (demux);
3851 earliest_time = videocontext->earliest_time;
3852 GST_OBJECT_UNLOCK (demux);
3853 earliest_stream_time =
3854 gst_segment_position_from_running_time (&demux->common.segment,
3855 GST_FORMAT_TIME, earliest_time);
3857 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
3858 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
3859 lace_time <= earliest_stream_time) {
3860 /* find index entry (keyframe) <= earliest_stream_time */
3861 GstMatroskaIndex *entry =
3862 gst_util_array_binary_search (stream->index_table->data,
3863 stream->index_table->len, sizeof (GstMatroskaIndex),
3864 (GCompareDataFunc) gst_matroska_index_seek_find,
3865 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
3867 /* if that entry (keyframe) is after the current the current
3868 buffer, we can skip pushing (and thus decoding) all
3869 buffers until that keyframe. */
3870 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
3871 entry->time > lace_time) {
3872 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
3873 stream->set_discont = TRUE;
3879 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
3880 gst_buffer_get_size (buf) - size, lace_size[n]);
3881 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
3884 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3886 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
3888 if (invisible_frame)
3889 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
3891 if (stream->encodings != NULL && stream->encodings->len > 0)
3892 sub = gst_matroska_decode_buffer (stream, sub);
3895 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
3899 if (!stream->dts_only) {
3900 GST_BUFFER_PTS (sub) = lace_time;
3902 GST_BUFFER_DTS (sub) = lace_time;
3903 if (stream->intra_only)
3904 GST_BUFFER_PTS (sub) = lace_time;
3907 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
3909 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
3910 GstClockTime last_stop_end;
3912 /* Check if this stream is after segment stop */
3913 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
3914 lace_time >= demux->common.segment.stop) {
3915 GST_DEBUG_OBJECT (demux,
3916 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
3917 GST_TIME_ARGS (demux->common.segment.stop));
3918 gst_buffer_unref (sub);
3921 if (offset >= stream->to_offset
3922 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
3923 && lace_time > demux->to_time)) {
3924 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
3926 gst_buffer_unref (sub);
3930 /* handle gaps, e.g. non-zero start-time, or an cue index entry
3931 * that landed us with timestamps not quite intended */
3932 GST_OBJECT_LOCK (demux);
3933 if (demux->max_gap_time &&
3934 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
3935 demux->common.segment.rate > 0.0) {
3936 GstClockTimeDiff diff;
3938 /* only send segments with increasing start times,
3939 * otherwise if these go back and forth downstream (sinks) increase
3940 * accumulated time and running_time */
3941 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
3942 if (diff > 0 && diff > demux->max_gap_time
3943 && lace_time > demux->common.segment.start
3944 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
3945 || lace_time < demux->common.segment.stop)) {
3947 GST_DEBUG_OBJECT (demux,
3948 "Gap of %" G_GINT64_FORMAT " ns detected in"
3949 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
3950 "Sending updated SEGMENT events", diff,
3951 stream->index, GST_TIME_ARGS (stream->pos),
3952 GST_TIME_ARGS (lace_time));
3954 event = gst_event_new_gap (demux->last_stop_end, diff);
3955 GST_OBJECT_UNLOCK (demux);
3956 gst_pad_push_event (stream->pad, event);
3957 GST_OBJECT_LOCK (demux);
3961 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
3962 || demux->common.segment.position < lace_time) {
3963 demux->common.segment.position = lace_time;
3965 GST_OBJECT_UNLOCK (demux);
3967 last_stop_end = lace_time;
3969 GST_BUFFER_DURATION (sub) = duration / laces;
3970 last_stop_end += GST_BUFFER_DURATION (sub);
3973 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
3974 demux->last_stop_end < last_stop_end)
3975 demux->last_stop_end = last_stop_end;
3977 GST_OBJECT_LOCK (demux);
3978 if (demux->common.segment.duration == -1 ||
3979 demux->stream_start_time + demux->common.segment.duration <
3981 demux->common.segment.duration =
3982 last_stop_end - demux->stream_start_time;
3983 GST_OBJECT_UNLOCK (demux);
3984 if (!demux->invalid_duration) {
3985 gst_element_post_message (GST_ELEMENT_CAST (demux),
3986 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
3987 demux->invalid_duration = TRUE;
3990 GST_OBJECT_UNLOCK (demux);
3994 stream->pos = lace_time;
3996 gst_matroska_demux_sync_streams (demux);
3998 if (stream->set_discont) {
3999 GST_DEBUG_OBJECT (demux, "marking DISCONT");
4000 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
4001 stream->set_discont = FALSE;
4003 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
4006 /* reverse playback book-keeping */
4007 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
4008 stream->from_time = lace_time;
4009 if (stream->from_offset == -1)
4010 stream->from_offset = offset;
4012 GST_DEBUG_OBJECT (demux,
4013 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
4014 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
4015 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
4016 GST_TIME_ARGS (buffer_timestamp),
4017 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
4020 if (demux->common.element_index) {
4021 if (stream->index_writer_id == -1)
4022 gst_index_get_writer_id (demux->common.element_index,
4023 GST_OBJECT (stream->pad), &stream->index_writer_id);
4025 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4026 G_GUINT64_FORMAT " for writer id %d",
4027 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
4028 stream->index_writer_id);
4029 gst_index_add_association (demux->common.element_index,
4030 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
4031 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
4032 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
4037 /* Postprocess the buffers depending on the codec used */
4038 if (stream->postprocess_frame) {
4039 GST_LOG_OBJECT (demux, "running post process");
4040 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
4043 /* At this point, we have a sub-buffer pointing at data within a larger
4044 buffer. This data might not be aligned with anything. If the data is
4045 raw samples though, we want it aligned to the raw type (eg, 4 bytes
4046 for 32 bit samples, etc), or bad things will happen downstream as
4047 elements typically assume minimal alignment.
4048 Therefore, create an aligned copy if necessary. */
4049 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
4051 if (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
4052 guint64 start_clip = 0, end_clip = 0;
4054 /* Codec delay is part of the timestamps */
4055 if (GST_BUFFER_PTS_IS_VALID (sub) && stream->codec_delay) {
4056 if (GST_BUFFER_PTS (sub) > stream->codec_delay) {
4057 GST_BUFFER_PTS (sub) -= stream->codec_delay;
4059 GST_BUFFER_PTS (sub) = 0;
4061 gst_util_uint64_scale_round (stream->codec_delay, 48000,
4064 if (GST_BUFFER_DURATION_IS_VALID (sub)) {
4065 if (GST_BUFFER_DURATION (sub) > stream->codec_delay)
4066 GST_BUFFER_DURATION (sub) -= stream->codec_delay;
4068 GST_BUFFER_DURATION (sub) = 0;
4073 if (block_discardpadding) {
4075 gst_util_uint64_scale_round (block_discardpadding, 48000,
4079 if (start_clip || end_clip) {
4080 gst_buffer_add_audio_clipping_meta (sub, GST_FORMAT_DEFAULT,
4081 start_clip, end_clip);
4085 if (GST_BUFFER_PTS_IS_VALID (sub)) {
4086 stream->pos = GST_BUFFER_PTS (sub);
4087 if (GST_BUFFER_DURATION_IS_VALID (sub))
4088 stream->pos += GST_BUFFER_DURATION (sub);
4089 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
4090 stream->pos = GST_BUFFER_DTS (sub);
4091 if (GST_BUFFER_DURATION_IS_VALID (sub))
4092 stream->pos += GST_BUFFER_DURATION (sub);
4095 ret = gst_pad_push (stream->pad, sub);
4097 if (demux->common.segment.rate < 0) {
4098 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
4099 /* In reverse playback we can get a GST_FLOW_EOS when
4100 * we are at the end of the segment, so we just need to jump
4101 * back to the previous section. */
4102 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
4107 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
4111 size -= lace_size[n];
4112 if (lace_time != GST_CLOCK_TIME_NONE && duration)
4113 lace_time += duration / laces;
4115 lace_time = GST_CLOCK_TIME_NONE;
4121 gst_buffer_unmap (buf, &map);
4122 gst_buffer_unref (buf);
4134 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
4140 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
4141 /* non-fatal, try next block(group) */
4147 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
4148 /* non-fatal, try next block(group) */
4154 /* return FALSE if block(group) should be skipped (due to a seek) */
4155 static inline gboolean
4156 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
4158 if (G_UNLIKELY (demux->seek_block)) {
4159 if (!(--demux->seek_block)) {
4162 GST_LOG_OBJECT (demux, "should skip block due to seek");
4170 static GstFlowReturn
4171 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
4175 guint64 seek_pos = (guint64) - 1;
4176 guint32 seek_id = 0;
4179 DEBUG_ELEMENT_START (demux, ebml, "Seek");
4181 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4182 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4186 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4187 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4191 case GST_MATROSKA_ID_SEEKID:
4195 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4198 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
4203 case GST_MATROSKA_ID_SEEKPOSITION:
4207 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4210 if (t > G_MAXINT64) {
4211 GST_WARNING_OBJECT (demux,
4212 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
4216 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
4222 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
4228 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
4231 if (!seek_id || seek_pos == (guint64) - 1) {
4232 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
4233 G_GUINT64_FORMAT ")", seek_id, seek_pos);
4238 case GST_MATROSKA_ID_SEEKHEAD:
4241 case GST_MATROSKA_ID_CUES:
4242 case GST_MATROSKA_ID_TAGS:
4243 case GST_MATROSKA_ID_TRACKS:
4244 case GST_MATROSKA_ID_SEGMENTINFO:
4245 case GST_MATROSKA_ID_ATTACHMENTS:
4246 case GST_MATROSKA_ID_CHAPTERS:
4248 guint64 before_pos, length;
4252 length = gst_matroska_read_common_get_length (&demux->common);
4253 before_pos = demux->common.offset;
4255 if (length == (guint64) - 1) {
4256 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
4260 /* check for validity */
4261 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
4262 GST_WARNING_OBJECT (demux,
4263 "SeekHead reference lies outside file!" " (%"
4264 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
4265 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
4270 /* only pick up index location when streaming */
4271 if (demux->streaming) {
4272 if (seek_id == GST_MATROSKA_ID_CUES) {
4273 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
4274 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
4275 demux->index_offset);
4281 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
4284 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4285 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
4289 if (id != seek_id) {
4290 GST_WARNING_OBJECT (demux,
4291 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
4292 seek_id, id, seek_pos + demux->common.ebml_segment_start);
4295 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4300 demux->common.offset = before_pos;
4304 case GST_MATROSKA_ID_CLUSTER:
4306 guint64 pos = seek_pos + demux->common.ebml_segment_start;
4308 GST_LOG_OBJECT (demux, "Cluster position");
4309 if (G_UNLIKELY (!demux->clusters))
4310 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
4311 g_array_append_val (demux->clusters, pos);
4316 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
4319 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4324 static GstFlowReturn
4325 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4327 GstFlowReturn ret = GST_FLOW_OK;
4330 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4332 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4333 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4337 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4338 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4342 case GST_MATROSKA_ID_SEEKENTRY:
4344 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
4345 /* Ignore EOS and errors here */
4346 if (ret != GST_FLOW_OK) {
4347 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4354 ret = gst_matroska_read_common_parse_skip (&demux->common,
4355 ebml, "SeekHead", id);
4360 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4362 /* Sort clusters by position for easier searching */
4363 if (demux->clusters)
4364 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4369 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
4371 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4373 static inline GstFlowReturn
4374 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4376 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4377 /* only a few blocks are expected/allowed to be large,
4378 * and will be recursed into, whereas others will be read and must fit */
4379 if (demux->streaming) {
4380 /* fatal in streaming case, as we can't step over easily */
4381 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4382 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4383 "file might be corrupt.", bytes));
4384 return GST_FLOW_ERROR;
4386 /* indicate higher level to quietly give up */
4387 GST_DEBUG_OBJECT (demux,
4388 "too large block of size %" G_GUINT64_FORMAT, bytes);
4389 return GST_FLOW_ERROR;
4396 /* returns TRUE if we truely are in error state, and should give up */
4397 static inline GstFlowReturn
4398 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4400 if (!demux->streaming && demux->next_cluster_offset > 0) {
4401 /* just repositioning to where next cluster should be and try from there */
4402 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4403 G_GUINT64_FORMAT, demux->next_cluster_offset);
4404 demux->common.offset = demux->next_cluster_offset;
4405 demux->next_cluster_offset = 0;
4411 /* sigh, one last attempt above and beyond call of duty ...;
4412 * search for cluster mark following current pos */
4413 pos = demux->common.offset;
4414 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4415 if ((ret = gst_matroska_demux_search_cluster (demux, &pos, TRUE)) !=
4417 /* did not work, give up */
4420 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4421 /* try that position */
4422 demux->common.offset = pos;
4428 static inline GstFlowReturn
4429 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4431 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4432 demux->common.offset += flush;
4433 if (demux->streaming) {
4436 /* hard to skip large blocks when streaming */
4437 ret = gst_matroska_demux_check_read_size (demux, flush);
4438 if (ret != GST_FLOW_OK)
4440 if (flush <= gst_adapter_available (demux->common.adapter))
4441 gst_adapter_flush (demux->common.adapter, flush);
4443 return GST_FLOW_EOS;
4448 /* initializes @ebml with @bytes from input stream at current offset.
4449 * Returns EOS if insufficient available,
4450 * ERROR if too much was attempted to read. */
4451 static inline GstFlowReturn
4452 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4455 GstBuffer *buffer = NULL;
4456 GstFlowReturn ret = GST_FLOW_OK;
4458 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4460 ret = gst_matroska_demux_check_read_size (demux, bytes);
4461 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4462 if (!demux->streaming) {
4463 /* in pull mode, we can skip */
4464 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4465 ret = GST_FLOW_OVERFLOW;
4467 /* otherwise fatal */
4468 ret = GST_FLOW_ERROR;
4472 if (demux->streaming) {
4473 if (gst_adapter_available (demux->common.adapter) >= bytes)
4474 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4478 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4479 demux->common.offset, bytes, &buffer, NULL);
4480 if (G_LIKELY (buffer)) {
4481 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4482 demux->common.offset);
4483 demux->common.offset += bytes;
4490 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4493 gboolean seekable = FALSE;
4494 gint64 start = -1, stop = -1;
4496 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4497 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4498 GST_DEBUG_OBJECT (demux, "seeking query failed");
4502 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4504 /* try harder to query upstream size if we didn't get it the first time */
4505 if (seekable && stop == -1) {
4506 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4507 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4511 /* if upstream doesn't know the size, it's likely that it's not seekable in
4512 * practice even if it technically may be seekable */
4513 if (seekable && (start != 0 || stop <= start)) {
4514 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4519 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4520 G_GUINT64_FORMAT ")", seekable, start, stop);
4521 demux->seekable = seekable;
4523 gst_query_unref (query);
4526 static GstFlowReturn
4527 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4533 GstFlowReturn ret = GST_FLOW_OK;
4535 GST_WARNING_OBJECT (demux,
4536 "Found Cluster element before Tracks, searching Tracks");
4539 before_pos = demux->common.offset;
4541 /* Search Tracks element */
4543 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4544 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4545 if (ret != GST_FLOW_OK)
4548 if (id != GST_MATROSKA_ID_TRACKS) {
4549 /* we may be skipping large cluster here, so forego size check etc */
4550 /* ... but we can't skip undefined size; force error */
4551 if (length == G_MAXUINT64) {
4552 ret = gst_matroska_demux_check_read_size (demux, length);
4555 demux->common.offset += needed;
4556 demux->common.offset += length;
4561 /* will lead to track parsing ... */
4562 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4567 demux->common.offset = before_pos;
4572 #define GST_READ_CHECK(stmt) \
4574 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4575 if (ret == GST_FLOW_OVERFLOW) { \
4576 ret = GST_FLOW_OK; \
4582 static GstFlowReturn
4583 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4584 guint64 length, guint needed)
4586 GstEbmlRead ebml = { 0, };
4587 GstFlowReturn ret = GST_FLOW_OK;
4590 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4591 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4593 /* if we plan to read and parse this element, we need prefix (id + length)
4594 * and the contents */
4595 /* mind about overflow wrap-around when dealing with undefined size */
4597 if (G_LIKELY (length != G_MAXUINT64))
4600 switch (demux->common.state) {
4601 case GST_MATROSKA_READ_STATE_START:
4603 case GST_EBML_ID_HEADER:
4604 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4605 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4606 if (ret != GST_FLOW_OK)
4608 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4609 gst_matroska_demux_check_seekability (demux);
4612 goto invalid_header;
4616 case GST_MATROSKA_READ_STATE_SEGMENT:
4618 case GST_MATROSKA_ID_SEGMENT:
4619 /* eat segment prefix */
4620 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4621 GST_DEBUG_OBJECT (demux,
4622 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4623 G_GUINT64_FORMAT, demux->common.offset, length);
4624 /* seeks are from the beginning of the segment,
4625 * after the segment ID/length */
4626 demux->common.ebml_segment_start = demux->common.offset;
4628 length = G_MAXUINT64;
4629 demux->common.ebml_segment_length = length;
4630 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4633 GST_WARNING_OBJECT (demux,
4634 "Expected a Segment ID (0x%x), but received 0x%x!",
4635 GST_MATROSKA_ID_SEGMENT, id);
4636 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4640 case GST_MATROSKA_READ_STATE_SCANNING:
4641 if (id != GST_MATROSKA_ID_CLUSTER &&
4642 id != GST_MATROSKA_ID_CLUSTERTIMECODE) {
4643 if (demux->common.start_resync_offset != -1) {
4644 /* we need to skip byte per byte if we are scanning for a new cluster
4645 * after invalid data is found
4651 if (demux->common.start_resync_offset != -1) {
4652 GST_LOG_OBJECT (demux, "Resync done, new cluster found!");
4653 demux->common.start_resync_offset = -1;
4654 demux->common.state = demux->common.state_to_restore;
4658 case GST_MATROSKA_READ_STATE_HEADER:
4659 case GST_MATROSKA_READ_STATE_DATA:
4660 case GST_MATROSKA_READ_STATE_SEEK:
4662 case GST_MATROSKA_ID_SEGMENTINFO:
4663 if (!demux->common.segmentinfo_parsed) {
4664 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4665 ret = gst_matroska_read_common_parse_info (&demux->common,
4666 GST_ELEMENT_CAST (demux), &ebml);
4667 if (ret == GST_FLOW_OK)
4668 gst_matroska_demux_send_tags (demux);
4670 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4673 case GST_MATROSKA_ID_TRACKS:
4674 if (!demux->tracks_parsed) {
4675 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4676 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4678 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4681 case GST_MATROSKA_ID_CLUSTER:
4682 if (G_UNLIKELY (!demux->tracks_parsed)) {
4683 if (demux->streaming) {
4684 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4685 goto not_streamable;
4687 ret = gst_matroska_demux_find_tracks (demux);
4688 if (!demux->tracks_parsed)
4692 if (G_UNLIKELY (demux->common.state
4693 == GST_MATROSKA_READ_STATE_HEADER)) {
4694 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4695 demux->first_cluster_offset = demux->common.offset;
4696 if (!demux->streaming &&
4697 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.duration)) {
4698 GstMatroskaIndex *last = NULL;
4700 GST_DEBUG_OBJECT (demux,
4701 "estimating duration using last cluster");
4702 if ((last = gst_matroska_demux_search_pos (demux,
4703 GST_CLOCK_TIME_NONE)) != NULL) {
4704 demux->last_cluster_offset =
4705 last->pos + demux->common.ebml_segment_start;
4706 demux->stream_last_time = last->time;
4707 demux->common.segment.duration =
4708 demux->stream_last_time - demux->stream_start_time;
4709 /* above estimate should not be taken all too strongly */
4710 demux->invalid_duration = TRUE;
4711 GST_DEBUG_OBJECT (demux,
4712 "estimated duration as %" GST_TIME_FORMAT,
4713 GST_TIME_ARGS (demux->common.segment.duration));
4716 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4717 gst_element_no_more_pads (GST_ELEMENT (demux));
4718 /* send initial segment - we wait till we know the first
4719 incoming timestamp, so we can properly set the start of
4721 demux->need_segment = TRUE;
4723 demux->cluster_time = GST_CLOCK_TIME_NONE;
4724 demux->cluster_offset = demux->common.offset;
4725 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4726 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4727 " not found in Cluster, trying next Cluster's first block instead",
4729 demux->seek_block = 0;
4731 demux->seek_first = FALSE;
4732 /* record next cluster for recovery */
4733 if (read != G_MAXUINT64)
4734 demux->next_cluster_offset = demux->cluster_offset + read;
4735 /* eat cluster prefix */
4736 gst_matroska_demux_flush (demux, needed);
4738 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4742 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4743 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4745 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4746 demux->cluster_time = num;
4747 /* track last cluster */
4748 if (demux->cluster_offset > demux->last_cluster_offset) {
4749 demux->last_cluster_offset = demux->cluster_offset;
4750 demux->stream_last_time =
4751 demux->cluster_time * demux->common.time_scale;
4754 if (demux->common.element_index) {
4755 if (demux->common.element_index_writer_id == -1)
4756 gst_index_get_writer_id (demux->common.element_index,
4757 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4758 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4759 G_GUINT64_FORMAT " for writer id %d",
4760 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4761 demux->common.element_index_writer_id);
4762 gst_index_add_association (demux->common.element_index,
4763 demux->common.element_index_writer_id,
4764 GST_ASSOCIATION_FLAG_KEY_UNIT,
4765 GST_FORMAT_TIME, demux->cluster_time,
4766 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4771 case GST_MATROSKA_ID_BLOCKGROUP:
4772 if (!gst_matroska_demux_seek_block (demux))
4774 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4775 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4776 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4777 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4778 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4780 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4782 case GST_MATROSKA_ID_SIMPLEBLOCK:
4783 if (!gst_matroska_demux_seek_block (demux))
4785 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4786 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4787 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4788 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4789 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4791 case GST_MATROSKA_ID_ATTACHMENTS:
4792 if (!demux->common.attachments_parsed) {
4793 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4794 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4795 GST_ELEMENT_CAST (demux), &ebml);
4796 if (ret == GST_FLOW_OK)
4797 gst_matroska_demux_send_tags (demux);
4799 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4802 case GST_MATROSKA_ID_TAGS:
4803 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4804 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4805 GST_ELEMENT_CAST (demux), &ebml);
4806 if (ret == GST_FLOW_OK)
4807 gst_matroska_demux_send_tags (demux);
4809 case GST_MATROSKA_ID_CHAPTERS:
4810 if (!demux->common.chapters_parsed) {
4811 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4813 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4815 if (demux->common.toc) {
4816 gst_matroska_demux_send_event (demux,
4817 gst_event_new_toc (demux->common.toc, FALSE));
4820 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4822 case GST_MATROSKA_ID_SEEKHEAD:
4823 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4824 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4826 case GST_MATROSKA_ID_CUES:
4827 if (demux->common.index_parsed) {
4828 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4831 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4832 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4833 /* only push based; delayed index building */
4834 if (ret == GST_FLOW_OK
4835 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4838 GST_OBJECT_LOCK (demux);
4839 event = demux->seek_event;
4840 demux->seek_event = NULL;
4841 GST_OBJECT_UNLOCK (demux);
4844 /* unlikely to fail, since we managed to seek to this point */
4845 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
4846 gst_event_unref (event);
4849 gst_event_unref (event);
4850 /* resume data handling, main thread clear to seek again */
4851 GST_OBJECT_LOCK (demux);
4852 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4853 GST_OBJECT_UNLOCK (demux);
4856 case GST_MATROSKA_ID_POSITION:
4857 case GST_MATROSKA_ID_PREVSIZE:
4858 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4859 case GST_MATROSKA_ID_SILENTTRACKS:
4860 GST_DEBUG_OBJECT (demux,
4861 "Skipping Cluster subelement 0x%x - ignoring", id);
4865 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4866 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4872 if (ret == GST_FLOW_PARSE)
4876 gst_ebml_read_clear (&ebml);
4882 /* simply exit, maybe not enough data yet */
4883 /* no ebml to clear if read error */
4888 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4889 ("Failed to parse Element 0x%x", id));
4890 ret = GST_FLOW_ERROR;
4895 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4896 ("File layout does not permit streaming"));
4897 ret = GST_FLOW_ERROR;
4902 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4903 ("No Tracks element found"));
4904 ret = GST_FLOW_ERROR;
4909 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4910 ret = GST_FLOW_ERROR;
4915 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4916 ret = GST_FLOW_ERROR;
4922 gst_matroska_demux_loop (GstPad * pad)
4924 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4930 /* If we have to close a segment, send a new segment to do this now */
4931 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4932 if (G_UNLIKELY (demux->new_segment)) {
4933 gst_matroska_demux_send_event (demux, demux->new_segment);
4934 demux->new_segment = NULL;
4938 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4939 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4940 if (ret == GST_FLOW_EOS) {
4942 } else if (ret == GST_FLOW_FLUSHING) {
4944 } else if (ret != GST_FLOW_OK) {
4945 ret = gst_matroska_demux_check_parse_error (demux);
4947 /* Only handle EOS as no error if we're outside the segment already */
4948 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4949 && demux->common.offset >=
4950 demux->common.ebml_segment_start +
4951 demux->common.ebml_segment_length))
4953 else if (ret != GST_FLOW_OK)
4959 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4960 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4963 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4964 if (ret == GST_FLOW_EOS)
4966 if (ret != GST_FLOW_OK)
4969 /* check if we're at the end of a configured segment */
4970 if (G_LIKELY (demux->common.src->len)) {
4973 g_assert (demux->common.num_streams == demux->common.src->len);
4974 for (i = 0; i < demux->common.src->len; i++) {
4975 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4977 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4978 GST_TIME_ARGS (context->pos));
4979 if (context->eos == FALSE)
4983 GST_INFO_OBJECT (demux, "All streams are EOS");
4989 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4990 demux->common.offset >= demux->cached_length)) {
4991 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4992 if (demux->common.offset == demux->cached_length) {
4993 GST_LOG_OBJECT (demux, "Reached end of stream");
5004 if (demux->common.segment.rate < 0.0) {
5005 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
5006 if (ret == GST_FLOW_OK)
5013 const gchar *reason = gst_flow_get_name (ret);
5014 gboolean push_eos = FALSE;
5016 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
5017 gst_pad_pause_task (demux->common.sinkpad);
5019 if (ret == GST_FLOW_EOS) {
5020 /* perform EOS logic */
5022 /* If we were in the headers, make sure we send no-more-pads.
5023 This will ensure decodebin does not get stuck thinking
5024 the chain is not complete yet, and waiting indefinitely. */
5025 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
5026 if (demux->common.src->len == 0) {
5027 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
5028 ("No pads created"));
5030 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
5031 ("Failed to finish reading headers"));
5033 gst_element_no_more_pads (GST_ELEMENT (demux));
5036 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
5041 /* for segment playback we need to post when (in stream time)
5042 * we stopped, this is either stop (when set) or the duration. */
5043 if ((stop = demux->common.segment.stop) == -1)
5044 stop = demux->last_stop_end;
5046 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
5047 msg = gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
5049 if (demux->segment_seqnum)
5050 gst_message_set_seqnum (msg, demux->segment_seqnum);
5051 gst_element_post_message (GST_ELEMENT (demux), msg);
5053 event = gst_event_new_segment_done (GST_FORMAT_TIME, stop);
5054 if (demux->segment_seqnum)
5055 gst_event_set_seqnum (event, demux->segment_seqnum);
5056 gst_matroska_demux_send_event (demux, event);
5060 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
5061 /* for fatal errors we post an error message */
5062 GST_ELEMENT_FLOW_ERROR (demux, ret);
5068 /* send EOS, and prevent hanging if no streams yet */
5069 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
5070 event = gst_event_new_eos ();
5071 if (demux->segment_seqnum)
5072 gst_event_set_seqnum (event, demux->segment_seqnum);
5073 if (!gst_matroska_demux_send_event (demux, event) &&
5074 (ret == GST_FLOW_EOS)) {
5075 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5076 (NULL), ("got eos but no streams (yet)"));
5084 * Create and push a flushing seek event upstream
5087 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
5088 guint32 seqnum, GstSeekFlags flags)
5093 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
5096 gst_event_new_seek (rate, GST_FORMAT_BYTES,
5097 flags | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
5098 GST_SEEK_TYPE_SET, offset, GST_SEEK_TYPE_NONE, -1);
5099 gst_event_set_seqnum (event, seqnum);
5101 res = gst_pad_push_event (demux->common.sinkpad, event);
5103 /* segment event will update offset */
5107 static GstFlowReturn
5108 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
5110 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5112 GstFlowReturn ret = GST_FLOW_OK;
5117 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
5118 GST_DEBUG_OBJECT (demux, "got DISCONT");
5119 gst_adapter_clear (demux->common.adapter);
5120 GST_OBJECT_LOCK (demux);
5121 gst_matroska_read_common_reset_streams (&demux->common,
5122 GST_CLOCK_TIME_NONE, FALSE);
5123 GST_OBJECT_UNLOCK (demux);
5126 gst_adapter_push (demux->common.adapter, buffer);
5130 available = gst_adapter_available (demux->common.adapter);
5132 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
5133 GST_ELEMENT_CAST (demux), &id, &length, &needed);
5134 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
5135 if (demux->common.ebml_segment_length != G_MAXUINT64
5136 && demux->common.offset >=
5137 demux->common.ebml_segment_start + demux->common.ebml_segment_length) {
5140 gint64 bytes_scanned;
5141 if (demux->common.start_resync_offset == -1) {
5142 demux->common.start_resync_offset = demux->common.offset;
5143 demux->common.state_to_restore = demux->common.state;
5145 bytes_scanned = demux->common.offset - demux->common.start_resync_offset;
5146 if (bytes_scanned <= INVALID_DATA_THRESHOLD) {
5147 GST_WARNING_OBJECT (demux,
5148 "parse error, looking for next cluster, actual offset %"
5149 G_GUINT64_FORMAT ", start resync offset %" G_GUINT64_FORMAT,
5150 demux->common.offset, demux->common.start_resync_offset);
5151 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
5154 GST_WARNING_OBJECT (demux,
5155 "unrecoverable parse error, next cluster not found and threshold "
5156 "exceeded, bytes scanned %" G_GINT64_FORMAT, bytes_scanned);
5162 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
5163 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
5164 demux->common.offset, id, length, needed, available);
5166 if (needed > available)
5169 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5170 if (ret == GST_FLOW_EOS) {
5171 /* need more data */
5173 } else if (ret != GST_FLOW_OK) {
5180 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
5183 gboolean res = TRUE;
5184 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5186 GST_DEBUG_OBJECT (demux,
5187 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
5189 switch (GST_EVENT_TYPE (event)) {
5190 case GST_EVENT_SEGMENT:
5192 const GstSegment *segment;
5194 /* some debug output */
5195 gst_event_parse_segment (event, &segment);
5196 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
5197 GST_DEBUG_OBJECT (demux,
5198 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
5201 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
5202 GST_DEBUG_OBJECT (demux, "still starting");
5206 /* we only expect a BYTE segment, e.g. following a seek */
5207 if (segment->format != GST_FORMAT_BYTES) {
5208 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
5212 GST_DEBUG_OBJECT (demux, "clearing segment state");
5213 GST_OBJECT_LOCK (demux);
5214 /* clear current segment leftover */
5215 gst_adapter_clear (demux->common.adapter);
5216 /* and some streaming setup */
5217 demux->common.offset = segment->start;
5218 /* accumulate base based on current position */
5219 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
5220 demux->common.segment.base +=
5221 (MAX (demux->common.segment.position, demux->stream_start_time)
5222 - demux->stream_start_time) / fabs (demux->common.segment.rate);
5223 /* do not know where we are;
5224 * need to come across a cluster and generate segment */
5225 demux->common.segment.position = GST_CLOCK_TIME_NONE;
5226 demux->cluster_time = GST_CLOCK_TIME_NONE;
5227 demux->cluster_offset = 0;
5228 demux->need_segment = TRUE;
5229 demux->segment_seqnum = gst_event_get_seqnum (event);
5230 /* but keep some of the upstream segment */
5231 demux->common.segment.rate = segment->rate;
5232 demux->common.segment.flags = segment->flags;
5233 /* also check if need to keep some of the requested seek position */
5234 if (demux->seek_offset == segment->start) {
5235 GST_DEBUG_OBJECT (demux, "position matches requested seek");
5236 demux->common.segment.position = demux->requested_seek_time;
5238 GST_DEBUG_OBJECT (demux, "unexpected segment position");
5240 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
5241 demux->seek_offset = -1;
5242 GST_OBJECT_UNLOCK (demux);
5244 /* chain will send initial segment after pads have been added,
5245 * or otherwise come up with one */
5246 GST_DEBUG_OBJECT (demux, "eating event");
5247 gst_event_unref (event);
5253 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA
5254 && demux->common.state != GST_MATROSKA_READ_STATE_SCANNING) {
5255 gst_event_unref (event);
5256 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5257 (NULL), ("got eos and didn't receive a complete header object"));
5258 } else if (demux->common.num_streams == 0) {
5259 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5260 (NULL), ("got eos but no streams (yet)"));
5262 gst_matroska_demux_send_event (demux, event);
5266 case GST_EVENT_FLUSH_STOP:
5270 gst_adapter_clear (demux->common.adapter);
5271 GST_OBJECT_LOCK (demux);
5272 gst_matroska_read_common_reset_streams (&demux->common,
5273 GST_CLOCK_TIME_NONE, TRUE);
5274 gst_flow_combiner_reset (demux->flowcombiner);
5275 dur = demux->common.segment.duration;
5276 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
5277 demux->common.segment.duration = dur;
5278 demux->cluster_time = GST_CLOCK_TIME_NONE;
5279 demux->cluster_offset = 0;
5280 GST_OBJECT_UNLOCK (demux);
5284 res = gst_pad_event_default (pad, parent, event);
5292 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
5294 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5296 gboolean pull_mode = FALSE;
5298 query = gst_query_new_scheduling ();
5300 if (gst_pad_peer_query (sinkpad, query))
5301 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
5302 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
5304 gst_query_unref (query);
5307 GST_DEBUG ("going to pull mode");
5308 demux->streaming = FALSE;
5309 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
5311 GST_DEBUG ("going to push (streaming) mode");
5312 demux->streaming = TRUE;
5313 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
5318 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
5319 GstPadMode mode, gboolean active)
5322 case GST_PAD_MODE_PULL:
5324 /* if we have a scheduler we can start the task */
5325 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
5328 gst_pad_stop_task (sinkpad);
5331 case GST_PAD_MODE_PUSH:
5339 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
5340 videocontext, const gchar * codec_id, guint8 * data, guint size,
5341 gchar ** codec_name, guint32 * riff_fourcc)
5343 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
5344 GstCaps *caps = NULL;
5346 g_assert (videocontext != NULL);
5347 g_assert (codec_name != NULL);
5352 /* TODO: check if we have all codec types from matroska-ids.h
5353 * check if we have to do more special things with codec_private
5356 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
5357 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
5360 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
5361 gst_riff_strf_vids *vids = NULL;
5364 GstBuffer *buf = NULL;
5366 vids = (gst_riff_strf_vids *) data;
5368 /* assure size is big enough */
5370 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
5373 if (size < sizeof (gst_riff_strf_vids)) {
5374 vids = g_new (gst_riff_strf_vids, 1);
5375 memcpy (vids, data, size);
5378 context->dts_only = TRUE; /* VFW files only store DTS */
5380 /* little-endian -> byte-order */
5381 vids->size = GUINT32_FROM_LE (vids->size);
5382 vids->width = GUINT32_FROM_LE (vids->width);
5383 vids->height = GUINT32_FROM_LE (vids->height);
5384 vids->planes = GUINT16_FROM_LE (vids->planes);
5385 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
5386 vids->compression = GUINT32_FROM_LE (vids->compression);
5387 vids->image_size = GUINT32_FROM_LE (vids->image_size);
5388 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
5389 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
5390 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
5391 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
5393 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
5394 gsize offset = sizeof (gst_riff_strf_vids);
5397 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
5398 size - offset), size - offset);
5402 *riff_fourcc = vids->compression;
5404 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
5405 buf, NULL, codec_name);
5408 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
5409 GST_FOURCC_ARGS (vids->compression));
5411 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
5412 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
5413 "video/x-compressed-yuv");
5414 context->intra_only =
5415 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
5419 gst_buffer_unref (buf);
5421 if (vids != (gst_riff_strf_vids *) data)
5424 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
5426 GstVideoFormat format;
5428 gst_video_info_init (&info);
5429 switch (videocontext->fourcc) {
5430 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5431 format = GST_VIDEO_FORMAT_I420;
5433 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5434 format = GST_VIDEO_FORMAT_YUY2;
5436 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5437 format = GST_VIDEO_FORMAT_YV12;
5439 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5440 format = GST_VIDEO_FORMAT_UYVY;
5442 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5443 format = GST_VIDEO_FORMAT_AYUV;
5445 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
5446 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
5447 format = GST_VIDEO_FORMAT_GRAY8;
5449 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
5450 format = GST_VIDEO_FORMAT_RGB;
5452 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
5453 format = GST_VIDEO_FORMAT_BGR;
5456 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5457 GST_FOURCC_ARGS (videocontext->fourcc));
5461 context->intra_only = TRUE;
5463 gst_video_info_set_format (&info, format, videocontext->pixel_width,
5464 videocontext->pixel_height);
5465 caps = gst_video_info_to_caps (&info);
5466 *codec_name = gst_pb_utils_get_codec_description (caps);
5467 context->alignment = 32;
5468 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5469 caps = gst_caps_new_simple ("video/x-divx",
5470 "divxversion", G_TYPE_INT, 4, NULL);
5471 *codec_name = g_strdup ("MPEG-4 simple profile");
5472 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5473 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5474 caps = gst_caps_new_simple ("video/mpeg",
5475 "mpegversion", G_TYPE_INT, 4,
5476 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5480 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5481 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5482 gst_buffer_unref (priv);
5484 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
5486 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5487 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5489 *codec_name = g_strdup ("MPEG-4 advanced profile");
5490 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5492 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5493 "divxversion", G_TYPE_INT, 3, NULL),
5494 gst_structure_new ("video/x-msmpeg",
5495 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5497 caps = gst_caps_new_simple ("video/x-msmpeg",
5498 "msmpegversion", G_TYPE_INT, 43, NULL);
5499 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5500 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5501 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5504 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5509 caps = gst_caps_new_simple ("video/mpeg",
5510 "systemstream", G_TYPE_BOOLEAN, FALSE,
5511 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5512 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5513 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5514 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5515 caps = gst_caps_new_empty_simple ("image/jpeg");
5516 *codec_name = g_strdup ("Motion-JPEG");
5517 context->intra_only = TRUE;
5518 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5519 caps = gst_caps_new_empty_simple ("video/x-h264");
5523 /* First byte is the version, second is the profile indication, and third
5524 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5525 * level indication. */
5526 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5529 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5530 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5531 gst_buffer_unref (priv);
5533 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5534 "alignment", G_TYPE_STRING, "au", NULL);
5536 GST_WARNING ("No codec data found, assuming output is byte-stream");
5537 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5540 *codec_name = g_strdup ("H264");
5541 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
5542 caps = gst_caps_new_empty_simple ("video/x-h265");
5546 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
5549 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5550 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5551 gst_buffer_unref (priv);
5553 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
5554 "alignment", G_TYPE_STRING, "au", NULL);
5556 GST_WARNING ("No codec data found, assuming output is byte-stream");
5557 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5560 *codec_name = g_strdup ("HEVC");
5561 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5562 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5563 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5564 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5565 gint rmversion = -1;
5567 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5569 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5571 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5573 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5576 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5577 "rmversion", G_TYPE_INT, rmversion, NULL);
5578 GST_DEBUG ("data:%p, size:0x%x", data, size);
5579 /* We need to extract the extradata ! */
5580 if (data && (size >= 0x22)) {
5585 subformat = GST_READ_UINT32_BE (data + 0x1a);
5586 rformat = GST_READ_UINT32_BE (data + 0x1e);
5589 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5591 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5592 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5593 gst_buffer_unref (priv);
5596 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5597 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5598 caps = gst_caps_new_empty_simple ("video/x-theora");
5599 context->stream_headers =
5600 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5601 context->codec_priv_size);
5602 /* FIXME: mark stream as broken and skip if there are no stream headers */
5603 context->send_stream_headers = TRUE;
5604 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5605 caps = gst_caps_new_empty_simple ("video/x-dirac");
5606 *codec_name = g_strdup_printf ("Dirac");
5607 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5608 caps = gst_caps_new_empty_simple ("video/x-vp8");
5609 *codec_name = g_strdup_printf ("On2 VP8");
5610 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5611 caps = gst_caps_new_empty_simple ("video/x-vp9");
5612 *codec_name = g_strdup_printf ("On2 VP9");
5613 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_AV1)) {
5614 caps = gst_caps_new_empty_simple ("video/x-av1");
5615 *codec_name = g_strdup_printf ("AOM AV1");
5616 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
5618 const gchar *variant, *variant_descr = "";
5620 /* Expect a fourcc in the codec private data */
5621 if (!data || size < 4) {
5622 GST_WARNING ("No or too small PRORESS fourcc (%d bytes)", size);
5626 fourcc = GST_STR_FOURCC (data);
5628 case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
5629 variant_descr = " 4:2:2 LT";
5632 case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
5634 variant_descr = " 4:2:2 HQ";
5636 case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
5638 variant_descr = " 4:4:4:4";
5640 case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
5642 variant_descr = " 4:2:2 Proxy";
5644 case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
5646 variant = "standard";
5647 variant_descr = " 4:2:2 SD";
5651 GST_LOG ("Prores video, codec fourcc %" GST_FOURCC_FORMAT,
5652 GST_FOURCC_ARGS (fourcc));
5654 caps = gst_caps_new_simple ("video/x-prores",
5655 "format", G_TYPE_STRING, variant, NULL);
5656 *codec_name = g_strdup_printf ("Apple ProRes%s", variant_descr);
5657 context->postprocess_frame = gst_matroska_demux_add_prores_header;
5659 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5665 GstStructure *structure;
5667 for (i = 0; i < gst_caps_get_size (caps); i++) {
5668 structure = gst_caps_get_structure (caps, i);
5670 /* FIXME: use the real unit here! */
5671 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5672 videocontext->pixel_width,
5673 videocontext->pixel_height,
5674 videocontext->display_width, videocontext->display_height);
5676 /* pixel width and height are the w and h of the video in pixels */
5677 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5678 gint w = videocontext->pixel_width;
5679 gint h = videocontext->pixel_height;
5681 gst_structure_set (structure,
5682 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5685 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5688 if (videocontext->display_width <= 0)
5689 videocontext->display_width = videocontext->pixel_width;
5690 if (videocontext->display_height <= 0)
5691 videocontext->display_height = videocontext->pixel_height;
5693 /* calculate the pixel aspect ratio using the display and pixel w/h */
5694 n = videocontext->display_width * videocontext->pixel_height;
5695 d = videocontext->display_height * videocontext->pixel_width;
5696 GST_DEBUG ("setting PAR to %d/%d", n, d);
5697 gst_structure_set (structure, "pixel-aspect-ratio",
5699 videocontext->display_width * videocontext->pixel_height,
5700 videocontext->display_height * videocontext->pixel_width, NULL);
5703 if (videocontext->default_fps > 0.0) {
5706 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5708 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5710 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5712 } else if (context->default_duration > 0) {
5715 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5717 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5718 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5720 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5721 fps_n, fps_d, NULL);
5723 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5727 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5728 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5731 if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
5732 if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
5733 videocontext->pixel_width, videocontext->pixel_height,
5734 videocontext->display_width * videocontext->pixel_height,
5735 videocontext->display_height * videocontext->pixel_width)) {
5736 videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
5738 gst_caps_set_simple (caps,
5739 "multiview-mode", G_TYPE_STRING,
5740 gst_video_multiview_mode_to_caps_string
5741 (videocontext->multiview_mode), "multiview-flags",
5742 GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
5743 GST_FLAG_SET_MASK_EXACT, NULL);
5746 if (videocontext->colorimetry.range != GST_VIDEO_COLOR_RANGE_UNKNOWN ||
5747 videocontext->colorimetry.matrix != GST_VIDEO_COLOR_MATRIX_UNKNOWN ||
5748 videocontext->colorimetry.transfer != GST_VIDEO_TRANSFER_UNKNOWN ||
5749 videocontext->colorimetry.primaries !=
5750 GST_VIDEO_COLOR_PRIMARIES_UNKNOWN) {
5751 gchar *colorimetry =
5752 gst_video_colorimetry_to_string (&videocontext->colorimetry);
5753 gst_caps_set_simple (caps, "colorimetry", G_TYPE_STRING, colorimetry,
5755 GST_DEBUG ("setting colorimetry to %s", colorimetry);
5756 g_free (colorimetry);
5759 caps = gst_caps_simplify (caps);
5766 * Some AAC specific code... *sigh*
5767 * FIXME: maybe we should use '15' and code the sample rate explicitly
5768 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5772 aac_rate_idx (gint rate)
5776 else if (75132 <= rate)
5778 else if (55426 <= rate)
5780 else if (46009 <= rate)
5782 else if (37566 <= rate)
5784 else if (27713 <= rate)
5786 else if (23004 <= rate)
5788 else if (18783 <= rate)
5790 else if (13856 <= rate)
5792 else if (11502 <= rate)
5794 else if (9391 <= rate)
5801 aac_profile_idx (const gchar * codec_id)
5805 if (strlen (codec_id) <= 12)
5807 else if (!strncmp (&codec_id[12], "MAIN", 4))
5809 else if (!strncmp (&codec_id[12], "LC", 2))
5811 else if (!strncmp (&codec_id[12], "SSR", 3))
5820 round_up_pow2 (guint n)
5831 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5834 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5835 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5836 gchar ** codec_name, guint16 * riff_audio_fmt)
5838 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5839 GstCaps *caps = NULL;
5841 g_assert (audiocontext != NULL);
5842 g_assert (codec_name != NULL);
5845 *riff_audio_fmt = 0;
5847 /* TODO: check if we have all codec types from matroska-ids.h
5848 * check if we have to do more special things with codec_private
5849 * check if we need bitdepth in different places too
5850 * implement channel position magic
5852 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5853 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5854 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5855 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5858 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5859 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5860 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5863 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5865 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5870 caps = gst_caps_new_simple ("audio/mpeg",
5871 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5872 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5873 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5874 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5877 GstAudioFormat format;
5879 sign = (audiocontext->bitdepth != 8);
5880 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5881 endianness = G_BIG_ENDIAN;
5883 endianness = G_LITTLE_ENDIAN;
5885 format = gst_audio_format_build_integer (sign, endianness,
5886 audiocontext->bitdepth, audiocontext->bitdepth);
5888 /* FIXME: Channel mask and reordering */
5889 caps = gst_caps_new_simple ("audio/x-raw",
5890 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5891 "layout", G_TYPE_STRING, "interleaved",
5892 "channel-mask", GST_TYPE_BITMASK,
5893 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5895 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5896 audiocontext->bitdepth);
5897 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5898 context->alignment = round_up_pow2 (context->alignment);
5899 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5900 const gchar *format;
5901 if (audiocontext->bitdepth == 32)
5905 /* FIXME: Channel mask and reordering */
5906 caps = gst_caps_new_simple ("audio/x-raw",
5907 "format", G_TYPE_STRING, format,
5908 "layout", G_TYPE_STRING, "interleaved",
5909 "channel-mask", GST_TYPE_BITMASK,
5910 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5911 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5912 audiocontext->bitdepth);
5913 context->alignment = audiocontext->bitdepth / 8;
5914 context->alignment = round_up_pow2 (context->alignment);
5915 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5916 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5917 caps = gst_caps_new_simple ("audio/x-ac3",
5918 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5919 *codec_name = g_strdup ("AC-3 audio");
5920 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5921 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5922 caps = gst_caps_new_simple ("audio/x-eac3",
5923 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5924 *codec_name = g_strdup ("E-AC-3 audio");
5925 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5926 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5927 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5928 *codec_name = g_strdup ("Dolby TrueHD");
5929 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5930 caps = gst_caps_new_empty_simple ("audio/x-dts");
5931 *codec_name = g_strdup ("DTS audio");
5932 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5933 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5934 context->stream_headers =
5935 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5936 context->codec_priv_size);
5937 /* FIXME: mark stream as broken and skip if there are no stream headers */
5938 context->send_stream_headers = TRUE;
5939 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
5940 caps = gst_caps_new_empty_simple ("audio/x-flac");
5941 context->stream_headers =
5942 gst_matroska_parse_flac_stream_headers (context->codec_priv,
5943 context->codec_priv_size);
5944 /* FIXME: mark stream as broken and skip if there are no stream headers */
5945 context->send_stream_headers = TRUE;
5946 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
5947 caps = gst_caps_new_empty_simple ("audio/x-speex");
5948 context->stream_headers =
5949 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5950 context->codec_priv_size);
5951 /* FIXME: mark stream as broken and skip if there are no stream headers */
5952 context->send_stream_headers = TRUE;
5953 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5956 if (context->codec_priv_size >= 19) {
5957 if (audiocontext->samplerate)
5958 GST_WRITE_UINT32_LE ((guint8 *) context->codec_priv + 12,
5959 audiocontext->samplerate);
5960 if (context->codec_delay) {
5962 gst_util_uint64_scale_round (context->codec_delay, 48000,
5964 GST_WRITE_UINT16_LE ((guint8 *) context->codec_priv + 10, delay);
5968 gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5969 context->codec_priv_size), context->codec_priv_size);
5970 caps = gst_codec_utils_opus_create_caps_from_header (tmp, NULL);
5971 gst_buffer_unref (tmp);
5972 *codec_name = g_strdup ("Opus");
5973 } else if (context->codec_priv_size == 0) {
5974 GST_WARNING ("No Opus codec data found, trying to create one");
5975 if (audiocontext->channels <= 2) {
5976 guint8 streams, coupled, channels;
5980 audiocontext->samplerate == 0 ? 48000 : audiocontext->samplerate;
5981 channels = audiocontext->channels == 0 ? 2 : audiocontext->channels;
5982 if (channels == 1) {
5991 gst_codec_utils_opus_create_caps (samplerate, channels, 0, streams,
5994 *codec_name = g_strdup ("Opus");
5996 GST_WARNING ("Failed to create Opus caps from audio context");
5999 GST_WARNING ("No Opus codec data, and not enough info to create one");
6002 GST_WARNING ("Invalid Opus codec data size (got %" G_GSIZE_FORMAT
6003 ", expected 19)", context->codec_priv_size);
6005 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
6006 gst_riff_strf_auds auds;
6008 if (data && size >= 18) {
6009 GstBuffer *codec_data = NULL;
6011 /* little-endian -> byte-order */
6012 auds.format = GST_READ_UINT16_LE (data);
6013 auds.channels = GST_READ_UINT16_LE (data + 2);
6014 auds.rate = GST_READ_UINT32_LE (data + 4);
6015 auds.av_bps = GST_READ_UINT32_LE (data + 8);
6016 auds.blockalign = GST_READ_UINT16_LE (data + 12);
6017 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
6019 /* 18 is the waveformatex size */
6021 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
6022 data + 18, size - 18, 0, size - 18, NULL, NULL);
6026 *riff_audio_fmt = auds.format;
6028 /* FIXME: Handle reorder map */
6029 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
6030 codec_data, codec_name, NULL);
6032 gst_buffer_unref (codec_data);
6035 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
6038 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
6040 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
6041 GstBuffer *priv = NULL;
6043 gint rate_idx, profile;
6044 guint8 *data = NULL;
6046 /* unspecified AAC profile with opaque private codec data */
6047 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
6048 if (context->codec_priv_size >= 2) {
6049 guint obj_type, freq_index, explicit_freq_bytes = 0;
6051 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6053 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
6054 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
6055 if (freq_index == 15)
6056 explicit_freq_bytes = 3;
6057 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
6058 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
6059 context->codec_priv_size), context->codec_priv_size);
6060 /* assume SBR if samplerate <= 24kHz */
6061 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
6062 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
6063 audiocontext->samplerate *= 2;
6066 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
6067 /* this is pretty broken;
6068 * maybe we need to make up some default private,
6069 * or maybe ADTS data got dumped in.
6070 * Let's set up some private data now, and check actual data later */
6071 /* just try this and see what happens ... */
6072 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6073 context->postprocess_frame = gst_matroska_demux_check_aac;
6077 /* make up decoder-specific data if it is not supplied */
6081 priv = gst_buffer_new_allocate (NULL, 5, NULL);
6082 gst_buffer_map (priv, &map, GST_MAP_WRITE);
6084 rate_idx = aac_rate_idx (audiocontext->samplerate);
6085 profile = aac_profile_idx (codec_id);
6087 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
6088 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
6090 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
6091 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
6093 gst_buffer_unmap (priv, &map);
6094 gst_buffer_set_size (priv, 2);
6095 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
6096 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
6099 if (g_strrstr (codec_id, "SBR")) {
6100 /* HE-AAC (aka SBR AAC) */
6101 audiocontext->samplerate *= 2;
6102 rate_idx = aac_rate_idx (audiocontext->samplerate);
6103 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
6104 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
6105 data[4] = (1 << 7) | (rate_idx << 3);
6106 gst_buffer_unmap (priv, &map);
6108 gst_buffer_unmap (priv, &map);
6109 gst_buffer_set_size (priv, 2);
6112 gst_buffer_unmap (priv, &map);
6113 gst_buffer_unref (priv);
6115 GST_ERROR ("Unknown AAC profile and no codec private data");
6120 caps = gst_caps_new_simple ("audio/mpeg",
6121 "mpegversion", G_TYPE_INT, mpegversion,
6122 "framed", G_TYPE_BOOLEAN, TRUE,
6123 "stream-format", G_TYPE_STRING, "raw", NULL);
6124 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6125 if (context->codec_priv && context->codec_priv_size > 0)
6126 gst_codec_utils_aac_caps_set_level_and_profile (caps,
6127 context->codec_priv, context->codec_priv_size);
6128 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
6129 gst_buffer_unref (priv);
6131 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
6132 caps = gst_caps_new_simple ("audio/x-tta",
6133 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
6134 *codec_name = g_strdup ("TTA audio");
6135 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
6136 caps = gst_caps_new_simple ("audio/x-wavpack",
6137 "width", G_TYPE_INT, audiocontext->bitdepth,
6138 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6139 *codec_name = g_strdup ("Wavpack audio");
6140 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
6141 audiocontext->wvpk_block_index = 0;
6142 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
6143 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
6144 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
6145 gint raversion = -1;
6147 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
6149 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
6154 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
6155 "raversion", G_TYPE_INT, raversion, NULL);
6156 /* Extract extra information from caps, mapping varies based on codec */
6157 if (data && (size >= 0x50)) {
6164 guint extra_data_size;
6166 GST_DEBUG ("real audio raversion:%d", raversion);
6167 if (raversion == 8) {
6169 flavor = GST_READ_UINT16_BE (data + 22);
6170 packet_size = GST_READ_UINT32_BE (data + 24);
6171 height = GST_READ_UINT16_BE (data + 40);
6172 leaf_size = GST_READ_UINT16_BE (data + 44);
6173 sample_width = GST_READ_UINT16_BE (data + 58);
6174 extra_data_size = GST_READ_UINT32_BE (data + 74);
6177 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
6178 flavor, packet_size, height, leaf_size, sample_width,
6180 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
6181 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
6182 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
6184 if ((size - 78) >= extra_data_size) {
6185 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
6187 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6188 gst_buffer_unref (priv);
6193 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
6194 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
6195 caps = gst_caps_new_empty_simple ("audio/x-sipro");
6196 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
6197 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
6198 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
6199 *codec_name = g_strdup ("Real Audio Lossless");
6200 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
6201 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
6202 *codec_name = g_strdup ("Sony ATRAC3");
6204 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6209 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
6212 for (i = 0; i < gst_caps_get_size (caps); i++) {
6213 gst_structure_set (gst_caps_get_structure (caps, i),
6214 "channels", G_TYPE_INT, audiocontext->channels,
6215 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
6219 caps = gst_caps_simplify (caps);
6226 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
6227 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
6229 GstCaps *caps = NULL;
6230 GstMatroskaTrackContext *context =
6231 (GstMatroskaTrackContext *) subtitlecontext;
6233 /* for backwards compatibility */
6234 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
6235 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
6236 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
6237 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
6238 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
6239 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
6240 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
6241 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
6243 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
6244 * Check if we have to do something with codec_private */
6245 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
6246 /* well, plain text simply does not have a lot of markup ... */
6247 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
6248 "pango-markup", NULL);
6249 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6250 subtitlecontext->check_markup = TRUE;
6251 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
6252 caps = gst_caps_new_empty_simple ("application/x-ssa");
6253 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6254 subtitlecontext->check_markup = FALSE;
6255 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
6256 caps = gst_caps_new_empty_simple ("application/x-ass");
6257 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6258 subtitlecontext->check_markup = FALSE;
6259 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
6260 caps = gst_caps_new_empty_simple ("application/x-usf");
6261 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6262 subtitlecontext->check_markup = FALSE;
6263 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
6264 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
6265 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
6266 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
6267 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
6268 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
6269 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
6270 context->stream_headers =
6271 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6272 context->codec_priv_size);
6273 /* FIXME: mark stream as broken and skip if there are no stream headers */
6274 context->send_stream_headers = TRUE;
6276 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
6277 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
6280 if (data != NULL && size > 0) {
6283 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
6284 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
6285 gst_buffer_unref (buf);
6293 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
6295 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6297 GST_OBJECT_LOCK (demux);
6298 if (demux->common.element_index)
6299 gst_object_unref (demux->common.element_index);
6300 demux->common.element_index = index ? gst_object_ref (index) : NULL;
6301 GST_OBJECT_UNLOCK (demux);
6302 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
6303 demux->common.element_index);
6307 gst_matroska_demux_get_index (GstElement * element)
6309 GstIndex *result = NULL;
6310 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6312 GST_OBJECT_LOCK (demux);
6313 if (demux->common.element_index)
6314 result = gst_object_ref (demux->common.element_index);
6315 GST_OBJECT_UNLOCK (demux);
6317 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
6323 static GstStateChangeReturn
6324 gst_matroska_demux_change_state (GstElement * element,
6325 GstStateChange transition)
6327 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6328 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
6330 /* handle upwards state changes here */
6331 switch (transition) {
6336 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
6338 /* handle downwards state changes */
6339 switch (transition) {
6340 case GST_STATE_CHANGE_PAUSED_TO_READY:
6341 gst_matroska_demux_reset (GST_ELEMENT (demux));
6351 gst_matroska_demux_set_property (GObject * object,
6352 guint prop_id, const GValue * value, GParamSpec * pspec)
6354 GstMatroskaDemux *demux;
6356 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6357 demux = GST_MATROSKA_DEMUX (object);
6360 case PROP_MAX_GAP_TIME:
6361 GST_OBJECT_LOCK (demux);
6362 demux->max_gap_time = g_value_get_uint64 (value);
6363 GST_OBJECT_UNLOCK (demux);
6366 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6372 gst_matroska_demux_get_property (GObject * object,
6373 guint prop_id, GValue * value, GParamSpec * pspec)
6375 GstMatroskaDemux *demux;
6377 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6378 demux = GST_MATROSKA_DEMUX (object);
6381 case PROP_MAX_GAP_TIME:
6382 GST_OBJECT_LOCK (demux);
6383 g_value_set_uint64 (value, demux->max_gap_time);
6384 GST_OBJECT_UNLOCK (demux);
6387 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6393 gst_matroska_demux_plugin_init (GstPlugin * plugin)
6397 /* parser helper separate debug */
6398 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
6399 0, "EBML stream helper class");
6401 /* create an elementfactory for the matroska_demux element */
6402 if (!gst_element_register (plugin, "matroskademux",
6403 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))