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 /* Opus GstAudioClippingMeta units are scaled by 48000/sample_rate.
4062 That is, if a Opus track has audio encoded at 24000 Hz and 132
4063 samples need to be clipped, GstAudioClippingMeta.start will be
4064 set to 264. (This is also the case for buffer offsets.)
4065 Opus sample rates are always divisors of 48000 Hz, which is the
4066 maximum allowed sample rate. */
4068 gst_util_uint64_scale_round (stream->codec_delay, 48000,
4071 if (GST_BUFFER_DURATION_IS_VALID (sub)) {
4072 if (GST_BUFFER_DURATION (sub) > stream->codec_delay)
4073 GST_BUFFER_DURATION (sub) -= stream->codec_delay;
4075 GST_BUFFER_DURATION (sub) = 0;
4080 if (block_discardpadding) {
4082 gst_util_uint64_scale_round (block_discardpadding, 48000,
4086 if (start_clip || end_clip) {
4087 gst_buffer_add_audio_clipping_meta (sub, GST_FORMAT_DEFAULT,
4088 start_clip, end_clip);
4092 if (GST_BUFFER_PTS_IS_VALID (sub)) {
4093 stream->pos = GST_BUFFER_PTS (sub);
4094 if (GST_BUFFER_DURATION_IS_VALID (sub))
4095 stream->pos += GST_BUFFER_DURATION (sub);
4096 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
4097 stream->pos = GST_BUFFER_DTS (sub);
4098 if (GST_BUFFER_DURATION_IS_VALID (sub))
4099 stream->pos += GST_BUFFER_DURATION (sub);
4102 ret = gst_pad_push (stream->pad, sub);
4104 if (demux->common.segment.rate < 0) {
4105 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
4106 /* In reverse playback we can get a GST_FLOW_EOS when
4107 * we are at the end of the segment, so we just need to jump
4108 * back to the previous section. */
4109 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
4114 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
4118 size -= lace_size[n];
4119 if (lace_time != GST_CLOCK_TIME_NONE && duration)
4120 lace_time += duration / laces;
4122 lace_time = GST_CLOCK_TIME_NONE;
4128 gst_buffer_unmap (buf, &map);
4129 gst_buffer_unref (buf);
4141 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
4147 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
4148 /* non-fatal, try next block(group) */
4154 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
4155 /* non-fatal, try next block(group) */
4161 /* return FALSE if block(group) should be skipped (due to a seek) */
4162 static inline gboolean
4163 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
4165 if (G_UNLIKELY (demux->seek_block)) {
4166 if (!(--demux->seek_block)) {
4169 GST_LOG_OBJECT (demux, "should skip block due to seek");
4177 static GstFlowReturn
4178 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
4182 guint64 seek_pos = (guint64) - 1;
4183 guint32 seek_id = 0;
4186 DEBUG_ELEMENT_START (demux, ebml, "Seek");
4188 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4189 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4193 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4194 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4198 case GST_MATROSKA_ID_SEEKID:
4202 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4205 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
4210 case GST_MATROSKA_ID_SEEKPOSITION:
4214 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4217 if (t > G_MAXINT64) {
4218 GST_WARNING_OBJECT (demux,
4219 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
4223 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
4229 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
4235 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
4238 if (!seek_id || seek_pos == (guint64) - 1) {
4239 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
4240 G_GUINT64_FORMAT ")", seek_id, seek_pos);
4245 case GST_MATROSKA_ID_SEEKHEAD:
4248 case GST_MATROSKA_ID_CUES:
4249 case GST_MATROSKA_ID_TAGS:
4250 case GST_MATROSKA_ID_TRACKS:
4251 case GST_MATROSKA_ID_SEGMENTINFO:
4252 case GST_MATROSKA_ID_ATTACHMENTS:
4253 case GST_MATROSKA_ID_CHAPTERS:
4255 guint64 before_pos, length;
4259 length = gst_matroska_read_common_get_length (&demux->common);
4260 before_pos = demux->common.offset;
4262 if (length == (guint64) - 1) {
4263 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
4267 /* check for validity */
4268 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
4269 GST_WARNING_OBJECT (demux,
4270 "SeekHead reference lies outside file!" " (%"
4271 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
4272 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
4277 /* only pick up index location when streaming */
4278 if (demux->streaming) {
4279 if (seek_id == GST_MATROSKA_ID_CUES) {
4280 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
4281 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
4282 demux->index_offset);
4288 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
4291 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4292 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
4296 if (id != seek_id) {
4297 GST_WARNING_OBJECT (demux,
4298 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
4299 seek_id, id, seek_pos + demux->common.ebml_segment_start);
4302 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4307 demux->common.offset = before_pos;
4311 case GST_MATROSKA_ID_CLUSTER:
4313 guint64 pos = seek_pos + demux->common.ebml_segment_start;
4315 GST_LOG_OBJECT (demux, "Cluster position");
4316 if (G_UNLIKELY (!demux->clusters))
4317 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
4318 g_array_append_val (demux->clusters, pos);
4323 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
4326 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4331 static GstFlowReturn
4332 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4334 GstFlowReturn ret = GST_FLOW_OK;
4337 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4339 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4340 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4344 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4345 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4349 case GST_MATROSKA_ID_SEEKENTRY:
4351 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
4352 /* Ignore EOS and errors here */
4353 if (ret != GST_FLOW_OK) {
4354 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4361 ret = gst_matroska_read_common_parse_skip (&demux->common,
4362 ebml, "SeekHead", id);
4367 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4369 /* Sort clusters by position for easier searching */
4370 if (demux->clusters)
4371 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4376 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
4378 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4380 static inline GstFlowReturn
4381 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4383 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4384 /* only a few blocks are expected/allowed to be large,
4385 * and will be recursed into, whereas others will be read and must fit */
4386 if (demux->streaming) {
4387 /* fatal in streaming case, as we can't step over easily */
4388 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4389 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4390 "file might be corrupt.", bytes));
4391 return GST_FLOW_ERROR;
4393 /* indicate higher level to quietly give up */
4394 GST_DEBUG_OBJECT (demux,
4395 "too large block of size %" G_GUINT64_FORMAT, bytes);
4396 return GST_FLOW_ERROR;
4403 /* returns TRUE if we truely are in error state, and should give up */
4404 static inline GstFlowReturn
4405 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4407 if (!demux->streaming && demux->next_cluster_offset > 0) {
4408 /* just repositioning to where next cluster should be and try from there */
4409 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4410 G_GUINT64_FORMAT, demux->next_cluster_offset);
4411 demux->common.offset = demux->next_cluster_offset;
4412 demux->next_cluster_offset = 0;
4418 /* sigh, one last attempt above and beyond call of duty ...;
4419 * search for cluster mark following current pos */
4420 pos = demux->common.offset;
4421 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4422 if ((ret = gst_matroska_demux_search_cluster (demux, &pos, TRUE)) !=
4424 /* did not work, give up */
4427 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4428 /* try that position */
4429 demux->common.offset = pos;
4435 static inline GstFlowReturn
4436 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4438 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4439 demux->common.offset += flush;
4440 if (demux->streaming) {
4443 /* hard to skip large blocks when streaming */
4444 ret = gst_matroska_demux_check_read_size (demux, flush);
4445 if (ret != GST_FLOW_OK)
4447 if (flush <= gst_adapter_available (demux->common.adapter))
4448 gst_adapter_flush (demux->common.adapter, flush);
4450 return GST_FLOW_EOS;
4455 /* initializes @ebml with @bytes from input stream at current offset.
4456 * Returns EOS if insufficient available,
4457 * ERROR if too much was attempted to read. */
4458 static inline GstFlowReturn
4459 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4462 GstBuffer *buffer = NULL;
4463 GstFlowReturn ret = GST_FLOW_OK;
4465 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4467 ret = gst_matroska_demux_check_read_size (demux, bytes);
4468 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4469 if (!demux->streaming) {
4470 /* in pull mode, we can skip */
4471 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4472 ret = GST_FLOW_OVERFLOW;
4474 /* otherwise fatal */
4475 ret = GST_FLOW_ERROR;
4479 if (demux->streaming) {
4480 if (gst_adapter_available (demux->common.adapter) >= bytes)
4481 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4485 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4486 demux->common.offset, bytes, &buffer, NULL);
4487 if (G_LIKELY (buffer)) {
4488 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4489 demux->common.offset);
4490 demux->common.offset += bytes;
4497 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4500 gboolean seekable = FALSE;
4501 gint64 start = -1, stop = -1;
4503 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4504 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4505 GST_DEBUG_OBJECT (demux, "seeking query failed");
4509 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4511 /* try harder to query upstream size if we didn't get it the first time */
4512 if (seekable && stop == -1) {
4513 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4514 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4518 /* if upstream doesn't know the size, it's likely that it's not seekable in
4519 * practice even if it technically may be seekable */
4520 if (seekable && (start != 0 || stop <= start)) {
4521 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4526 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4527 G_GUINT64_FORMAT ")", seekable, start, stop);
4528 demux->seekable = seekable;
4530 gst_query_unref (query);
4533 static GstFlowReturn
4534 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4540 GstFlowReturn ret = GST_FLOW_OK;
4542 GST_WARNING_OBJECT (demux,
4543 "Found Cluster element before Tracks, searching Tracks");
4546 before_pos = demux->common.offset;
4548 /* Search Tracks element */
4550 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4551 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4552 if (ret != GST_FLOW_OK)
4555 if (id != GST_MATROSKA_ID_TRACKS) {
4556 /* we may be skipping large cluster here, so forego size check etc */
4557 /* ... but we can't skip undefined size; force error */
4558 if (length == G_MAXUINT64) {
4559 ret = gst_matroska_demux_check_read_size (demux, length);
4562 demux->common.offset += needed;
4563 demux->common.offset += length;
4568 /* will lead to track parsing ... */
4569 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4574 demux->common.offset = before_pos;
4579 #define GST_READ_CHECK(stmt) \
4581 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4582 if (ret == GST_FLOW_OVERFLOW) { \
4583 ret = GST_FLOW_OK; \
4589 static GstFlowReturn
4590 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4591 guint64 length, guint needed)
4593 GstEbmlRead ebml = { 0, };
4594 GstFlowReturn ret = GST_FLOW_OK;
4597 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4598 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4600 /* if we plan to read and parse this element, we need prefix (id + length)
4601 * and the contents */
4602 /* mind about overflow wrap-around when dealing with undefined size */
4604 if (G_LIKELY (length != G_MAXUINT64))
4607 switch (demux->common.state) {
4608 case GST_MATROSKA_READ_STATE_START:
4610 case GST_EBML_ID_HEADER:
4611 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4612 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4613 if (ret != GST_FLOW_OK)
4615 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4616 gst_matroska_demux_check_seekability (demux);
4619 goto invalid_header;
4623 case GST_MATROSKA_READ_STATE_SEGMENT:
4625 case GST_MATROSKA_ID_SEGMENT:
4626 /* eat segment prefix */
4627 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4628 GST_DEBUG_OBJECT (demux,
4629 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4630 G_GUINT64_FORMAT, demux->common.offset, length);
4631 /* seeks are from the beginning of the segment,
4632 * after the segment ID/length */
4633 demux->common.ebml_segment_start = demux->common.offset;
4635 length = G_MAXUINT64;
4636 demux->common.ebml_segment_length = length;
4637 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4640 GST_WARNING_OBJECT (demux,
4641 "Expected a Segment ID (0x%x), but received 0x%x!",
4642 GST_MATROSKA_ID_SEGMENT, id);
4643 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4647 case GST_MATROSKA_READ_STATE_SCANNING:
4648 if (id != GST_MATROSKA_ID_CLUSTER &&
4649 id != GST_MATROSKA_ID_CLUSTERTIMECODE) {
4650 if (demux->common.start_resync_offset != -1) {
4651 /* we need to skip byte per byte if we are scanning for a new cluster
4652 * after invalid data is found
4658 if (demux->common.start_resync_offset != -1) {
4659 GST_LOG_OBJECT (demux, "Resync done, new cluster found!");
4660 demux->common.start_resync_offset = -1;
4661 demux->common.state = demux->common.state_to_restore;
4665 case GST_MATROSKA_READ_STATE_HEADER:
4666 case GST_MATROSKA_READ_STATE_DATA:
4667 case GST_MATROSKA_READ_STATE_SEEK:
4669 case GST_MATROSKA_ID_SEGMENTINFO:
4670 if (!demux->common.segmentinfo_parsed) {
4671 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4672 ret = gst_matroska_read_common_parse_info (&demux->common,
4673 GST_ELEMENT_CAST (demux), &ebml);
4674 if (ret == GST_FLOW_OK)
4675 gst_matroska_demux_send_tags (demux);
4677 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4680 case GST_MATROSKA_ID_TRACKS:
4681 if (!demux->tracks_parsed) {
4682 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4683 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4685 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4688 case GST_MATROSKA_ID_CLUSTER:
4689 if (G_UNLIKELY (!demux->tracks_parsed)) {
4690 if (demux->streaming) {
4691 GST_DEBUG_OBJECT (demux, "Cluster before Track");
4692 goto not_streamable;
4694 ret = gst_matroska_demux_find_tracks (demux);
4695 if (!demux->tracks_parsed)
4699 if (G_UNLIKELY (demux->common.state
4700 == GST_MATROSKA_READ_STATE_HEADER)) {
4701 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4702 demux->first_cluster_offset = demux->common.offset;
4703 if (!demux->streaming &&
4704 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.duration)) {
4705 GstMatroskaIndex *last = NULL;
4707 GST_DEBUG_OBJECT (demux,
4708 "estimating duration using last cluster");
4709 if ((last = gst_matroska_demux_search_pos (demux,
4710 GST_CLOCK_TIME_NONE)) != NULL) {
4711 demux->last_cluster_offset =
4712 last->pos + demux->common.ebml_segment_start;
4713 demux->stream_last_time = last->time;
4714 demux->common.segment.duration =
4715 demux->stream_last_time - demux->stream_start_time;
4716 /* above estimate should not be taken all too strongly */
4717 demux->invalid_duration = TRUE;
4718 GST_DEBUG_OBJECT (demux,
4719 "estimated duration as %" GST_TIME_FORMAT,
4720 GST_TIME_ARGS (demux->common.segment.duration));
4723 GST_DEBUG_OBJECT (demux, "signaling no more pads");
4724 gst_element_no_more_pads (GST_ELEMENT (demux));
4725 /* send initial segment - we wait till we know the first
4726 incoming timestamp, so we can properly set the start of
4728 demux->need_segment = TRUE;
4730 demux->cluster_time = GST_CLOCK_TIME_NONE;
4731 demux->cluster_offset = demux->common.offset;
4732 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4733 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4734 " not found in Cluster, trying next Cluster's first block instead",
4736 demux->seek_block = 0;
4738 demux->seek_first = FALSE;
4739 /* record next cluster for recovery */
4740 if (read != G_MAXUINT64)
4741 demux->next_cluster_offset = demux->cluster_offset + read;
4742 /* eat cluster prefix */
4743 gst_matroska_demux_flush (demux, needed);
4745 case GST_MATROSKA_ID_CLUSTERTIMECODE:
4749 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4750 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4752 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4753 demux->cluster_time = num;
4754 /* track last cluster */
4755 if (demux->cluster_offset > demux->last_cluster_offset) {
4756 demux->last_cluster_offset = demux->cluster_offset;
4757 demux->stream_last_time =
4758 demux->cluster_time * demux->common.time_scale;
4761 if (demux->common.element_index) {
4762 if (demux->common.element_index_writer_id == -1)
4763 gst_index_get_writer_id (demux->common.element_index,
4764 GST_OBJECT (demux), &demux->common.element_index_writer_id);
4765 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4766 G_GUINT64_FORMAT " for writer id %d",
4767 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4768 demux->common.element_index_writer_id);
4769 gst_index_add_association (demux->common.element_index,
4770 demux->common.element_index_writer_id,
4771 GST_ASSOCIATION_FLAG_KEY_UNIT,
4772 GST_FORMAT_TIME, demux->cluster_time,
4773 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4778 case GST_MATROSKA_ID_BLOCKGROUP:
4779 if (!gst_matroska_demux_seek_block (demux))
4781 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4782 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4783 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4784 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4785 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4787 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4789 case GST_MATROSKA_ID_SIMPLEBLOCK:
4790 if (!gst_matroska_demux_seek_block (demux))
4792 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4793 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4794 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4795 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4796 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4798 case GST_MATROSKA_ID_ATTACHMENTS:
4799 if (!demux->common.attachments_parsed) {
4800 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4801 ret = gst_matroska_read_common_parse_attachments (&demux->common,
4802 GST_ELEMENT_CAST (demux), &ebml);
4803 if (ret == GST_FLOW_OK)
4804 gst_matroska_demux_send_tags (demux);
4806 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4809 case GST_MATROSKA_ID_TAGS:
4810 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4811 ret = gst_matroska_read_common_parse_metadata (&demux->common,
4812 GST_ELEMENT_CAST (demux), &ebml);
4813 if (ret == GST_FLOW_OK)
4814 gst_matroska_demux_send_tags (demux);
4816 case GST_MATROSKA_ID_CHAPTERS:
4817 if (!demux->common.chapters_parsed) {
4818 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4820 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4822 if (demux->common.toc) {
4823 gst_matroska_demux_send_event (demux,
4824 gst_event_new_toc (demux->common.toc, FALSE));
4827 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4829 case GST_MATROSKA_ID_SEEKHEAD:
4830 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4831 ret = gst_matroska_demux_parse_contents (demux, &ebml);
4833 case GST_MATROSKA_ID_CUES:
4834 if (demux->common.index_parsed) {
4835 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4838 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4839 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4840 /* only push based; delayed index building */
4841 if (ret == GST_FLOW_OK
4842 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4845 GST_OBJECT_LOCK (demux);
4846 event = demux->seek_event;
4847 demux->seek_event = NULL;
4848 GST_OBJECT_UNLOCK (demux);
4851 /* unlikely to fail, since we managed to seek to this point */
4852 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
4853 gst_event_unref (event);
4856 gst_event_unref (event);
4857 /* resume data handling, main thread clear to seek again */
4858 GST_OBJECT_LOCK (demux);
4859 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4860 GST_OBJECT_UNLOCK (demux);
4863 case GST_MATROSKA_ID_POSITION:
4864 case GST_MATROSKA_ID_PREVSIZE:
4865 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4866 case GST_MATROSKA_ID_SILENTTRACKS:
4867 GST_DEBUG_OBJECT (demux,
4868 "Skipping Cluster subelement 0x%x - ignoring", id);
4872 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4873 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4879 if (ret == GST_FLOW_PARSE)
4883 gst_ebml_read_clear (&ebml);
4889 /* simply exit, maybe not enough data yet */
4890 /* no ebml to clear if read error */
4895 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4896 ("Failed to parse Element 0x%x", id));
4897 ret = GST_FLOW_ERROR;
4902 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4903 ("File layout does not permit streaming"));
4904 ret = GST_FLOW_ERROR;
4909 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4910 ("No Tracks element found"));
4911 ret = GST_FLOW_ERROR;
4916 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4917 ret = GST_FLOW_ERROR;
4922 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4923 ret = GST_FLOW_ERROR;
4929 gst_matroska_demux_loop (GstPad * pad)
4931 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4937 /* If we have to close a segment, send a new segment to do this now */
4938 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4939 if (G_UNLIKELY (demux->new_segment)) {
4940 gst_matroska_demux_send_event (demux, demux->new_segment);
4941 demux->new_segment = NULL;
4945 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4946 GST_ELEMENT_CAST (demux), &id, &length, &needed);
4947 if (ret == GST_FLOW_EOS) {
4949 } else if (ret == GST_FLOW_FLUSHING) {
4951 } else if (ret != GST_FLOW_OK) {
4952 ret = gst_matroska_demux_check_parse_error (demux);
4954 /* Only handle EOS as no error if we're outside the segment already */
4955 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4956 && demux->common.offset >=
4957 demux->common.ebml_segment_start +
4958 demux->common.ebml_segment_length))
4960 else if (ret != GST_FLOW_OK)
4966 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4967 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4970 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4971 if (ret == GST_FLOW_EOS)
4973 if (ret != GST_FLOW_OK)
4976 /* check if we're at the end of a configured segment */
4977 if (G_LIKELY (demux->common.src->len)) {
4980 g_assert (demux->common.num_streams == demux->common.src->len);
4981 for (i = 0; i < demux->common.src->len; i++) {
4982 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4984 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4985 GST_TIME_ARGS (context->pos));
4986 if (context->eos == FALSE)
4990 GST_INFO_OBJECT (demux, "All streams are EOS");
4996 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4997 demux->common.offset >= demux->cached_length)) {
4998 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4999 if (demux->common.offset == demux->cached_length) {
5000 GST_LOG_OBJECT (demux, "Reached end of stream");
5011 if (demux->common.segment.rate < 0.0) {
5012 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
5013 if (ret == GST_FLOW_OK)
5020 const gchar *reason = gst_flow_get_name (ret);
5021 gboolean push_eos = FALSE;
5023 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
5024 gst_pad_pause_task (demux->common.sinkpad);
5026 if (ret == GST_FLOW_EOS) {
5027 /* perform EOS logic */
5029 /* If we were in the headers, make sure we send no-more-pads.
5030 This will ensure decodebin does not get stuck thinking
5031 the chain is not complete yet, and waiting indefinitely. */
5032 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
5033 if (demux->common.src->len == 0) {
5034 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
5035 ("No pads created"));
5037 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
5038 ("Failed to finish reading headers"));
5040 gst_element_no_more_pads (GST_ELEMENT (demux));
5043 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
5048 /* for segment playback we need to post when (in stream time)
5049 * we stopped, this is either stop (when set) or the duration. */
5050 if ((stop = demux->common.segment.stop) == -1)
5051 stop = demux->last_stop_end;
5053 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
5054 msg = gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
5056 if (demux->segment_seqnum)
5057 gst_message_set_seqnum (msg, demux->segment_seqnum);
5058 gst_element_post_message (GST_ELEMENT (demux), msg);
5060 event = gst_event_new_segment_done (GST_FORMAT_TIME, stop);
5061 if (demux->segment_seqnum)
5062 gst_event_set_seqnum (event, demux->segment_seqnum);
5063 gst_matroska_demux_send_event (demux, event);
5067 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
5068 /* for fatal errors we post an error message */
5069 GST_ELEMENT_FLOW_ERROR (demux, ret);
5075 /* send EOS, and prevent hanging if no streams yet */
5076 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
5077 event = gst_event_new_eos ();
5078 if (demux->segment_seqnum)
5079 gst_event_set_seqnum (event, demux->segment_seqnum);
5080 if (!gst_matroska_demux_send_event (demux, event) &&
5081 (ret == GST_FLOW_EOS)) {
5082 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5083 (NULL), ("got eos but no streams (yet)"));
5091 * Create and push a flushing seek event upstream
5094 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
5095 guint32 seqnum, GstSeekFlags flags)
5100 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
5103 gst_event_new_seek (rate, GST_FORMAT_BYTES,
5104 flags | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
5105 GST_SEEK_TYPE_SET, offset, GST_SEEK_TYPE_NONE, -1);
5106 gst_event_set_seqnum (event, seqnum);
5108 res = gst_pad_push_event (demux->common.sinkpad, event);
5110 /* segment event will update offset */
5114 static GstFlowReturn
5115 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
5117 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5119 GstFlowReturn ret = GST_FLOW_OK;
5124 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
5125 GST_DEBUG_OBJECT (demux, "got DISCONT");
5126 gst_adapter_clear (demux->common.adapter);
5127 GST_OBJECT_LOCK (demux);
5128 gst_matroska_read_common_reset_streams (&demux->common,
5129 GST_CLOCK_TIME_NONE, FALSE);
5130 GST_OBJECT_UNLOCK (demux);
5133 gst_adapter_push (demux->common.adapter, buffer);
5137 available = gst_adapter_available (demux->common.adapter);
5139 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
5140 GST_ELEMENT_CAST (demux), &id, &length, &needed);
5141 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
5142 if (demux->common.ebml_segment_length != G_MAXUINT64
5143 && demux->common.offset >=
5144 demux->common.ebml_segment_start + demux->common.ebml_segment_length) {
5147 gint64 bytes_scanned;
5148 if (demux->common.start_resync_offset == -1) {
5149 demux->common.start_resync_offset = demux->common.offset;
5150 demux->common.state_to_restore = demux->common.state;
5152 bytes_scanned = demux->common.offset - demux->common.start_resync_offset;
5153 if (bytes_scanned <= INVALID_DATA_THRESHOLD) {
5154 GST_WARNING_OBJECT (demux,
5155 "parse error, looking for next cluster, actual offset %"
5156 G_GUINT64_FORMAT ", start resync offset %" G_GUINT64_FORMAT,
5157 demux->common.offset, demux->common.start_resync_offset);
5158 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
5161 GST_WARNING_OBJECT (demux,
5162 "unrecoverable parse error, next cluster not found and threshold "
5163 "exceeded, bytes scanned %" G_GINT64_FORMAT, bytes_scanned);
5169 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
5170 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
5171 demux->common.offset, id, length, needed, available);
5173 if (needed > available)
5176 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5177 if (ret == GST_FLOW_EOS) {
5178 /* need more data */
5180 } else if (ret != GST_FLOW_OK) {
5187 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
5190 gboolean res = TRUE;
5191 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5193 GST_DEBUG_OBJECT (demux,
5194 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
5196 switch (GST_EVENT_TYPE (event)) {
5197 case GST_EVENT_SEGMENT:
5199 const GstSegment *segment;
5201 /* some debug output */
5202 gst_event_parse_segment (event, &segment);
5203 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
5204 GST_DEBUG_OBJECT (demux,
5205 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
5208 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
5209 GST_DEBUG_OBJECT (demux, "still starting");
5213 /* we only expect a BYTE segment, e.g. following a seek */
5214 if (segment->format != GST_FORMAT_BYTES) {
5215 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
5219 GST_DEBUG_OBJECT (demux, "clearing segment state");
5220 GST_OBJECT_LOCK (demux);
5221 /* clear current segment leftover */
5222 gst_adapter_clear (demux->common.adapter);
5223 /* and some streaming setup */
5224 demux->common.offset = segment->start;
5225 /* accumulate base based on current position */
5226 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
5227 demux->common.segment.base +=
5228 (MAX (demux->common.segment.position, demux->stream_start_time)
5229 - demux->stream_start_time) / fabs (demux->common.segment.rate);
5230 /* do not know where we are;
5231 * need to come across a cluster and generate segment */
5232 demux->common.segment.position = GST_CLOCK_TIME_NONE;
5233 demux->cluster_time = GST_CLOCK_TIME_NONE;
5234 demux->cluster_offset = 0;
5235 demux->need_segment = TRUE;
5236 demux->segment_seqnum = gst_event_get_seqnum (event);
5237 /* but keep some of the upstream segment */
5238 demux->common.segment.rate = segment->rate;
5239 demux->common.segment.flags = segment->flags;
5240 /* also check if need to keep some of the requested seek position */
5241 if (demux->seek_offset == segment->start) {
5242 GST_DEBUG_OBJECT (demux, "position matches requested seek");
5243 demux->common.segment.position = demux->requested_seek_time;
5245 GST_DEBUG_OBJECT (demux, "unexpected segment position");
5247 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
5248 demux->seek_offset = -1;
5249 GST_OBJECT_UNLOCK (demux);
5251 /* chain will send initial segment after pads have been added,
5252 * or otherwise come up with one */
5253 GST_DEBUG_OBJECT (demux, "eating event");
5254 gst_event_unref (event);
5260 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA
5261 && demux->common.state != GST_MATROSKA_READ_STATE_SCANNING) {
5262 gst_event_unref (event);
5263 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5264 (NULL), ("got eos and didn't receive a complete header object"));
5265 } else if (demux->common.num_streams == 0) {
5266 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5267 (NULL), ("got eos but no streams (yet)"));
5269 gst_matroska_demux_send_event (demux, event);
5273 case GST_EVENT_FLUSH_STOP:
5277 gst_adapter_clear (demux->common.adapter);
5278 GST_OBJECT_LOCK (demux);
5279 gst_matroska_read_common_reset_streams (&demux->common,
5280 GST_CLOCK_TIME_NONE, TRUE);
5281 gst_flow_combiner_reset (demux->flowcombiner);
5282 dur = demux->common.segment.duration;
5283 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
5284 demux->common.segment.duration = dur;
5285 demux->cluster_time = GST_CLOCK_TIME_NONE;
5286 demux->cluster_offset = 0;
5287 GST_OBJECT_UNLOCK (demux);
5291 res = gst_pad_event_default (pad, parent, event);
5299 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
5301 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5303 gboolean pull_mode = FALSE;
5305 query = gst_query_new_scheduling ();
5307 if (gst_pad_peer_query (sinkpad, query))
5308 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
5309 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
5311 gst_query_unref (query);
5314 GST_DEBUG ("going to pull mode");
5315 demux->streaming = FALSE;
5316 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
5318 GST_DEBUG ("going to push (streaming) mode");
5319 demux->streaming = TRUE;
5320 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
5325 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
5326 GstPadMode mode, gboolean active)
5329 case GST_PAD_MODE_PULL:
5331 /* if we have a scheduler we can start the task */
5332 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
5335 gst_pad_stop_task (sinkpad);
5338 case GST_PAD_MODE_PUSH:
5346 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
5347 videocontext, const gchar * codec_id, guint8 * data, guint size,
5348 gchar ** codec_name, guint32 * riff_fourcc)
5350 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
5351 GstCaps *caps = NULL;
5353 g_assert (videocontext != NULL);
5354 g_assert (codec_name != NULL);
5359 /* TODO: check if we have all codec types from matroska-ids.h
5360 * check if we have to do more special things with codec_private
5363 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
5364 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
5367 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
5368 gst_riff_strf_vids *vids = NULL;
5371 GstBuffer *buf = NULL;
5373 vids = (gst_riff_strf_vids *) data;
5375 /* assure size is big enough */
5377 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
5380 if (size < sizeof (gst_riff_strf_vids)) {
5381 vids = g_new (gst_riff_strf_vids, 1);
5382 memcpy (vids, data, size);
5385 context->dts_only = TRUE; /* VFW files only store DTS */
5387 /* little-endian -> byte-order */
5388 vids->size = GUINT32_FROM_LE (vids->size);
5389 vids->width = GUINT32_FROM_LE (vids->width);
5390 vids->height = GUINT32_FROM_LE (vids->height);
5391 vids->planes = GUINT16_FROM_LE (vids->planes);
5392 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
5393 vids->compression = GUINT32_FROM_LE (vids->compression);
5394 vids->image_size = GUINT32_FROM_LE (vids->image_size);
5395 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
5396 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
5397 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
5398 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
5400 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
5401 gsize offset = sizeof (gst_riff_strf_vids);
5404 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
5405 size - offset), size - offset);
5409 *riff_fourcc = vids->compression;
5411 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
5412 buf, NULL, codec_name);
5415 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
5416 GST_FOURCC_ARGS (vids->compression));
5418 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
5419 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
5420 "video/x-compressed-yuv");
5421 context->intra_only =
5422 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
5426 gst_buffer_unref (buf);
5428 if (vids != (gst_riff_strf_vids *) data)
5431 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
5433 GstVideoFormat format;
5435 gst_video_info_init (&info);
5436 switch (videocontext->fourcc) {
5437 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5438 format = GST_VIDEO_FORMAT_I420;
5440 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5441 format = GST_VIDEO_FORMAT_YUY2;
5443 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5444 format = GST_VIDEO_FORMAT_YV12;
5446 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5447 format = GST_VIDEO_FORMAT_UYVY;
5449 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5450 format = GST_VIDEO_FORMAT_AYUV;
5452 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
5453 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
5454 format = GST_VIDEO_FORMAT_GRAY8;
5456 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
5457 format = GST_VIDEO_FORMAT_RGB;
5459 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
5460 format = GST_VIDEO_FORMAT_BGR;
5463 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5464 GST_FOURCC_ARGS (videocontext->fourcc));
5468 context->intra_only = TRUE;
5470 gst_video_info_set_format (&info, format, videocontext->pixel_width,
5471 videocontext->pixel_height);
5472 caps = gst_video_info_to_caps (&info);
5473 *codec_name = gst_pb_utils_get_codec_description (caps);
5474 context->alignment = 32;
5475 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5476 caps = gst_caps_new_simple ("video/x-divx",
5477 "divxversion", G_TYPE_INT, 4, NULL);
5478 *codec_name = g_strdup ("MPEG-4 simple profile");
5479 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5480 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5481 caps = gst_caps_new_simple ("video/mpeg",
5482 "mpegversion", G_TYPE_INT, 4,
5483 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5487 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5488 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5489 gst_buffer_unref (priv);
5491 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
5493 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5494 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5496 *codec_name = g_strdup ("MPEG-4 advanced profile");
5497 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5499 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5500 "divxversion", G_TYPE_INT, 3, NULL),
5501 gst_structure_new ("video/x-msmpeg",
5502 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5504 caps = gst_caps_new_simple ("video/x-msmpeg",
5505 "msmpegversion", G_TYPE_INT, 43, NULL);
5506 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5507 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5508 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5511 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5516 caps = gst_caps_new_simple ("video/mpeg",
5517 "systemstream", G_TYPE_BOOLEAN, FALSE,
5518 "mpegversion", G_TYPE_INT, mpegversion, NULL);
5519 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5520 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5521 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5522 caps = gst_caps_new_empty_simple ("image/jpeg");
5523 *codec_name = g_strdup ("Motion-JPEG");
5524 context->intra_only = TRUE;
5525 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5526 caps = gst_caps_new_empty_simple ("video/x-h264");
5530 /* First byte is the version, second is the profile indication, and third
5531 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5532 * level indication. */
5533 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5536 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5537 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5538 gst_buffer_unref (priv);
5540 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5541 "alignment", G_TYPE_STRING, "au", NULL);
5543 GST_WARNING ("No codec data found, assuming output is byte-stream");
5544 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5547 *codec_name = g_strdup ("H264");
5548 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
5549 caps = gst_caps_new_empty_simple ("video/x-h265");
5553 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
5556 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5557 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5558 gst_buffer_unref (priv);
5560 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
5561 "alignment", G_TYPE_STRING, "au", NULL);
5563 GST_WARNING ("No codec data found, assuming output is byte-stream");
5564 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5567 *codec_name = g_strdup ("HEVC");
5568 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5569 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5570 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5571 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5572 gint rmversion = -1;
5574 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5576 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5578 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5580 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5583 caps = gst_caps_new_simple ("video/x-pn-realvideo",
5584 "rmversion", G_TYPE_INT, rmversion, NULL);
5585 GST_DEBUG ("data:%p, size:0x%x", data, size);
5586 /* We need to extract the extradata ! */
5587 if (data && (size >= 0x22)) {
5592 subformat = GST_READ_UINT32_BE (data + 0x1a);
5593 rformat = GST_READ_UINT32_BE (data + 0x1e);
5596 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5598 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5599 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5600 gst_buffer_unref (priv);
5603 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5604 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5605 caps = gst_caps_new_empty_simple ("video/x-theora");
5606 context->stream_headers =
5607 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5608 context->codec_priv_size);
5609 /* FIXME: mark stream as broken and skip if there are no stream headers */
5610 context->send_stream_headers = TRUE;
5611 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5612 caps = gst_caps_new_empty_simple ("video/x-dirac");
5613 *codec_name = g_strdup_printf ("Dirac");
5614 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5615 caps = gst_caps_new_empty_simple ("video/x-vp8");
5616 *codec_name = g_strdup_printf ("On2 VP8");
5617 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5618 caps = gst_caps_new_empty_simple ("video/x-vp9");
5619 *codec_name = g_strdup_printf ("On2 VP9");
5620 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_AV1)) {
5621 caps = gst_caps_new_empty_simple ("video/x-av1");
5622 *codec_name = g_strdup_printf ("AOM AV1");
5623 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
5625 const gchar *variant, *variant_descr = "";
5627 /* Expect a fourcc in the codec private data */
5628 if (!data || size < 4) {
5629 GST_WARNING ("No or too small PRORESS fourcc (%d bytes)", size);
5633 fourcc = GST_STR_FOURCC (data);
5635 case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
5636 variant_descr = " 4:2:2 LT";
5639 case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
5641 variant_descr = " 4:2:2 HQ";
5643 case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
5645 variant_descr = " 4:4:4:4";
5647 case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
5649 variant_descr = " 4:2:2 Proxy";
5651 case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
5653 variant = "standard";
5654 variant_descr = " 4:2:2 SD";
5658 GST_LOG ("Prores video, codec fourcc %" GST_FOURCC_FORMAT,
5659 GST_FOURCC_ARGS (fourcc));
5661 caps = gst_caps_new_simple ("video/x-prores",
5662 "format", G_TYPE_STRING, variant, NULL);
5663 *codec_name = g_strdup_printf ("Apple ProRes%s", variant_descr);
5664 context->postprocess_frame = gst_matroska_demux_add_prores_header;
5666 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5672 GstStructure *structure;
5674 for (i = 0; i < gst_caps_get_size (caps); i++) {
5675 structure = gst_caps_get_structure (caps, i);
5677 /* FIXME: use the real unit here! */
5678 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5679 videocontext->pixel_width,
5680 videocontext->pixel_height,
5681 videocontext->display_width, videocontext->display_height);
5683 /* pixel width and height are the w and h of the video in pixels */
5684 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5685 gint w = videocontext->pixel_width;
5686 gint h = videocontext->pixel_height;
5688 gst_structure_set (structure,
5689 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5692 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5695 if (videocontext->display_width <= 0)
5696 videocontext->display_width = videocontext->pixel_width;
5697 if (videocontext->display_height <= 0)
5698 videocontext->display_height = videocontext->pixel_height;
5700 /* calculate the pixel aspect ratio using the display and pixel w/h */
5701 n = videocontext->display_width * videocontext->pixel_height;
5702 d = videocontext->display_height * videocontext->pixel_width;
5703 GST_DEBUG ("setting PAR to %d/%d", n, d);
5704 gst_structure_set (structure, "pixel-aspect-ratio",
5706 videocontext->display_width * videocontext->pixel_height,
5707 videocontext->display_height * videocontext->pixel_width, NULL);
5710 if (videocontext->default_fps > 0.0) {
5713 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5715 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5717 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5719 } else if (context->default_duration > 0) {
5722 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5724 GST_INFO ("using default duration %" G_GUINT64_FORMAT
5725 " framerate %d/%d", context->default_duration, fps_n, fps_d);
5727 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5728 fps_n, fps_d, NULL);
5730 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5734 if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5735 gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5738 if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
5739 if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
5740 videocontext->pixel_width, videocontext->pixel_height,
5741 videocontext->display_width * videocontext->pixel_height,
5742 videocontext->display_height * videocontext->pixel_width)) {
5743 videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
5745 gst_caps_set_simple (caps,
5746 "multiview-mode", G_TYPE_STRING,
5747 gst_video_multiview_mode_to_caps_string
5748 (videocontext->multiview_mode), "multiview-flags",
5749 GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
5750 GST_FLAG_SET_MASK_EXACT, NULL);
5753 if (videocontext->colorimetry.range != GST_VIDEO_COLOR_RANGE_UNKNOWN ||
5754 videocontext->colorimetry.matrix != GST_VIDEO_COLOR_MATRIX_UNKNOWN ||
5755 videocontext->colorimetry.transfer != GST_VIDEO_TRANSFER_UNKNOWN ||
5756 videocontext->colorimetry.primaries !=
5757 GST_VIDEO_COLOR_PRIMARIES_UNKNOWN) {
5758 gchar *colorimetry =
5759 gst_video_colorimetry_to_string (&videocontext->colorimetry);
5760 gst_caps_set_simple (caps, "colorimetry", G_TYPE_STRING, colorimetry,
5762 GST_DEBUG ("setting colorimetry to %s", colorimetry);
5763 g_free (colorimetry);
5766 caps = gst_caps_simplify (caps);
5773 * Some AAC specific code... *sigh*
5774 * FIXME: maybe we should use '15' and code the sample rate explicitly
5775 * if the sample rate doesn't match the predefined rates exactly? (tpm)
5779 aac_rate_idx (gint rate)
5783 else if (75132 <= rate)
5785 else if (55426 <= rate)
5787 else if (46009 <= rate)
5789 else if (37566 <= rate)
5791 else if (27713 <= rate)
5793 else if (23004 <= rate)
5795 else if (18783 <= rate)
5797 else if (13856 <= rate)
5799 else if (11502 <= rate)
5801 else if (9391 <= rate)
5808 aac_profile_idx (const gchar * codec_id)
5812 if (strlen (codec_id) <= 12)
5814 else if (!strncmp (&codec_id[12], "MAIN", 4))
5816 else if (!strncmp (&codec_id[12], "LC", 2))
5818 else if (!strncmp (&codec_id[12], "SSR", 3))
5827 round_up_pow2 (guint n)
5838 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5841 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5842 audiocontext, const gchar * codec_id, guint8 * data, guint size,
5843 gchar ** codec_name, guint16 * riff_audio_fmt)
5845 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5846 GstCaps *caps = NULL;
5848 g_assert (audiocontext != NULL);
5849 g_assert (codec_name != NULL);
5852 *riff_audio_fmt = 0;
5854 /* TODO: check if we have all codec types from matroska-ids.h
5855 * check if we have to do more special things with codec_private
5856 * check if we need bitdepth in different places too
5857 * implement channel position magic
5859 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5860 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5861 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5862 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5865 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5866 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5867 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5870 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5872 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5877 caps = gst_caps_new_simple ("audio/mpeg",
5878 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5879 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5880 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5881 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5884 GstAudioFormat format;
5886 sign = (audiocontext->bitdepth != 8);
5887 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5888 endianness = G_BIG_ENDIAN;
5890 endianness = G_LITTLE_ENDIAN;
5892 format = gst_audio_format_build_integer (sign, endianness,
5893 audiocontext->bitdepth, audiocontext->bitdepth);
5895 /* FIXME: Channel mask and reordering */
5896 caps = gst_caps_new_simple ("audio/x-raw",
5897 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5898 "layout", G_TYPE_STRING, "interleaved",
5899 "channel-mask", GST_TYPE_BITMASK,
5900 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5902 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5903 audiocontext->bitdepth);
5904 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5905 context->alignment = round_up_pow2 (context->alignment);
5906 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5907 const gchar *format;
5908 if (audiocontext->bitdepth == 32)
5912 /* FIXME: Channel mask and reordering */
5913 caps = gst_caps_new_simple ("audio/x-raw",
5914 "format", G_TYPE_STRING, format,
5915 "layout", G_TYPE_STRING, "interleaved",
5916 "channel-mask", GST_TYPE_BITMASK,
5917 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5918 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5919 audiocontext->bitdepth);
5920 context->alignment = audiocontext->bitdepth / 8;
5921 context->alignment = round_up_pow2 (context->alignment);
5922 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5923 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5924 caps = gst_caps_new_simple ("audio/x-ac3",
5925 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5926 *codec_name = g_strdup ("AC-3 audio");
5927 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5928 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5929 caps = gst_caps_new_simple ("audio/x-eac3",
5930 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5931 *codec_name = g_strdup ("E-AC-3 audio");
5932 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5933 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5934 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5935 *codec_name = g_strdup ("Dolby TrueHD");
5936 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5937 caps = gst_caps_new_empty_simple ("audio/x-dts");
5938 *codec_name = g_strdup ("DTS audio");
5939 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5940 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5941 context->stream_headers =
5942 gst_matroska_parse_xiph_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_FLAC)) {
5947 caps = gst_caps_new_empty_simple ("audio/x-flac");
5948 context->stream_headers =
5949 gst_matroska_parse_flac_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_SPEEX)) {
5954 caps = gst_caps_new_empty_simple ("audio/x-speex");
5955 context->stream_headers =
5956 gst_matroska_parse_speex_stream_headers (context->codec_priv,
5957 context->codec_priv_size);
5958 /* FIXME: mark stream as broken and skip if there are no stream headers */
5959 context->send_stream_headers = TRUE;
5960 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5963 if (context->codec_priv_size >= 19) {
5964 if (audiocontext->samplerate)
5965 GST_WRITE_UINT32_LE ((guint8 *) context->codec_priv + 12,
5966 audiocontext->samplerate);
5967 if (context->codec_delay) {
5969 gst_util_uint64_scale_round (context->codec_delay, 48000,
5971 GST_WRITE_UINT16_LE ((guint8 *) context->codec_priv + 10, delay);
5975 gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5976 context->codec_priv_size), context->codec_priv_size);
5977 caps = gst_codec_utils_opus_create_caps_from_header (tmp, NULL);
5978 gst_buffer_unref (tmp);
5979 *codec_name = g_strdup ("Opus");
5980 } else if (context->codec_priv_size == 0) {
5981 GST_WARNING ("No Opus codec data found, trying to create one");
5982 if (audiocontext->channels <= 2) {
5983 guint8 streams, coupled, channels;
5987 audiocontext->samplerate == 0 ? 48000 : audiocontext->samplerate;
5988 channels = audiocontext->channels == 0 ? 2 : audiocontext->channels;
5989 if (channels == 1) {
5998 gst_codec_utils_opus_create_caps (samplerate, channels, 0, streams,
6001 *codec_name = g_strdup ("Opus");
6003 GST_WARNING ("Failed to create Opus caps from audio context");
6006 GST_WARNING ("No Opus codec data, and not enough info to create one");
6009 GST_WARNING ("Invalid Opus codec data size (got %" G_GSIZE_FORMAT
6010 ", expected 19)", context->codec_priv_size);
6012 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
6013 gst_riff_strf_auds auds;
6015 if (data && size >= 18) {
6016 GstBuffer *codec_data = NULL;
6018 /* little-endian -> byte-order */
6019 auds.format = GST_READ_UINT16_LE (data);
6020 auds.channels = GST_READ_UINT16_LE (data + 2);
6021 auds.rate = GST_READ_UINT32_LE (data + 4);
6022 auds.av_bps = GST_READ_UINT32_LE (data + 8);
6023 auds.blockalign = GST_READ_UINT16_LE (data + 12);
6024 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
6026 /* 18 is the waveformatex size */
6028 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
6029 data + 18, size - 18, 0, size - 18, NULL, NULL);
6033 *riff_audio_fmt = auds.format;
6035 /* FIXME: Handle reorder map */
6036 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
6037 codec_data, codec_name, NULL);
6039 gst_buffer_unref (codec_data);
6042 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
6045 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
6047 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
6048 GstBuffer *priv = NULL;
6050 gint rate_idx, profile;
6051 guint8 *data = NULL;
6053 /* unspecified AAC profile with opaque private codec data */
6054 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
6055 if (context->codec_priv_size >= 2) {
6056 guint obj_type, freq_index, explicit_freq_bytes = 0;
6058 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6060 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
6061 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
6062 if (freq_index == 15)
6063 explicit_freq_bytes = 3;
6064 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
6065 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
6066 context->codec_priv_size), context->codec_priv_size);
6067 /* assume SBR if samplerate <= 24kHz */
6068 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
6069 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
6070 audiocontext->samplerate *= 2;
6073 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
6074 /* this is pretty broken;
6075 * maybe we need to make up some default private,
6076 * or maybe ADTS data got dumped in.
6077 * Let's set up some private data now, and check actual data later */
6078 /* just try this and see what happens ... */
6079 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6080 context->postprocess_frame = gst_matroska_demux_check_aac;
6084 /* make up decoder-specific data if it is not supplied */
6088 priv = gst_buffer_new_allocate (NULL, 5, NULL);
6089 gst_buffer_map (priv, &map, GST_MAP_WRITE);
6091 rate_idx = aac_rate_idx (audiocontext->samplerate);
6092 profile = aac_profile_idx (codec_id);
6094 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
6095 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
6097 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
6098 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
6100 gst_buffer_unmap (priv, &map);
6101 gst_buffer_set_size (priv, 2);
6102 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
6103 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
6106 if (g_strrstr (codec_id, "SBR")) {
6107 /* HE-AAC (aka SBR AAC) */
6108 audiocontext->samplerate *= 2;
6109 rate_idx = aac_rate_idx (audiocontext->samplerate);
6110 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
6111 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
6112 data[4] = (1 << 7) | (rate_idx << 3);
6113 gst_buffer_unmap (priv, &map);
6115 gst_buffer_unmap (priv, &map);
6116 gst_buffer_set_size (priv, 2);
6119 gst_buffer_unmap (priv, &map);
6120 gst_buffer_unref (priv);
6122 GST_ERROR ("Unknown AAC profile and no codec private data");
6127 caps = gst_caps_new_simple ("audio/mpeg",
6128 "mpegversion", G_TYPE_INT, mpegversion,
6129 "framed", G_TYPE_BOOLEAN, TRUE,
6130 "stream-format", G_TYPE_STRING, "raw", NULL);
6131 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6132 if (context->codec_priv && context->codec_priv_size > 0)
6133 gst_codec_utils_aac_caps_set_level_and_profile (caps,
6134 context->codec_priv, context->codec_priv_size);
6135 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
6136 gst_buffer_unref (priv);
6138 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
6139 caps = gst_caps_new_simple ("audio/x-tta",
6140 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
6141 *codec_name = g_strdup ("TTA audio");
6142 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
6143 caps = gst_caps_new_simple ("audio/x-wavpack",
6144 "width", G_TYPE_INT, audiocontext->bitdepth,
6145 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6146 *codec_name = g_strdup ("Wavpack audio");
6147 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
6148 audiocontext->wvpk_block_index = 0;
6149 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
6150 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
6151 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
6152 gint raversion = -1;
6154 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
6156 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
6161 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
6162 "raversion", G_TYPE_INT, raversion, NULL);
6163 /* Extract extra information from caps, mapping varies based on codec */
6164 if (data && (size >= 0x50)) {
6171 guint extra_data_size;
6173 GST_DEBUG ("real audio raversion:%d", raversion);
6174 if (raversion == 8) {
6176 flavor = GST_READ_UINT16_BE (data + 22);
6177 packet_size = GST_READ_UINT32_BE (data + 24);
6178 height = GST_READ_UINT16_BE (data + 40);
6179 leaf_size = GST_READ_UINT16_BE (data + 44);
6180 sample_width = GST_READ_UINT16_BE (data + 58);
6181 extra_data_size = GST_READ_UINT32_BE (data + 74);
6184 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
6185 flavor, packet_size, height, leaf_size, sample_width,
6187 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
6188 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
6189 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
6191 if ((size - 78) >= extra_data_size) {
6192 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
6194 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6195 gst_buffer_unref (priv);
6200 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
6201 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
6202 caps = gst_caps_new_empty_simple ("audio/x-sipro");
6203 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
6204 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
6205 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
6206 *codec_name = g_strdup ("Real Audio Lossless");
6207 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
6208 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
6209 *codec_name = g_strdup ("Sony ATRAC3");
6211 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6216 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
6219 for (i = 0; i < gst_caps_get_size (caps); i++) {
6220 gst_structure_set (gst_caps_get_structure (caps, i),
6221 "channels", G_TYPE_INT, audiocontext->channels,
6222 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
6226 caps = gst_caps_simplify (caps);
6233 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
6234 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
6236 GstCaps *caps = NULL;
6237 GstMatroskaTrackContext *context =
6238 (GstMatroskaTrackContext *) subtitlecontext;
6240 /* for backwards compatibility */
6241 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
6242 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
6243 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
6244 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
6245 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
6246 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
6247 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
6248 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
6250 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
6251 * Check if we have to do something with codec_private */
6252 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
6253 /* well, plain text simply does not have a lot of markup ... */
6254 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
6255 "pango-markup", NULL);
6256 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6257 subtitlecontext->check_markup = TRUE;
6258 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
6259 caps = gst_caps_new_empty_simple ("application/x-ssa");
6260 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6261 subtitlecontext->check_markup = FALSE;
6262 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
6263 caps = gst_caps_new_empty_simple ("application/x-ass");
6264 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6265 subtitlecontext->check_markup = FALSE;
6266 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
6267 caps = gst_caps_new_empty_simple ("application/x-usf");
6268 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6269 subtitlecontext->check_markup = FALSE;
6270 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
6271 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
6272 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
6273 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
6274 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
6275 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
6276 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
6277 context->stream_headers =
6278 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6279 context->codec_priv_size);
6280 /* FIXME: mark stream as broken and skip if there are no stream headers */
6281 context->send_stream_headers = TRUE;
6283 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
6284 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
6287 if (data != NULL && size > 0) {
6290 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
6291 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
6292 gst_buffer_unref (buf);
6300 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
6302 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6304 GST_OBJECT_LOCK (demux);
6305 if (demux->common.element_index)
6306 gst_object_unref (demux->common.element_index);
6307 demux->common.element_index = index ? gst_object_ref (index) : NULL;
6308 GST_OBJECT_UNLOCK (demux);
6309 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
6310 demux->common.element_index);
6314 gst_matroska_demux_get_index (GstElement * element)
6316 GstIndex *result = NULL;
6317 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6319 GST_OBJECT_LOCK (demux);
6320 if (demux->common.element_index)
6321 result = gst_object_ref (demux->common.element_index);
6322 GST_OBJECT_UNLOCK (demux);
6324 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
6330 static GstStateChangeReturn
6331 gst_matroska_demux_change_state (GstElement * element,
6332 GstStateChange transition)
6334 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6335 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
6337 /* handle upwards state changes here */
6338 switch (transition) {
6343 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
6345 /* handle downwards state changes */
6346 switch (transition) {
6347 case GST_STATE_CHANGE_PAUSED_TO_READY:
6348 gst_matroska_demux_reset (GST_ELEMENT (demux));
6358 gst_matroska_demux_set_property (GObject * object,
6359 guint prop_id, const GValue * value, GParamSpec * pspec)
6361 GstMatroskaDemux *demux;
6363 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6364 demux = GST_MATROSKA_DEMUX (object);
6367 case PROP_MAX_GAP_TIME:
6368 GST_OBJECT_LOCK (demux);
6369 demux->max_gap_time = g_value_get_uint64 (value);
6370 GST_OBJECT_UNLOCK (demux);
6373 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6379 gst_matroska_demux_get_property (GObject * object,
6380 guint prop_id, GValue * value, GParamSpec * pspec)
6382 GstMatroskaDemux *demux;
6384 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6385 demux = GST_MATROSKA_DEMUX (object);
6388 case PROP_MAX_GAP_TIME:
6389 GST_OBJECT_LOCK (demux);
6390 g_value_set_uint64 (value, demux->max_gap_time);
6391 GST_OBJECT_UNLOCK (demux);
6394 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6400 gst_matroska_demux_plugin_init (GstPlugin * plugin)
6404 /* parser helper separate debug */
6405 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
6406 0, "EBML stream helper class");
6408 /* create an elementfactory for the matroska_demux element */
6409 if (!gst_element_register (plugin, "matroskademux",
6410 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))