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 #include <gst/base/base.h>
58 /* For AVI compatibility mode
59 and for fourcc stuff */
60 #include <gst/riff/riff-read.h>
61 #include <gst/riff/riff-ids.h>
62 #include <gst/riff/riff-media.h>
64 #include <gst/audio/audio.h>
65 #include <gst/tag/tag.h>
66 #include <gst/pbutils/pbutils.h>
67 #include <gst/video/video.h>
69 #include "matroska-demux.h"
70 #include "matroska-ids.h"
72 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
73 #define GST_CAT_DEFAULT matroskademux_debug
75 #define DEBUG_ELEMENT_START(demux, ebml, element) \
76 GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
77 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
79 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
80 GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
81 " finished with '%s'", gst_flow_get_name (ret))
89 PROP_MAX_BACKTRACK_DISTANCE
92 #define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
93 #define DEFAULT_MAX_BACKTRACK_DISTANCE 30
94 #define INVALID_DATA_THRESHOLD (2 * 1024 * 1024)
96 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
99 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
100 "video/x-matroska-3d; audio/webm; video/webm")
103 /* TODO: fill in caps! */
105 static GstStaticPadTemplate audio_src_templ =
106 GST_STATIC_PAD_TEMPLATE ("audio_%u",
109 GST_STATIC_CAPS ("ANY")
112 static GstStaticPadTemplate video_src_templ =
113 GST_STATIC_PAD_TEMPLATE ("video_%u",
116 GST_STATIC_CAPS ("ANY")
119 static GstStaticPadTemplate subtitle_src_templ =
120 GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
123 GST_STATIC_CAPS ("text/x-raw, format=pango-markup; application/x-ssa; "
124 "application/x-ass;application/x-usf; subpicture/x-dvd; "
125 "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
128 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
129 guint32 id, guint64 length, guint needed);
131 /* element functions */
132 static void gst_matroska_demux_loop (GstPad * pad);
134 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
136 static gboolean gst_matroska_demux_element_query (GstElement * element,
140 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad,
142 static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
143 GstObject * parent, GstPadMode mode, gboolean active);
145 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
146 GstPad * pad, GstEvent * event);
147 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
148 GstObject * parent, GstEvent * event);
149 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
150 GstObject * parent, GstQuery * query);
152 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
153 GstObject * parent, GstEvent * event);
154 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
155 GstObject * object, GstBuffer * buffer);
157 static GstStateChangeReturn
158 gst_matroska_demux_change_state (GstElement * element,
159 GstStateChange transition);
162 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
163 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
167 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
168 * videocontext, const gchar * codec_id, guint8 * data, guint size,
169 gchar ** codec_name, guint32 * riff_fourcc);
170 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
171 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
172 gchar ** codec_name, guint16 * riff_audio_fmt);
174 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
175 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
178 static void gst_matroska_demux_reset (GstElement * element);
179 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
180 gdouble rate, guint64 offset, guint32 seqnum, GstSeekFlags flags);
182 /* gobject functions */
183 static void gst_matroska_demux_set_property (GObject * object,
184 guint prop_id, const GValue * value, GParamSpec * pspec);
185 static void gst_matroska_demux_get_property (GObject * object,
186 guint prop_id, GValue * value, GParamSpec * pspec);
188 GType gst_matroska_demux_get_type (void);
189 #define parent_class gst_matroska_demux_parent_class
190 G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
193 gst_matroska_demux_finalize (GObject * object)
195 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
197 gst_matroska_read_common_finalize (&demux->common);
198 gst_flow_combiner_free (demux->flowcombiner);
199 G_OBJECT_CLASS (parent_class)->finalize (object);
203 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
205 GObjectClass *gobject_class = (GObjectClass *) klass;
206 GstElementClass *gstelement_class = (GstElementClass *) klass;
208 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
211 gobject_class->finalize = gst_matroska_demux_finalize;
213 gobject_class->get_property = gst_matroska_demux_get_property;
214 gobject_class->set_property = gst_matroska_demux_set_property;
216 g_object_class_install_property (gobject_class, PROP_MAX_GAP_TIME,
217 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
218 "The demuxer sends out segment events for skipping "
219 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
220 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
222 g_object_class_install_property (gobject_class, PROP_MAX_BACKTRACK_DISTANCE,
223 g_param_spec_uint ("max-backtrack-distance",
224 "Maximum backtrack distance",
225 "Maximum backtrack distance in seconds when seeking without "
226 "and index in pull mode and search for a keyframe "
227 "(0 = disable backtracking).",
228 0, G_MAXUINT, DEFAULT_MAX_BACKTRACK_DISTANCE,
229 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
231 gstelement_class->change_state =
232 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
233 gstelement_class->send_event =
234 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
235 gstelement_class->query =
236 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
238 gstelement_class->set_index =
239 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
240 gstelement_class->get_index =
241 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
244 gst_element_class_add_static_pad_template (gstelement_class,
246 gst_element_class_add_static_pad_template (gstelement_class,
248 gst_element_class_add_static_pad_template (gstelement_class,
249 &subtitle_src_templ);
250 gst_element_class_add_static_pad_template (gstelement_class, &sink_templ);
252 gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
254 "Demuxes Matroska/WebM streams into video/audio/subtitles",
255 "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
259 gst_matroska_demux_init (GstMatroskaDemux * demux)
261 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
263 gst_pad_set_activate_function (demux->common.sinkpad,
264 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
265 gst_pad_set_activatemode_function (demux->common.sinkpad,
266 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
267 gst_pad_set_chain_function (demux->common.sinkpad,
268 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
269 gst_pad_set_event_function (demux->common.sinkpad,
270 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
271 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
273 /* init defaults for common read context */
274 gst_matroska_read_common_init (&demux->common);
276 /* property defaults */
277 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
278 demux->max_backtrack_distance = DEFAULT_MAX_BACKTRACK_DISTANCE;
280 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
282 demux->flowcombiner = gst_flow_combiner_new ();
285 gst_matroska_demux_reset (GST_ELEMENT (demux));
289 gst_matroska_demux_reset (GstElement * element)
291 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
293 GST_DEBUG_OBJECT (demux, "Resetting state");
295 gst_matroska_read_common_reset (GST_ELEMENT (demux), &demux->common);
297 demux->num_a_streams = 0;
298 demux->num_t_streams = 0;
299 demux->num_v_streams = 0;
300 demux->have_nonintraonly_v_streams = FALSE;
302 demux->have_group_id = FALSE;
303 demux->group_id = G_MAXUINT;
306 demux->tracks_parsed = FALSE;
308 if (demux->clusters) {
309 g_array_free (demux->clusters, TRUE);
310 demux->clusters = NULL;
313 g_list_foreach (demux->seek_parsed,
314 (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
315 g_list_free (demux->seek_parsed);
316 demux->seek_parsed = NULL;
318 demux->last_stop_end = GST_CLOCK_TIME_NONE;
319 demux->seek_block = 0;
320 demux->stream_start_time = GST_CLOCK_TIME_NONE;
321 demux->to_time = GST_CLOCK_TIME_NONE;
322 demux->cluster_time = GST_CLOCK_TIME_NONE;
323 demux->cluster_offset = 0;
324 demux->cluster_prevsize = 0;
325 demux->seen_cluster_prevsize = FALSE;
326 demux->next_cluster_offset = 0;
327 demux->stream_last_time = GST_CLOCK_TIME_NONE;
328 demux->last_cluster_offset = 0;
329 demux->index_offset = 0;
330 demux->seekable = FALSE;
331 demux->need_segment = FALSE;
332 demux->segment_seqnum = 0;
333 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
334 demux->seek_offset = -1;
335 demux->building_index = FALSE;
336 if (demux->seek_event) {
337 gst_event_unref (demux->seek_event);
338 demux->seek_event = NULL;
341 demux->seek_index = NULL;
342 demux->seek_entry = 0;
344 if (demux->new_segment) {
345 gst_event_unref (demux->new_segment);
346 demux->new_segment = NULL;
349 demux->invalid_duration = FALSE;
351 demux->cached_length = G_MAXUINT64;
353 gst_flow_combiner_clear (demux->flowcombiner);
357 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
363 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
365 GST_DEBUG ("decoding buffer %p", buf);
367 gst_buffer_map (buf, &map, GST_MAP_READ);
371 g_return_val_if_fail (size > 0, buf);
373 if (gst_matroska_decode_data (context->encodings, &data, &size,
374 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
375 gst_buffer_unmap (buf, &map);
376 gst_buffer_unref (buf);
377 return gst_buffer_new_wrapped (data, size);
379 GST_DEBUG ("decode data failed");
380 gst_buffer_unmap (buf, &map);
381 gst_buffer_unref (buf);
387 gst_matroska_demux_add_stream_headers_to_caps (GstMatroskaDemux * demux,
388 GstBufferList * list, GstCaps * caps)
391 GValue arr_val = G_VALUE_INIT;
392 GValue buf_val = G_VALUE_INIT;
395 g_assert (gst_caps_is_writable (caps));
397 g_value_init (&arr_val, GST_TYPE_ARRAY);
398 g_value_init (&buf_val, GST_TYPE_BUFFER);
400 num = gst_buffer_list_length (list);
401 for (i = 0; i < num; ++i) {
402 g_value_set_boxed (&buf_val, gst_buffer_list_get (list, i));
403 gst_value_array_append_value (&arr_val, &buf_val);
406 s = gst_caps_get_structure (caps, 0);
407 gst_structure_take_value (s, "streamheader", &arr_val);
408 g_value_unset (&buf_val);
412 gst_matroska_demux_parse_colour (GstMatroskaDemux * demux, GstEbmlRead * ebml,
413 GstMatroskaTrackVideoContext * video_context)
416 GstVideoColorimetry colorimetry;
420 colorimetry.range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
421 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
422 colorimetry.transfer = GST_VIDEO_TRANSFER_UNKNOWN;
423 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
425 DEBUG_ELEMENT_START (demux, ebml, "TrackVideoColour");
427 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
430 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
431 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
435 case GST_MATROSKA_ID_VIDEOMATRIXCOEFFICIENTS:{
436 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
441 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
444 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT709;
447 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
450 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_FCC;
452 /* FIXME: "5: BT470BG" is undefined in GstVideoColorMatrix
453 * but it's functionally same as "6: BT601" */
456 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT601;
459 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_SMPTE240M;
462 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
465 GST_FIXME_OBJECT (demux, "Unsupported color matrix coefficients %"
466 G_GUINT64_FORMAT, num);
472 case GST_MATROSKA_ID_VIDEORANGE:{
473 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
478 colorimetry.range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
481 colorimetry.range = GST_VIDEO_COLOR_RANGE_16_235;
484 colorimetry.range = GST_VIDEO_COLOR_RANGE_0_255;
487 GST_FIXME_OBJECT (demux, "Unsupported color range %"
488 G_GUINT64_FORMAT, num);
494 case GST_MATROSKA_ID_VIDEOTRANSFERCHARACTERISTICS:{
495 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
499 /* FIXME: "6: BT601" and "14: BT2020_10" are undefined in
500 * GstVideoTransferFunction, but functionally same as "1: BT709" */
504 colorimetry.transfer = GST_VIDEO_TRANSFER_BT709;
507 colorimetry.transfer = GST_VIDEO_TRANSFER_UNKNOWN;
510 colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA22;
513 colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA28;
516 colorimetry.transfer = GST_VIDEO_TRANSFER_SMPTE240M;
519 colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA10;
522 colorimetry.transfer = GST_VIDEO_TRANSFER_LOG100;
525 colorimetry.transfer = GST_VIDEO_TRANSFER_LOG316;
528 colorimetry.transfer = GST_VIDEO_TRANSFER_SRGB;
531 colorimetry.transfer = GST_VIDEO_TRANSFER_BT2020_12;
534 GST_FIXME_OBJECT (demux,
535 "Unsupported color transfer characteristics %"
536 G_GUINT64_FORMAT, num);
542 case GST_MATROSKA_ID_VIDEOPRIMARIES:{
543 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
548 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
551 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
554 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT470M;
557 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT470BG;
560 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE170M;
563 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE240M;
566 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_FILM;
569 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
572 GST_FIXME_OBJECT (demux, "Unsupported color primaries %"
573 G_GUINT64_FORMAT, num);
580 GST_FIXME_OBJECT (demux, "Unsupported subelement 0x%x in Colour", id);
581 ret = gst_ebml_read_skip (ebml);
586 memcpy (&video_context->colorimetry, &colorimetry,
587 sizeof (GstVideoColorimetry));
590 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideoColour", ret);
595 gst_matroska_demux_parse_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml,
596 GstMatroskaTrackContext ** dest_context)
598 GstMatroskaTrackContext *context;
599 GstCaps *caps = NULL;
600 GstTagList *cached_taglist;
602 guint32 id, riff_fourcc = 0;
603 guint16 riff_audio_fmt = 0;
606 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
608 /* start with the master */
609 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
610 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
614 /* allocate generic... if we know the type, we'll g_renew()
615 * with the precise type */
616 context = g_new0 (GstMatroskaTrackContext, 1);
617 context->index_writer_id = -1;
618 context->type = 0; /* no type yet */
619 context->default_duration = 0;
621 context->set_discont = TRUE;
622 context->timecodescale = 1.0;
624 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
625 GST_MATROSKA_TRACK_LACING;
626 context->from_time = GST_CLOCK_TIME_NONE;
627 context->from_offset = -1;
628 context->to_offset = G_MAXINT64;
629 context->alignment = 1;
630 context->dts_only = FALSE;
631 context->intra_only = FALSE;
632 context->tags = gst_tag_list_new_empty ();
634 GST_DEBUG_OBJECT (demux, "Parsing a TrackEntry (%d tracks parsed so far)",
635 demux->common.num_streams);
637 /* try reading the trackentry headers */
638 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
639 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
643 /* track number (unique stream ID) */
644 case GST_MATROSKA_ID_TRACKNUMBER:{
647 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
651 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
652 ret = GST_FLOW_ERROR;
656 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
660 /* track UID (unique identifier) */
661 case GST_MATROSKA_ID_TRACKUID:{
664 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
668 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
669 ret = GST_FLOW_ERROR;
673 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
678 /* track type (video, audio, combined, subtitle, etc.) */
679 case GST_MATROSKA_ID_TRACKTYPE:{
682 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
686 if (context->type != 0 && context->type != track_type) {
687 GST_WARNING_OBJECT (demux,
688 "More than one tracktype defined in a TrackEntry - skipping");
690 } else if (track_type < 1 || track_type > 254) {
691 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
696 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
698 /* ok, so we're actually going to reallocate this thing */
699 switch (track_type) {
700 case GST_MATROSKA_TRACK_TYPE_VIDEO:
701 gst_matroska_track_init_video_context (&context);
703 case GST_MATROSKA_TRACK_TYPE_AUDIO:
704 gst_matroska_track_init_audio_context (&context);
706 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
707 gst_matroska_track_init_subtitle_context (&context);
709 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
710 case GST_MATROSKA_TRACK_TYPE_LOGO:
711 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
712 case GST_MATROSKA_TRACK_TYPE_CONTROL:
714 GST_WARNING_OBJECT (demux,
715 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
723 /* tracktype specific stuff for video */
724 case GST_MATROSKA_ID_TRACKVIDEO:{
725 GstMatroskaTrackVideoContext *videocontext;
727 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
729 if (!gst_matroska_track_init_video_context (&context)) {
730 GST_WARNING_OBJECT (demux,
731 "TrackVideo element in non-video track - ignoring track");
732 ret = GST_FLOW_ERROR;
734 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
737 videocontext = (GstMatroskaTrackVideoContext *) context;
739 while (ret == GST_FLOW_OK &&
740 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
741 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
745 /* Should be one level up but some broken muxers write it here. */
746 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
749 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
753 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
757 GST_DEBUG_OBJECT (demux,
758 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
759 context->default_duration = num;
763 /* video framerate */
764 /* NOTE: This one is here only for backward compatibility.
765 * Use _TRACKDEFAULDURATION one level up. */
766 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
769 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
773 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
777 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
778 if (context->default_duration == 0)
779 context->default_duration =
780 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
781 videocontext->default_fps = num;
785 /* width of the size to display the video at */
786 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
789 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
793 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
797 GST_DEBUG_OBJECT (demux,
798 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
799 videocontext->display_width = num;
803 /* height of the size to display the video at */
804 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
807 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
811 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
815 GST_DEBUG_OBJECT (demux,
816 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
817 videocontext->display_height = num;
821 /* width of the video in the file */
822 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
825 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
829 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
833 GST_DEBUG_OBJECT (demux,
834 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
835 videocontext->pixel_width = num;
839 /* height of the video in the file */
840 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
843 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
847 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
851 GST_DEBUG_OBJECT (demux,
852 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
853 videocontext->pixel_height = num;
857 /* whether the video is interlaced */
858 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
861 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
865 videocontext->interlace_mode =
866 GST_MATROSKA_INTERLACE_MODE_INTERLACED;
868 videocontext->interlace_mode =
869 GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
871 videocontext->interlace_mode =
872 GST_MATROSKA_INTERLACE_MODE_UNKNOWN;
874 GST_DEBUG_OBJECT (demux, "video track interlacing mode: %d",
875 videocontext->interlace_mode);
879 /* aspect ratio behaviour */
880 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
883 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
886 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
887 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
888 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
889 GST_WARNING_OBJECT (demux,
890 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
893 GST_DEBUG_OBJECT (demux,
894 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
895 videocontext->asr_mode = num;
899 /* colourspace (only matters for raw video) fourcc */
900 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
905 gst_ebml_read_binary (ebml, &id, &data,
906 &datalen)) != GST_FLOW_OK)
911 GST_WARNING_OBJECT (demux,
912 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
917 memcpy (&videocontext->fourcc, data, 4);
918 GST_DEBUG_OBJECT (demux,
919 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
920 GST_FOURCC_ARGS (videocontext->fourcc));
926 case GST_MATROSKA_ID_VIDEOCOLOUR:{
927 ret = gst_matroska_demux_parse_colour (demux, ebml, videocontext);
931 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
935 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
938 GST_DEBUG_OBJECT (demux, "StereoMode: %" G_GUINT64_FORMAT, num);
941 case GST_MATROSKA_STEREO_MODE_SBS_RL:
942 videocontext->multiview_flags =
943 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
945 case GST_MATROSKA_STEREO_MODE_SBS_LR:
946 videocontext->multiview_mode =
947 GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
949 case GST_MATROSKA_STEREO_MODE_TB_RL:
950 videocontext->multiview_flags =
951 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
953 case GST_MATROSKA_STEREO_MODE_TB_LR:
954 videocontext->multiview_mode =
955 GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM;
957 case GST_MATROSKA_STEREO_MODE_CHECKER_RL:
958 videocontext->multiview_flags =
959 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
961 case GST_MATROSKA_STEREO_MODE_CHECKER_LR:
962 videocontext->multiview_mode =
963 GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD;
965 case GST_MATROSKA_STEREO_MODE_FBF_RL:
966 videocontext->multiview_flags =
967 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
969 case GST_MATROSKA_STEREO_MODE_FBF_LR:
970 videocontext->multiview_mode =
971 GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
972 /* FIXME: In frame-by-frame mode, left/right frame buffers are
973 * laced within one block, and we'll need to apply FIRST_IN_BUNDLE
974 * accordingly. See http://www.matroska.org/technical/specs/index.html#StereoMode */
975 GST_FIXME_OBJECT (demux,
976 "Frame-by-frame stereoscopic mode not fully implemented");
983 GST_WARNING_OBJECT (demux,
984 "Unknown TrackVideo subelement 0x%x - ignoring", id);
986 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
987 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
988 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
989 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
990 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
991 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
992 ret = gst_ebml_read_skip (ebml);
997 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
1001 /* tracktype specific stuff for audio */
1002 case GST_MATROSKA_ID_TRACKAUDIO:{
1003 GstMatroskaTrackAudioContext *audiocontext;
1005 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
1007 if (!gst_matroska_track_init_audio_context (&context)) {
1008 GST_WARNING_OBJECT (demux,
1009 "TrackAudio element in non-audio track - ignoring track");
1010 ret = GST_FLOW_ERROR;
1014 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
1017 audiocontext = (GstMatroskaTrackAudioContext *) context;
1019 while (ret == GST_FLOW_OK &&
1020 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1021 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1026 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
1029 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1034 GST_WARNING_OBJECT (demux,
1035 "Invalid TrackAudioSamplingFrequency %lf", num);
1039 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
1040 audiocontext->samplerate = num;
1045 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
1048 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1052 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
1056 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
1058 audiocontext->bitdepth = num;
1063 case GST_MATROSKA_ID_AUDIOCHANNELS:{
1066 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1070 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
1074 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
1076 audiocontext->channels = num;
1081 GST_WARNING_OBJECT (demux,
1082 "Unknown TrackAudio subelement 0x%x - ignoring", id);
1084 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
1085 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
1086 ret = gst_ebml_read_skip (ebml);
1091 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
1096 /* codec identifier */
1097 case GST_MATROSKA_ID_CODECID:{
1100 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
1103 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
1104 context->codec_id = text;
1108 /* codec private data */
1109 case GST_MATROSKA_ID_CODECPRIVATE:{
1114 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
1117 context->codec_priv = data;
1118 context->codec_priv_size = size;
1120 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1125 /* name of the codec */
1126 case GST_MATROSKA_ID_CODECNAME:{
1129 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1132 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1133 context->codec_name = text;
1138 case GST_MATROSKA_ID_CODECDELAY:{
1141 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1144 context->codec_delay = num;
1146 GST_DEBUG_OBJECT (demux, "CodecDelay: %" GST_TIME_FORMAT,
1147 GST_TIME_ARGS (num));
1152 case GST_MATROSKA_ID_SEEKPREROLL:{
1155 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1158 context->seek_preroll = num;
1160 GST_DEBUG_OBJECT (demux, "SeekPreroll: %" GST_TIME_FORMAT,
1161 GST_TIME_ARGS (num));
1165 /* name of this track */
1166 case GST_MATROSKA_ID_TRACKNAME:{
1169 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1172 context->name = text;
1173 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1177 /* language (matters for audio/subtitles, mostly) */
1178 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1181 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1185 context->language = text;
1188 if (strlen (context->language) >= 4 && context->language[3] == '-')
1189 context->language[3] = '\0';
1191 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1192 GST_STR_NULL (context->language));
1196 /* whether this is actually used */
1197 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1200 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1204 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1206 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1208 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1209 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1213 /* whether it's the default for this track type */
1214 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1217 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1221 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1223 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1225 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1226 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
1230 /* whether the track must be used during playback */
1231 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1234 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1238 context->flags |= GST_MATROSKA_TRACK_FORCED;
1240 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1242 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1243 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
1247 /* lacing (like MPEG, where blocks don't end/start on frame
1249 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1252 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1256 context->flags |= GST_MATROSKA_TRACK_LACING;
1258 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1260 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1261 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
1265 /* default length (in time) of one data block in this track */
1266 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1269 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1274 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1278 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1280 context->default_duration = num;
1284 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1285 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1290 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1293 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1297 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1301 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1302 context->timecodescale = num;
1307 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1310 /* we ignore these because they're nothing useful (i.e. crap)
1311 * or simply not implemented yet. */
1312 case GST_MATROSKA_ID_TRACKMINCACHE:
1313 case GST_MATROSKA_ID_TRACKMAXCACHE:
1314 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1315 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1316 case GST_MATROSKA_ID_TRACKOVERLAY:
1317 case GST_MATROSKA_ID_TRACKTRANSLATE:
1318 case GST_MATROSKA_ID_TRACKOFFSET:
1319 case GST_MATROSKA_ID_CODECSETTINGS:
1320 case GST_MATROSKA_ID_CODECINFOURL:
1321 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1322 case GST_MATROSKA_ID_CODECDECODEALL:
1323 ret = gst_ebml_read_skip (ebml);
1328 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1330 /* Decode codec private data if necessary */
1331 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1332 && context->codec_priv_size > 0) {
1333 if (!gst_matroska_decode_data (context->encodings,
1334 &context->codec_priv, &context->codec_priv_size,
1335 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1336 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1337 ret = GST_FLOW_ERROR;
1341 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1342 && ret != GST_FLOW_EOS)) {
1343 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1344 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1346 gst_matroska_track_free (context);
1348 *dest_context = NULL;
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);
1360 switch (context->type) {
1361 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1362 GstMatroskaTrackVideoContext *videocontext =
1363 (GstMatroskaTrackVideoContext *) context;
1365 caps = gst_matroska_demux_video_caps (videocontext,
1366 context->codec_id, context->codec_priv,
1367 context->codec_priv_size, &codec, &riff_fourcc);
1370 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1371 GST_TAG_VIDEO_CODEC, codec, NULL);
1372 context->tags_changed = TRUE;
1378 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1379 GstMatroskaTrackAudioContext *audiocontext =
1380 (GstMatroskaTrackAudioContext *) context;
1382 caps = gst_matroska_demux_audio_caps (audiocontext,
1383 context->codec_id, context->codec_priv, context->codec_priv_size,
1384 &codec, &riff_audio_fmt);
1387 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1388 GST_TAG_AUDIO_CODEC, codec, NULL);
1389 context->tags_changed = TRUE;
1395 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1396 GstMatroskaTrackSubtitleContext *subtitlecontext =
1397 (GstMatroskaTrackSubtitleContext *) context;
1399 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1400 context->codec_id, context->codec_priv, context->codec_priv_size);
1404 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1405 case GST_MATROSKA_TRACK_TYPE_LOGO:
1406 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1407 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1409 /* we should already have quit by now */
1410 g_assert_not_reached ();
1413 if ((context->language == NULL || *context->language == '\0') &&
1414 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1415 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1416 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1417 context->language = g_strdup ("eng");
1420 if (context->language) {
1423 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1424 lang = gst_tag_get_language_code (context->language);
1425 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1426 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1428 if (context->name) {
1429 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1430 GST_TAG_TITLE, context->name, NULL);
1432 context->tags_changed = TRUE;
1436 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1437 "codec_id='%s'", context->codec_id);
1438 switch (context->type) {
1439 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1440 caps = gst_caps_new_empty_simple ("video/x-unknown");
1442 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1443 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1445 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1446 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1448 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1450 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1453 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1456 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1457 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1458 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1459 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1460 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1461 GST_FOURCC_ARGS (riff_fourcc));
1462 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1465 } else if (context->stream_headers != NULL) {
1466 gst_matroska_demux_add_stream_headers_to_caps (demux,
1467 context->stream_headers, caps);
1470 context->caps = caps;
1473 *dest_context = context;
1478 gst_matroska_demux_add_stream (GstMatroskaDemux * demux,
1479 GstMatroskaTrackContext * context)
1481 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
1482 gchar *padname = NULL;
1483 GstPadTemplate *templ = NULL;
1484 GstStreamFlags stream_flags;
1486 GstEvent *stream_start;
1490 g_ptr_array_add (demux->common.src, context);
1491 context->index = demux->common.num_streams++;
1492 g_assert (demux->common.src->len == demux->common.num_streams);
1493 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1) =
1496 /* now create the GStreamer connectivity */
1497 switch (context->type) {
1498 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1499 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1500 templ = gst_element_class_get_pad_template (klass, "video_%u");
1502 if (!context->intra_only)
1503 demux->have_nonintraonly_v_streams = TRUE;
1506 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1507 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1508 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1511 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1512 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1513 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1517 /* we should already have quit by now */
1518 g_assert_not_reached ();
1521 /* the pad in here */
1522 context->pad = gst_pad_new_from_template (templ, padname);
1524 gst_pad_set_event_function (context->pad,
1525 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1526 gst_pad_set_query_function (context->pad,
1527 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1529 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1530 padname, context->caps);
1532 gst_pad_set_element_private (context->pad, context);
1534 gst_pad_use_fixed_caps (context->pad);
1535 gst_pad_set_active (context->pad, TRUE);
1538 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1539 "%03" G_GUINT64_FORMAT ":%03" G_GUINT64_FORMAT,
1540 context->num, context->uid);
1542 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1545 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1546 demux->have_group_id = TRUE;
1548 demux->have_group_id = FALSE;
1549 gst_event_unref (stream_start);
1550 } else if (!demux->have_group_id) {
1551 demux->have_group_id = TRUE;
1552 demux->group_id = gst_util_group_id_next ();
1555 stream_start = gst_event_new_stream_start (stream_id);
1557 if (demux->have_group_id)
1558 gst_event_set_group_id (stream_start, demux->group_id);
1559 stream_flags = GST_STREAM_FLAG_NONE;
1560 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1561 stream_flags |= GST_STREAM_FLAG_SPARSE;
1562 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1563 stream_flags |= GST_STREAM_FLAG_SELECT;
1564 else if (!(context->flags & GST_MATROSKA_TRACK_ENABLED))
1565 stream_flags |= GST_STREAM_FLAG_UNSELECT;
1567 gst_event_set_stream_flags (stream_start, stream_flags);
1568 gst_pad_push_event (context->pad, stream_start);
1569 gst_pad_set_caps (context->pad, context->caps);
1572 if (demux->common.global_tags) {
1573 GstEvent *tag_event;
1575 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1576 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1577 GST_DEBUG_OBJECT (context->pad, "Sending global_tags %p: %" GST_PTR_FORMAT,
1578 demux->common.global_tags, demux->common.global_tags);
1581 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1583 gst_pad_push_event (context->pad, tag_event);
1586 if (G_UNLIKELY (context->tags_changed)) {
1587 GST_DEBUG_OBJECT (context->pad, "Sending tags %p: %"
1588 GST_PTR_FORMAT, context->tags, context->tags);
1589 gst_pad_push_event (context->pad,
1590 gst_event_new_tag (gst_tag_list_copy (context->tags)));
1591 context->tags_changed = FALSE;
1594 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1595 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1601 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1604 gboolean res = FALSE;
1605 GstMatroskaTrackContext *context = NULL;
1608 context = gst_pad_get_element_private (pad);
1611 switch (GST_QUERY_TYPE (query)) {
1612 case GST_QUERY_POSITION:
1616 gst_query_parse_position (query, &format, NULL);
1619 if (format == GST_FORMAT_TIME) {
1620 GST_OBJECT_LOCK (demux);
1622 gst_query_set_position (query, GST_FORMAT_TIME,
1623 MAX (context->pos, demux->stream_start_time) -
1624 demux->stream_start_time);
1626 gst_query_set_position (query, GST_FORMAT_TIME,
1627 MAX (demux->common.segment.position, demux->stream_start_time) -
1628 demux->stream_start_time);
1629 GST_OBJECT_UNLOCK (demux);
1630 } else if (format == GST_FORMAT_DEFAULT && context
1631 && context->default_duration) {
1632 GST_OBJECT_LOCK (demux);
1633 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1634 context->pos / context->default_duration);
1635 GST_OBJECT_UNLOCK (demux);
1637 GST_DEBUG_OBJECT (demux,
1638 "only position query in TIME and DEFAULT format is supported");
1644 case GST_QUERY_DURATION:
1648 gst_query_parse_duration (query, &format, NULL);
1651 if (format == GST_FORMAT_TIME) {
1652 GST_OBJECT_LOCK (demux);
1653 gst_query_set_duration (query, GST_FORMAT_TIME,
1654 demux->common.segment.duration);
1655 GST_OBJECT_UNLOCK (demux);
1656 } else if (format == GST_FORMAT_DEFAULT && context
1657 && context->default_duration) {
1658 GST_OBJECT_LOCK (demux);
1659 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1660 demux->common.segment.duration / context->default_duration);
1661 GST_OBJECT_UNLOCK (demux);
1663 GST_DEBUG_OBJECT (demux,
1664 "only duration query in TIME and DEFAULT format is supported");
1670 case GST_QUERY_SEEKING:
1674 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1675 GST_OBJECT_LOCK (demux);
1676 if (fmt == GST_FORMAT_TIME) {
1679 if (demux->streaming) {
1680 /* assuming we'll be able to get an index ... */
1681 seekable = demux->seekable;
1686 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1687 0, demux->common.segment.duration);
1690 GST_OBJECT_UNLOCK (demux);
1693 case GST_QUERY_SEGMENT:
1698 format = demux->common.segment.format;
1701 gst_segment_to_stream_time (&demux->common.segment, format,
1702 demux->common.segment.start);
1703 if ((stop = demux->common.segment.stop) == -1)
1704 stop = demux->common.segment.duration;
1707 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1709 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1716 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1719 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1728 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1730 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1734 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1737 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1739 return gst_matroska_demux_query (demux, pad, query);
1742 /* returns FALSE if there are no pads to deliver event to,
1743 * otherwise TRUE (whatever the outcome of event sending),
1744 * takes ownership of the passed event! */
1746 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1748 gboolean ret = FALSE;
1751 g_return_val_if_fail (event != NULL, FALSE);
1753 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1754 GST_EVENT_TYPE_NAME (event));
1756 g_assert (demux->common.src->len == demux->common.num_streams);
1757 for (i = 0; i < demux->common.src->len; i++) {
1758 GstMatroskaTrackContext *stream;
1760 stream = g_ptr_array_index (demux->common.src, i);
1761 gst_event_ref (event);
1762 gst_pad_push_event (stream->pad, event);
1766 gst_event_unref (event);
1771 gst_matroska_demux_send_tags (GstMatroskaDemux * demux)
1775 if (G_UNLIKELY (demux->common.global_tags_changed)) {
1776 GstEvent *tag_event;
1777 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1778 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1779 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1780 demux->common.global_tags, demux->common.global_tags);
1783 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1785 for (i = 0; i < demux->common.src->len; i++) {
1786 GstMatroskaTrackContext *stream;
1788 stream = g_ptr_array_index (demux->common.src, i);
1789 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1792 gst_event_unref (tag_event);
1793 demux->common.global_tags_changed = FALSE;
1796 g_assert (demux->common.src->len == demux->common.num_streams);
1797 for (i = 0; i < demux->common.src->len; i++) {
1798 GstMatroskaTrackContext *stream;
1800 stream = g_ptr_array_index (demux->common.src, i);
1802 if (G_UNLIKELY (stream->tags_changed)) {
1803 GST_DEBUG_OBJECT (demux, "Sending tags %p for pad %s:%s : %"
1804 GST_PTR_FORMAT, stream->tags,
1805 GST_DEBUG_PAD_NAME (stream->pad), stream->tags);
1806 gst_pad_push_event (stream->pad,
1807 gst_event_new_tag (gst_tag_list_copy (stream->tags)));
1808 stream->tags_changed = FALSE;
1814 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1816 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1819 g_return_val_if_fail (event != NULL, FALSE);
1821 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1822 /* no seeking until we are (safely) ready */
1823 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
1824 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
1825 gst_event_unref (event);
1828 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1830 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1831 GST_EVENT_TYPE_NAME (event));
1834 gst_event_unref (event);
1839 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1840 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1844 GST_OBJECT_LOCK (demux);
1847 /* seek (relative to matroska segment) */
1848 /* position might be invalid; will error when streaming resumes ... */
1849 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1850 demux->next_cluster_offset = 0;
1852 GST_DEBUG_OBJECT (demux,
1853 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1854 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1855 entry->block, GST_TIME_ARGS (entry->time));
1857 /* update the time */
1858 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1859 gst_flow_combiner_reset (demux->flowcombiner);
1860 demux->common.segment.position = entry->time;
1861 demux->seek_block = entry->block;
1862 demux->seek_first = TRUE;
1863 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1866 for (i = 0; i < demux->common.src->len; i++) {
1867 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1870 stream->to_offset = G_MAXINT64;
1872 if (stream->from_offset != -1)
1873 stream->to_offset = stream->from_offset;
1875 stream->from_offset = -1;
1876 stream->from_time = GST_CLOCK_TIME_NONE;
1879 GST_OBJECT_UNLOCK (demux);
1885 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1895 /* searches for a cluster start from @pos,
1896 * return GST_FLOW_OK and cluster position in @pos if found */
1897 static GstFlowReturn
1898 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos,
1901 gint64 newpos = *pos;
1903 GstFlowReturn ret = GST_FLOW_OK;
1904 const guint chunk = 128 * 1024;
1905 GstBuffer *buf = NULL;
1907 gpointer data = NULL;
1912 gint64 oldpos, oldlength;
1914 orig_offset = demux->common.offset;
1916 GST_LOG_OBJECT (demux, "searching cluster %s offset %" G_GINT64_FORMAT,
1917 forward ? "following" : "preceding", *pos);
1919 if (demux->clusters) {
1922 cpos = gst_util_array_binary_search (demux->clusters->data,
1923 demux->clusters->len, sizeof (gint64),
1924 (GCompareDataFunc) gst_matroska_cluster_compare,
1925 forward ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE, pos, NULL);
1928 GST_DEBUG_OBJECT (demux,
1929 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
1930 demux->common.offset = *cpos;
1931 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
1932 GST_ELEMENT_CAST (demux), &id, &length, &needed);
1933 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
1940 /* read in at newpos and scan for ebml cluster id */
1941 oldpos = oldlength = -1;
1943 GstByteReader reader;
1945 guint toread = chunk;
1948 /* never read beyond the requested target */
1949 if (G_UNLIKELY (newpos < chunk)) {
1957 gst_buffer_unmap (buf, &map);
1958 gst_buffer_unref (buf);
1961 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, toread, &buf);
1962 if (ret != GST_FLOW_OK)
1964 GST_DEBUG_OBJECT (demux,
1965 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1966 gst_buffer_get_size (buf), newpos);
1967 gst_buffer_map (buf, &map, GST_MAP_READ);
1970 if (oldpos == newpos && oldlength == map.size) {
1971 GST_ERROR_OBJECT (demux, "Stuck at same position");
1972 ret = GST_FLOW_ERROR;
1976 oldlength = map.size;
1979 gst_byte_reader_init (&reader, data, size);
1982 gint found = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1983 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
1985 cluster_pos = found;
1988 /* need last occurrence when searching backwards */
1990 cluster_pos = gst_byte_reader_get_pos (&reader) + found;
1991 gst_byte_reader_skip (&reader, found + 4);
1997 if (cluster_pos >= 0) {
1998 newpos += cluster_pos;
1999 GST_DEBUG_OBJECT (demux,
2000 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
2001 /* extra checks whether we really sync'ed to a cluster:
2002 * - either it is the first and only cluster
2003 * - either there is a cluster after this one
2004 * - either cluster length is undefined
2006 /* ok if first cluster (there may not a subsequent one) */
2007 if (newpos == demux->first_cluster_offset) {
2008 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
2011 demux->common.offset = newpos;
2012 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2013 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2014 if (ret != GST_FLOW_OK) {
2015 GST_DEBUG_OBJECT (demux, "need more data -> continue");
2018 g_assert (id == GST_MATROSKA_ID_CLUSTER);
2019 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
2021 /* ok if undefined length or first cluster */
2022 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
2023 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
2027 demux->common.offset += length + needed;
2028 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2029 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2030 if (ret != GST_FLOW_OK)
2032 GST_DEBUG_OBJECT (demux, "next element is %scluster",
2033 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
2034 if (id == GST_MATROSKA_ID_CLUSTER)
2040 /* partial cluster id may have been in tail of buffer */
2042 forward ? MAX (gst_byte_reader_get_remaining (&reader), 4) - 3 : 3;
2047 gst_buffer_unmap (buf, &map);
2048 gst_buffer_unref (buf);
2053 demux->common.offset = orig_offset;
2058 /* Three states to express: starts with I-frame, starts with delta, don't know */
2061 CLUSTER_STATUS_NONE = 0,
2062 CLUSTER_STATUS_STARTS_WITH_KEYFRAME,
2063 CLUSTER_STATUS_STARTS_WITH_DELTAUNIT,
2072 ClusterStatus status;
2075 static const gchar *
2076 cluster_status_get_nick (ClusterStatus status)
2079 case CLUSTER_STATUS_NONE:
2081 case CLUSTER_STATUS_STARTS_WITH_KEYFRAME:
2083 case CLUSTER_STATUS_STARTS_WITH_DELTAUNIT:
2089 /* Skip ebml-coded number:
2092 * 001x.. = 3 bytes, etc.
2095 bit_reader_skip_ebml_num (GstBitReader * br)
2099 if (!gst_bit_reader_peek_bits_uint8 (br, &v, 8))
2102 for (i = 0; i < 8; i++) {
2103 if ((v & (0x80 >> i)) != 0)
2106 return gst_bit_reader_skip (br, (i + 1) * 8);
2109 /* Don't probe more than that many bytes into the cluster for keyframe info
2110 * (random value, mostly for sanity checking) */
2111 #define MAX_CLUSTER_INFO_PROBE_LENGTH 256
2114 gst_matroska_demux_peek_cluster_info (GstMatroskaDemux * demux,
2115 ClusterInfo * cluster, guint64 offset)
2117 demux->common.offset = offset;
2118 demux->cluster_time = GST_CLOCK_TIME_NONE;
2120 cluster->offset = offset;
2122 cluster->prev_size = 0;
2123 cluster->time = GST_CLOCK_TIME_NONE;
2124 cluster->status = CLUSTER_STATUS_NONE;
2126 /* parse first few elements in cluster */
2133 flow = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2134 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2136 if (flow != GST_FLOW_OK)
2139 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2140 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
2143 /* Reached start of next cluster without finding data, stop processing */
2144 if (id == GST_MATROSKA_ID_CLUSTER && cluster->offset != offset)
2147 /* Not going to parse into these for now, stop processing */
2148 if (id == GST_MATROSKA_ID_ENCRYPTEDBLOCK
2149 || id == GST_MATROSKA_ID_BLOCKGROUP || id == GST_MATROSKA_ID_BLOCK)
2152 /* SimpleBlock: peek at headers to check if it's a keyframe */
2153 if (id == GST_MATROSKA_ID_SIMPLEBLOCK) {
2155 guint8 *d, hdr_len, v = 0;
2157 GST_DEBUG_OBJECT (demux, "SimpleBlock found");
2159 /* SimpleBlock header is max. 21 bytes */
2160 hdr_len = MIN (21, length);
2162 flow = gst_matroska_read_common_peek_bytes (&demux->common,
2163 demux->common.offset, hdr_len, NULL, &d);
2165 if (flow != GST_FLOW_OK)
2168 gst_bit_reader_init (&br, d, hdr_len);
2170 /* skip prefix: ebml id (SimpleBlock) + element length */
2171 if (!gst_bit_reader_skip (&br, 8 * needed))
2174 /* skip track number (ebml coded) */
2175 if (!bit_reader_skip_ebml_num (&br))
2179 if (!gst_bit_reader_skip (&br, 16))
2183 if (!gst_bit_reader_get_bits_uint8 (&br, &v, 8))
2186 if ((v & 0x80) != 0)
2187 cluster->status = CLUSTER_STATUS_STARTS_WITH_KEYFRAME;
2189 cluster->status = CLUSTER_STATUS_STARTS_WITH_DELTAUNIT;
2194 flow = gst_matroska_demux_parse_id (demux, id, length, needed);
2196 if (flow != GST_FLOW_OK)
2200 case GST_MATROSKA_ID_CLUSTER:
2201 if (length == G_MAXUINT64)
2204 cluster->size = length + needed;
2206 case GST_MATROSKA_ID_PREVSIZE:
2207 cluster->prev_size = demux->cluster_prevsize;
2209 case GST_MATROSKA_ID_CLUSTERTIMECODE:
2210 cluster->time = demux->cluster_time * demux->common.time_scale;
2212 case GST_MATROSKA_ID_SILENTTRACKS:
2213 /* ignore and continue */
2216 GST_WARNING_OBJECT (demux, "Unknown ebml id 0x%08x (possibly garbage), "
2220 } while (demux->common.offset - offset < MAX_CLUSTER_INFO_PROBE_LENGTH);
2224 GST_INFO_OBJECT (demux, "Cluster @ %" G_GUINT64_FORMAT ": "
2225 "time %" GST_TIME_FORMAT ", size %" G_GUINT64_FORMAT ", "
2226 "prev_size %" G_GUINT64_FORMAT ", %s", cluster->offset,
2227 GST_TIME_ARGS (cluster->time), cluster->size, cluster->prev_size,
2228 cluster_status_get_nick (cluster->status));
2230 /* return success as long as we could extract the minimum useful information */
2231 return cluster->time != GST_CLOCK_TIME_NONE;
2234 /* returns TRUE if the cluster offset was updated */
2236 gst_matroska_demux_scan_back_for_keyframe_cluster (GstMatroskaDemux * demux,
2237 gint64 * cluster_offset, GstClockTime * cluster_time)
2239 GstClockTime stream_start_time = demux->stream_start_time;
2240 guint64 first_cluster_offset = demux->first_cluster_offset;
2241 gint64 off = *cluster_offset;
2242 ClusterInfo cluster = { 0, };
2244 GST_INFO_OBJECT (demux, "Checking if cluster starts with keyframe");
2245 while (off > first_cluster_offset) {
2246 if (!gst_matroska_demux_peek_cluster_info (demux, &cluster, off)) {
2247 GST_LOG_OBJECT (demux,
2248 "Couldn't get info on cluster @ %" G_GUINT64_FORMAT, off);
2252 /* Keyframe? Then we're done */
2253 if (cluster.status == CLUSTER_STATUS_STARTS_WITH_KEYFRAME) {
2254 GST_LOG_OBJECT (demux,
2255 "Found keyframe at start of cluster @ %" G_GUINT64_FORMAT, off);
2259 /* We only scan back if we *know* we landed on a cluster that
2260 * starts with a delta frame. */
2261 if (cluster.status != CLUSTER_STATUS_STARTS_WITH_DELTAUNIT) {
2262 GST_LOG_OBJECT (demux,
2263 "No delta frame at start of cluster @ %" G_GUINT64_FORMAT, off);
2267 GST_DEBUG_OBJECT (demux, "Cluster starts with delta frame, backtracking");
2269 /* Don't scan back more than this much in time from the cluster we
2270 * originally landed on. This is mostly a sanity check in case a file
2271 * always has keyframes in the middle of clusters and never at the
2272 * beginning. Without this we would always scan back to the beginning
2273 * of the file in that case. */
2274 if (cluster.time != GST_CLOCK_TIME_NONE) {
2275 GstClockTimeDiff distance = GST_CLOCK_DIFF (cluster.time, *cluster_time);
2277 if (distance < 0 || distance > demux->max_backtrack_distance * GST_SECOND) {
2278 GST_DEBUG_OBJECT (demux, "Haven't found cluster with keyframe within "
2279 "%u secs of original seek target cluster, stopping",
2280 demux->max_backtrack_distance);
2285 /* If we have cluster prev_size we can skip back efficiently. If not,
2286 * we'll just do a brute force search for a cluster identifier */
2287 if (cluster.prev_size > 0 && off >= cluster.prev_size) {
2288 off -= cluster.prev_size;
2292 GST_LOG_OBJECT (demux, "Cluster has no or invalid prev size, searching "
2293 "for previous cluster instead then");
2295 flow = gst_matroska_demux_search_cluster (demux, &off, FALSE);
2296 if (flow != GST_FLOW_OK) {
2297 GST_DEBUG_OBJECT (demux, "cluster search yielded flow %s, stopping",
2298 gst_flow_get_name (flow));
2303 if (off <= first_cluster_offset) {
2304 GST_LOG_OBJECT (demux, "Reached first cluster, stopping");
2305 *cluster_offset = first_cluster_offset;
2306 *cluster_time = stream_start_time;
2309 GST_LOG_OBJECT (demux, "Trying prev cluster @ %" G_GUINT64_FORMAT, off);
2312 /* If we found a cluster starting with a keyframe jump to that instead,
2313 * otherwise leave everything as it was before */
2314 if (cluster.time != GST_CLOCK_TIME_NONE
2315 && (cluster.offset == first_cluster_offset
2316 || cluster.status == CLUSTER_STATUS_STARTS_WITH_KEYFRAME)) {
2317 *cluster_offset = cluster.offset;
2318 *cluster_time = cluster.time;
2325 /* bisect and scan through file for cluster starting before @time,
2326 * returns fake index entry with corresponding info on cluster */
2327 static GstMatroskaIndex *
2328 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
2330 GstMatroskaIndex *entry = NULL;
2331 GstMatroskaReadState current_state;
2332 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
2334 gint64 opos, newpos, current_offset;
2335 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
2336 gint64 apos, maxpos;
2337 guint64 cluster_size = 0;
2343 /* estimate new position, resync using cluster ebml id,
2344 * and bisect further or scan forward to appropriate cluster */
2346 /* save some current global state which will be touched by our scanning */
2347 current_state = demux->common.state;
2348 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
2350 current_cluster_offset = demux->cluster_offset;
2351 current_cluster_time = demux->cluster_time;
2352 current_offset = demux->common.offset;
2354 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
2356 /* estimate using start and last known cluster */
2357 GST_OBJECT_LOCK (demux);
2358 apos = demux->first_cluster_offset;
2359 atime = demux->stream_start_time;
2360 opos = demux->last_cluster_offset;
2361 otime = demux->stream_last_time;
2362 GST_OBJECT_UNLOCK (demux);
2365 time = MAX (time, atime);
2366 otime = MAX (otime, atime);
2367 opos = MAX (opos, apos);
2369 maxpos = gst_matroska_read_common_get_length (&demux->common);
2374 * apos always refer to a cluster before target time;
2375 * opos may or may not be after target time, but if it is once so,
2376 * then also in next iteration
2380 GST_LOG_OBJECT (demux,
2381 "apos: %" G_GUINT64_FORMAT ", atime: %" GST_TIME_FORMAT ", %"
2382 GST_TIME_FORMAT " in stream time, "
2383 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
2384 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
2385 GST_TIME_FORMAT, apos, GST_TIME_ARGS (atime),
2386 GST_TIME_ARGS (atime - demux->stream_start_time), opos,
2387 GST_TIME_ARGS (otime), GST_TIME_ARGS (otime - demux->stream_start_time),
2388 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
2390 g_assert (atime <= otime);
2391 g_assert (apos <= opos);
2392 if (time == GST_CLOCK_TIME_NONE) {
2393 GST_DEBUG_OBJECT (demux, "searching last cluster");
2396 GST_DEBUG_OBJECT (demux, "unknown file size; bailing out");
2399 } else if (otime <= atime) {
2403 gst_util_uint64_scale (opos - apos, time - atime, otime - atime);
2404 if (maxpos != -1 && newpos > maxpos)
2408 GST_DEBUG_OBJECT (demux,
2409 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
2410 GST_TIME_ARGS (time), newpos);
2412 /* search backwards */
2413 if (newpos > apos) {
2414 ret = gst_matroska_demux_search_cluster (demux, &newpos, FALSE);
2415 if (ret != GST_FLOW_OK)
2419 /* then start scanning and parsing for cluster time,
2420 * re-estimate if possible, otherwise next cluster and so on */
2421 /* note that each re-estimate is entered with a change in apos or opos,
2422 * avoiding infinite loop */
2423 demux->common.offset = newpos;
2424 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
2426 prev_cluster_time = GST_CLOCK_TIME_NONE;
2428 /* peek and parse some elements */
2429 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2430 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2431 if (ret != GST_FLOW_OK)
2433 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2434 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
2436 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
2437 if (ret != GST_FLOW_OK)
2440 if (id == GST_MATROSKA_ID_CLUSTER) {
2441 cluster_time = GST_CLOCK_TIME_NONE;
2442 if (length == G_MAXUINT64)
2445 cluster_size = length + needed;
2447 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
2448 cluster_time == GST_CLOCK_TIME_NONE) {
2449 cluster_time = demux->cluster_time * demux->common.time_scale;
2450 cluster_offset = demux->cluster_offset;
2451 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
2452 " with time %" GST_TIME_FORMAT, cluster_offset,
2453 GST_TIME_ARGS (cluster_time));
2454 if (time == GST_CLOCK_TIME_NONE) {
2455 GST_DEBUG_OBJECT (demux, "found last cluster");
2456 prev_cluster_time = cluster_time;
2457 prev_cluster_offset = cluster_offset;
2460 if (cluster_time > time) {
2461 GST_DEBUG_OBJECT (demux, "overshot target");
2462 /* cluster overshoots */
2463 if (cluster_offset == demux->first_cluster_offset) {
2464 /* but no prev one */
2465 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
2466 prev_cluster_time = cluster_time;
2467 prev_cluster_offset = cluster_offset;
2470 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
2471 /* prev cluster did not overshoot, so prev cluster is target */
2474 /* re-estimate using this new position info */
2475 opos = cluster_offset;
2476 otime = cluster_time;
2480 /* cluster undershoots */
2481 GST_DEBUG_OBJECT (demux, "undershot target");
2482 /* ok if close enough */
2483 if (GST_CLOCK_DIFF (cluster_time, time) < 5 * GST_SECOND) {
2484 GST_DEBUG_OBJECT (demux, "target close enough");
2485 prev_cluster_time = cluster_time;
2486 prev_cluster_offset = cluster_offset;
2490 /* we are in between atime and otime => can bisect if worthwhile */
2491 if (prev_cluster_time != GST_CLOCK_TIME_NONE &&
2492 cluster_time > prev_cluster_time &&
2493 (GST_CLOCK_DIFF (prev_cluster_time, cluster_time) * 10 <
2494 GST_CLOCK_DIFF (cluster_time, time))) {
2495 /* we moved at least one cluster forward,
2496 * and it looks like target is still far away,
2497 * let's estimate again */
2498 GST_DEBUG_OBJECT (demux, "bisecting with new apos");
2499 apos = cluster_offset;
2500 atime = cluster_time;
2504 /* cluster undershoots, goto next one */
2505 prev_cluster_time = cluster_time;
2506 prev_cluster_offset = cluster_offset;
2507 /* skip cluster if length is defined,
2508 * otherwise will be skippingly parsed into */
2510 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
2511 demux->common.offset = cluster_offset + cluster_size;
2512 demux->cluster_time = GST_CLOCK_TIME_NONE;
2514 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
2521 if (ret == GST_FLOW_EOS) {
2522 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
2528 /* In the bisect loop above we always undershoot and then jump forward
2529 * cluster-by-cluster until we overshoot, so if we get here we've gone
2530 * over and the previous cluster is where we need to go to. */
2531 cluster_offset = prev_cluster_offset;
2532 cluster_time = prev_cluster_time;
2534 /* If we have video and can easily backtrack, check if we landed on a cluster
2535 * that starts with a keyframe - and if not backtrack until we find one that
2537 if (demux->have_nonintraonly_v_streams && demux->max_backtrack_distance > 0) {
2538 if (gst_matroska_demux_scan_back_for_keyframe_cluster (demux,
2539 &cluster_offset, &cluster_time)) {
2540 GST_INFO_OBJECT (demux, "Adjusted cluster to %" GST_TIME_FORMAT " @ "
2541 "%" G_GUINT64_FORMAT, GST_TIME_ARGS (cluster_time), cluster_offset);
2545 entry = g_new0 (GstMatroskaIndex, 1);
2546 entry->time = cluster_time;
2547 entry->pos = cluster_offset - demux->common.ebml_segment_start;
2548 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
2549 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
2553 /* restore some state */
2554 demux->cluster_offset = current_cluster_offset;
2555 demux->cluster_time = current_cluster_time;
2556 demux->common.offset = current_offset;
2557 demux->common.state = current_state;
2563 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
2564 GstPad * pad, GstEvent * event)
2566 GstMatroskaIndex *entry = NULL;
2567 GstMatroskaIndex scan_entry;
2569 GstSeekType cur_type, stop_type;
2571 gboolean flush, keyunit, before, after, snap_next;
2574 GstMatroskaTrackContext *track = NULL;
2575 GstSegment seeksegment = { 0, };
2576 gboolean update = TRUE;
2577 gboolean pad_locked = FALSE;
2579 GstSearchMode snap_dir;
2581 g_return_val_if_fail (event != NULL, FALSE);
2584 track = gst_pad_get_element_private (pad);
2586 GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
2588 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2590 seqnum = gst_event_get_seqnum (event);
2592 /* we can only seek on time */
2593 if (format != GST_FORMAT_TIME) {
2594 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2598 /* copy segment, we need this because we still need the old
2599 * segment when we close the current segment. */
2600 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
2602 /* pull mode without index means that the actual duration is not known,
2603 * we might be playing a file that's still being recorded
2604 * so, invalidate our current duration, which is only a moving target,
2605 * and should not be used to clamp anything */
2606 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
2607 seeksegment.duration = GST_CLOCK_TIME_NONE;
2610 GST_DEBUG_OBJECT (demux, "configuring seek");
2611 /* Subtract stream_start_time so we always seek on a segment
2613 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2614 seeksegment.start -= demux->stream_start_time;
2615 seeksegment.position -= demux->stream_start_time;
2616 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2617 seeksegment.stop -= demux->stream_start_time;
2619 seeksegment.stop = seeksegment.duration;
2622 gst_segment_do_seek (&seeksegment, rate, format, flags,
2623 cur_type, cur, stop_type, stop, &update);
2625 /* Restore the clip timestamp offset */
2626 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2627 seeksegment.position += demux->stream_start_time;
2628 seeksegment.start += demux->stream_start_time;
2629 if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2630 seeksegment.stop = seeksegment.duration;
2631 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2632 seeksegment.stop += demux->stream_start_time;
2635 /* restore segment duration (if any effect),
2636 * would be determined again when parsing, but anyway ... */
2637 seeksegment.duration = demux->common.segment.duration;
2639 flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2640 keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2641 after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
2642 before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
2644 /* always do full update if flushing,
2645 * otherwise problems might arise downstream with missing keyframes etc */
2646 update = update || flush;
2648 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2650 /* check sanity before we start flushing and all that */
2651 snap_next = after && !before;
2652 if (seeksegment.rate < 0)
2653 snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
2655 snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
2657 GST_OBJECT_LOCK (demux);
2658 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2659 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2660 seeksegment.position, &demux->seek_index, &demux->seek_entry,
2661 snap_dir)) == NULL) {
2662 /* pull mode without index can scan later on */
2663 if (demux->streaming) {
2664 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2665 GST_OBJECT_UNLOCK (demux);
2667 } else if (rate < 0.0) {
2668 /* FIXME: We should build an index during playback or when scanning
2669 * that can be used here. The reverse playback code requires seek_index
2670 * and seek_entry to be set!
2672 GST_DEBUG_OBJECT (demux,
2673 "No matching seek entry in index, needed for reverse playback");
2674 GST_OBJECT_UNLOCK (demux);
2678 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2679 GST_OBJECT_UNLOCK (demux);
2682 /* only have to update some segment,
2683 * but also still have to honour flush and so on */
2684 GST_DEBUG_OBJECT (demux, "... no update");
2685 /* bad goto, bad ... */
2689 if (demux->streaming)
2694 GstEvent *flush_event = gst_event_new_flush_start ();
2695 gst_event_set_seqnum (flush_event, seqnum);
2696 GST_DEBUG_OBJECT (demux, "Starting flush");
2697 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2698 gst_matroska_demux_send_event (demux, flush_event);
2700 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2701 gst_pad_pause_task (demux->common.sinkpad);
2705 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2710 /* now grab the stream lock so that streaming cannot continue, for
2711 * non flushing seeks when the element is in PAUSED this could block
2713 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2714 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2717 /* pull mode without index can do some scanning */
2718 if (!demux->streaming && !entry) {
2719 GstEvent *flush_event;
2721 /* need to stop flushing upstream as we need it next */
2723 flush_event = gst_event_new_flush_stop (TRUE);
2724 gst_event_set_seqnum (flush_event, seqnum);
2725 gst_pad_push_event (demux->common.sinkpad, flush_event);
2727 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2728 /* keep local copy */
2730 scan_entry = *entry;
2732 entry = &scan_entry;
2734 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2736 flush_event = gst_event_new_flush_stop (TRUE);
2737 gst_event_set_seqnum (flush_event, seqnum);
2738 gst_matroska_demux_send_event (demux, flush_event);
2745 if (keyunit && seeksegment.rate > 0) {
2746 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2747 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2748 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2749 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2750 seeksegment.position = seeksegment.start;
2751 seeksegment.time = seeksegment.start - demux->stream_start_time;
2752 } else if (keyunit) {
2753 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment stop from %"
2754 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2755 GST_TIME_ARGS (seeksegment.stop), GST_TIME_ARGS (entry->time));
2756 seeksegment.stop = MAX (entry->time, demux->stream_start_time);
2757 seeksegment.position = seeksegment.stop;
2760 if (demux->streaming) {
2761 GST_OBJECT_LOCK (demux);
2762 /* track real position we should start at */
2763 GST_DEBUG_OBJECT (demux, "storing segment start");
2764 demux->requested_seek_time = seeksegment.position;
2765 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2766 GST_OBJECT_UNLOCK (demux);
2767 /* need to seek to cluster start to pick up cluster time */
2768 /* upstream takes care of flushing and all that
2769 * ... and newsegment event handling takes care of the rest */
2770 return perform_seek_to_offset (demux, rate,
2771 entry->pos + demux->common.ebml_segment_start, seqnum, flags);
2776 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2777 gst_event_set_seqnum (flush_event, seqnum);
2778 GST_DEBUG_OBJECT (demux, "Stopping flush");
2779 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2780 gst_matroska_demux_send_event (demux, flush_event);
2783 GST_OBJECT_LOCK (demux);
2784 /* now update the real segment info */
2785 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2786 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2787 GST_OBJECT_UNLOCK (demux);
2789 /* update some (segment) state */
2790 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2793 /* notify start of new segment */
2794 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2797 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2798 GST_FORMAT_TIME, demux->common.segment.start);
2799 gst_message_set_seqnum (msg, seqnum);
2800 gst_element_post_message (GST_ELEMENT (demux), msg);
2803 GST_OBJECT_LOCK (demux);
2804 if (demux->new_segment)
2805 gst_event_unref (demux->new_segment);
2807 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2808 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2809 gst_event_set_seqnum (demux->new_segment, seqnum);
2810 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2811 demux->to_time = demux->common.segment.position;
2813 demux->to_time = GST_CLOCK_TIME_NONE;
2814 demux->segment_seqnum = seqnum;
2815 GST_OBJECT_UNLOCK (demux);
2817 /* restart our task since it might have been stopped when we did the
2819 gst_pad_start_task (demux->common.sinkpad,
2820 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2822 /* streaming can continue now */
2824 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2832 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2834 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2840 * Handle whether we can perform the seek event or if we have to let the chain
2841 * function handle seeks to build the seek indexes first.
2844 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2848 GstSeekType cur_type, stop_type;
2853 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2858 /* we can only seek on time */
2859 if (format != GST_FORMAT_TIME) {
2860 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2864 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2865 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2869 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2870 GST_DEBUG_OBJECT (demux,
2871 "Non-flushing seek not supported in streaming mode");
2875 if (flags & GST_SEEK_FLAG_SEGMENT) {
2876 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2880 /* check for having parsed index already */
2881 if (!demux->common.index_parsed) {
2882 gboolean building_index;
2885 if (!demux->index_offset) {
2886 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2890 GST_OBJECT_LOCK (demux);
2891 /* handle the seek event in the chain function */
2892 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2893 /* no more seek can be issued until state reset to _DATA */
2895 /* copy the event */
2896 if (demux->seek_event)
2897 gst_event_unref (demux->seek_event);
2898 demux->seek_event = gst_event_ref (event);
2900 /* set the building_index flag so that only one thread can setup the
2901 * structures for index seeking. */
2902 building_index = demux->building_index;
2903 if (!building_index) {
2904 demux->building_index = TRUE;
2905 offset = demux->index_offset;
2907 GST_OBJECT_UNLOCK (demux);
2909 if (!building_index) {
2910 /* seek to the first subindex or legacy index */
2911 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2912 return perform_seek_to_offset (demux, rate, offset,
2913 gst_event_get_seqnum (event), GST_SEEK_FLAG_NONE);
2916 /* well, we are handling it already */
2920 /* delegate to tweaked regular seek */
2921 return gst_matroska_demux_handle_seek_event (demux, pad, event);
2925 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
2928 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
2929 gboolean res = TRUE;
2931 switch (GST_EVENT_TYPE (event)) {
2932 case GST_EVENT_SEEK:
2933 /* no seeking until we are (safely) ready */
2934 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
2935 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
2936 gst_event_unref (event);
2941 guint32 seqnum = gst_event_get_seqnum (event);
2942 if (seqnum == demux->segment_seqnum) {
2943 GST_LOG_OBJECT (pad,
2944 "Drop duplicated SEEK event seqnum %" G_GUINT32_FORMAT, seqnum);
2945 gst_event_unref (event);
2950 if (!demux->streaming)
2951 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
2953 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
2954 gst_event_unref (event);
2959 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
2960 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2961 GstMatroskaTrackVideoContext *videocontext =
2962 (GstMatroskaTrackVideoContext *) context;
2964 GstClockTimeDiff diff;
2965 GstClockTime timestamp;
2967 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
2969 GST_OBJECT_LOCK (demux);
2970 videocontext->earliest_time = timestamp + diff;
2971 GST_OBJECT_UNLOCK (demux);
2974 gst_event_unref (event);
2978 case GST_EVENT_TOC_SELECT:
2981 GstTocEntry *entry = NULL;
2982 GstEvent *seek_event;
2985 if (!demux->common.toc) {
2986 GST_DEBUG_OBJECT (demux, "no TOC to select");
2989 gst_event_parse_toc_select (event, &uid);
2991 GST_OBJECT_LOCK (demux);
2992 entry = gst_toc_find_entry (demux->common.toc, uid);
2993 if (entry == NULL) {
2994 GST_OBJECT_UNLOCK (demux);
2995 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
2998 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
2999 GST_OBJECT_UNLOCK (demux);
3000 seek_event = gst_event_new_seek (1.0,
3002 GST_SEEK_FLAG_FLUSH,
3003 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
3004 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
3005 gst_event_unref (seek_event);
3009 GST_WARNING_OBJECT (demux, "received empty TOC select event");
3013 gst_event_unref (event);
3017 /* events we don't need to handle */
3018 case GST_EVENT_NAVIGATION:
3019 gst_event_unref (event);
3023 case GST_EVENT_LATENCY:
3025 res = gst_pad_push_event (demux->common.sinkpad, event);
3032 static GstFlowReturn
3033 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
3035 GstFlowReturn ret = GST_FLOW_EOS;
3036 gboolean done = TRUE;
3039 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
3040 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
3043 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
3045 if (!demux->seek_entry) {
3046 GST_DEBUG_OBJECT (demux, "no earlier index entry");
3050 for (i = 0; i < demux->common.src->len; i++) {
3051 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
3053 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
3054 ", stream %d at %" GST_TIME_FORMAT,
3055 GST_TIME_ARGS (demux->common.segment.start), stream->index,
3056 GST_TIME_ARGS (stream->from_time));
3057 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
3058 if (stream->from_time > demux->common.segment.start) {
3059 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
3063 /* nothing pushed for this stream;
3064 * likely seek entry did not start at keyframe, so all was skipped.
3065 * So we need an earlier entry */
3071 GstMatroskaIndex *entry;
3073 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
3074 --demux->seek_entry);
3075 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
3085 static GstFlowReturn
3086 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3088 GstFlowReturn ret = GST_FLOW_OK;
3091 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
3093 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3094 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3098 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3099 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3103 /* one track within the "all-tracks" header */
3104 case GST_MATROSKA_ID_TRACKENTRY:{
3105 GstMatroskaTrackContext *track;
3106 ret = gst_matroska_demux_parse_stream (demux, ebml, &track);
3107 if (track != NULL) {
3108 if (gst_matroska_read_common_tracknumber_unique (&demux->common,
3110 gst_matroska_demux_add_stream (demux, track);
3112 GST_ERROR_OBJECT (demux,
3113 "TrackNumber %" G_GUINT64_FORMAT " is not unique", track->num);
3114 ret = GST_FLOW_ERROR;
3115 gst_matroska_track_free (track);
3123 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3128 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3130 demux->tracks_parsed = TRUE;
3135 static GstFlowReturn
3136 gst_matroska_demux_update_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3138 GstFlowReturn ret = GST_FLOW_OK;
3139 guint num_tracks_found = 0;
3142 GST_INFO_OBJECT (demux, "Reparsing Tracks element");
3144 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
3146 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3147 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3151 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3152 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3156 /* one track within the "all-tracks" header */
3157 case GST_MATROSKA_ID_TRACKENTRY:{
3158 GstMatroskaTrackContext *new_track;
3159 gint old_track_index;
3160 GstMatroskaTrackContext *old_track;
3161 ret = gst_matroska_demux_parse_stream (demux, ebml, &new_track);
3162 if (new_track == NULL)
3166 if (gst_matroska_read_common_tracknumber_unique (&demux->common,
3168 GST_ERROR_OBJECT (demux,
3169 "Unexpected new TrackNumber: %" G_GUINT64_FORMAT, new_track->num);
3170 goto track_mismatch_error;
3174 gst_matroska_read_common_stream_from_num (&demux->common,
3176 g_assert (old_track_index != -1);
3177 old_track = g_ptr_array_index (demux->common.src, old_track_index);
3179 if (old_track->type != new_track->type) {
3180 GST_ERROR_OBJECT (demux,
3181 "Mismatch reparsing track %" G_GUINT64_FORMAT
3182 " on track type. Expected %d, found %d", new_track->num,
3183 old_track->type, new_track->type);
3184 goto track_mismatch_error;
3187 if (g_strcmp0 (old_track->codec_id, new_track->codec_id) != 0) {
3188 GST_ERROR_OBJECT (demux,
3189 "Mismatch reparsing track %" G_GUINT64_FORMAT
3190 " on codec id. Expected '%s', found '%s'", new_track->num,
3191 old_track->codec_id, new_track->codec_id);
3192 goto track_mismatch_error;
3195 /* The new track matches the old track. No problems on our side.
3196 * Let's make it replace the old track. */
3197 new_track->pad = old_track->pad;
3198 new_track->index = old_track->index;
3199 new_track->pos = old_track->pos;
3200 g_ptr_array_index (demux->common.src, old_track_index) = new_track;
3201 gst_pad_set_element_private (new_track->pad, new_track);
3203 if (!gst_caps_is_equal (old_track->caps, new_track->caps)) {
3204 gst_pad_set_caps (new_track->pad, new_track->caps);
3207 if (!gst_tag_list_is_equal (old_track->tags, new_track->tags)) {
3208 GST_DEBUG_OBJECT (old_track->pad, "Sending tags %p: %"
3209 GST_PTR_FORMAT, new_track->tags, new_track->tags);
3210 gst_pad_push_event (new_track->pad,
3211 gst_event_new_tag (gst_tag_list_copy (new_track->tags)));
3214 gst_matroska_track_free (old_track);
3217 track_mismatch_error:
3218 gst_matroska_track_free (new_track);
3220 ret = GST_FLOW_ERROR;
3225 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3230 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3232 if (ret != GST_FLOW_ERROR && demux->common.num_streams != num_tracks_found) {
3233 GST_ERROR_OBJECT (demux,
3234 "Mismatch on the number of tracks. Expected %du tracks, found %du",
3235 demux->common.num_streams, num_tracks_found);
3236 ret = GST_FLOW_ERROR;
3243 * Read signed/unsigned "EBML" numbers.
3244 * Return: number of bytes processed.
3248 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
3250 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
3258 while (read <= 8 && !(total & len_mask)) {
3265 if ((total &= (len_mask - 1)) == len_mask - 1)
3270 if (data[n] == 0xff)
3272 total = (total << 8) | data[n];
3276 if (read == num_ffs && total != 0)
3285 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
3290 /* read as unsigned number first */
3291 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
3295 if (unum == G_MAXUINT64)
3298 *num = unum - ((1 << ((7 * res) - 1)) - 1);
3304 * Mostly used for subtitles. We add void filler data for each
3305 * lagging stream to make sure we don't deadlock.
3309 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
3311 GstClockTime gap_threshold;
3314 GST_OBJECT_LOCK (demux);
3316 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
3317 GST_TIME_ARGS (demux->common.segment.position));
3319 g_assert (demux->common.num_streams == demux->common.src->len);
3320 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
3321 GstMatroskaTrackContext *context;
3323 context = g_ptr_array_index (demux->common.src, stream_nr);
3325 GST_LOG_OBJECT (demux,
3326 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
3327 GST_TIME_ARGS (context->pos));
3329 /* Only send gap events on non-subtitle streams if lagging way behind.
3330 * The 0.5 second threshold for subtitle streams is also quite random. */
3331 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
3332 gap_threshold = GST_SECOND / 2;
3334 gap_threshold = 3 * GST_SECOND;
3336 /* Lag need only be considered if we have advanced into requested segment */
3337 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
3338 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3339 demux->common.segment.position > demux->common.segment.start &&
3340 context->pos + gap_threshold < demux->common.segment.position) {
3343 guint64 start = context->pos;
3344 guint64 stop = demux->common.segment.position - gap_threshold;
3346 GST_DEBUG_OBJECT (demux,
3347 "Synchronizing stream %d with other by advancing time from %"
3348 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
3349 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
3351 context->pos = stop;
3353 event = gst_event_new_gap (start, stop - start);
3354 GST_OBJECT_UNLOCK (demux);
3355 gst_pad_push_event (context->pad, event);
3356 GST_OBJECT_LOCK (demux);
3360 GST_OBJECT_UNLOCK (demux);
3363 static GstFlowReturn
3364 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
3365 GstMatroskaTrackContext * stream)
3367 GstFlowReturn ret = GST_FLOW_OK;
3370 num = gst_buffer_list_length (stream->stream_headers);
3371 for (i = 0; i < num; ++i) {
3374 buf = gst_buffer_list_get (stream->stream_headers, i);
3375 buf = gst_buffer_copy (buf);
3377 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
3379 if (stream->set_discont) {
3380 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
3381 stream->set_discont = FALSE;
3383 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
3386 /* push out all headers in one go and use last flow return */
3387 ret = gst_pad_push (stream->pad, buf);
3390 /* don't need these any longer */
3391 gst_buffer_list_unref (stream->stream_headers);
3392 stream->stream_headers = NULL;
3395 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3401 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
3402 GstMatroskaTrackContext * stream)
3406 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
3408 if (!stream->codec_priv)
3411 /* ideally, VobSub private data should be parsed and stored more convenient
3412 * elsewhere, but for now, only interested in a small part */
3414 /* make sure we have terminating 0 */
3415 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
3417 /* just locate and parse palette part */
3418 start = strstr (buf, "palette:");
3423 guint8 r, g, b, y, u, v;
3426 while (g_ascii_isspace (*start))
3428 for (i = 0; i < 16; i++) {
3429 if (sscanf (start, "%06x", &col) != 1)
3432 while ((*start == ',') || g_ascii_isspace (*start))
3434 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
3435 r = (col >> 16) & 0xff;
3436 g = (col >> 8) & 0xff;
3438 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
3440 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
3441 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
3442 clut[i] = (y << 16) | (u << 8) | v;
3445 /* got them all without problems; build and send event */
3449 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
3450 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
3451 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
3452 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
3453 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
3454 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
3455 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
3456 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
3457 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
3458 G_TYPE_INT, clut[15], NULL);
3460 gst_pad_push_event (stream->pad,
3461 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
3468 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
3472 g_assert (demux->common.num_streams == demux->common.src->len);
3473 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
3474 GstMatroskaTrackContext *stream;
3476 stream = g_ptr_array_index (demux->common.src, stream_nr);
3478 if (stream->send_stream_headers) {
3479 if (stream->stream_headers != NULL) {
3480 gst_matroska_demux_push_stream_headers (demux, stream);
3482 /* FIXME: perhaps we can just disable and skip this stream then */
3483 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
3484 ("Failed to extract stream headers from codec private data"));
3486 stream->send_stream_headers = FALSE;
3489 if (stream->send_dvd_event) {
3490 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
3491 /* FIXME: should we send this event again after (flushing) seek ? */
3492 stream->send_dvd_event = FALSE;
3498 static GstFlowReturn
3499 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
3500 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3503 guint seq_header_len;
3504 guint32 header, tmp;
3506 if (stream->codec_state) {
3507 seq_header = stream->codec_state;
3508 seq_header_len = stream->codec_state_size;
3509 } else if (stream->codec_priv) {
3510 seq_header = stream->codec_priv;
3511 seq_header_len = stream->codec_priv_size;
3516 /* Sequence header only needed for keyframes */
3517 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
3520 if (gst_buffer_get_size (*buf) < 4)
3523 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
3524 header = GUINT32_FROM_BE (tmp);
3526 /* Sequence start code, if not found prepend */
3527 if (header != 0x000001b3) {
3530 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
3532 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
3535 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
3536 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
3537 gst_buffer_get_size (*buf));
3539 gst_buffer_unref (*buf);
3546 static GstFlowReturn
3547 gst_matroska_demux_add_wvpk_header (GstElement * element,
3548 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3550 GstMatroskaTrackAudioContext *audiocontext =
3551 (GstMatroskaTrackAudioContext *) stream;
3552 GstBuffer *newbuf = NULL;
3553 GstMapInfo map, outmap;
3554 guint8 *buf_data, *data;
3562 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
3565 wvh.total_samples = -1;
3566 wvh.block_index = audiocontext->wvpk_block_index;
3568 if (audiocontext->channels <= 2) {
3569 guint32 block_samples, tmp;
3570 gsize size = gst_buffer_get_size (*buf);
3572 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
3573 block_samples = GUINT32_FROM_LE (tmp);
3574 /* we need to reconstruct the header of the wavpack block */
3576 /* -20 because ck_size is the size of the wavpack block -8
3577 * and lace_size is the size of the wavpack block + 12
3578 * (the three guint32 of the header that already are in the buffer) */
3579 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
3581 /* block_samples, flags and crc are already in the buffer */
3582 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
3584 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3590 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
3591 GST_WRITE_UINT16_LE (data + 8, wvh.version);
3592 GST_WRITE_UINT8 (data + 10, wvh.track_no);
3593 GST_WRITE_UINT8 (data + 11, wvh.index_no);
3594 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
3595 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
3596 gst_buffer_unmap (newbuf, &outmap);
3598 /* Append data from buf: */
3599 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
3600 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
3602 gst_buffer_unref (*buf);
3604 audiocontext->wvpk_block_index += block_samples;
3606 guint8 *outdata = NULL;
3608 gsize buf_size, size, out_size = 0;
3609 guint32 block_samples, flags, crc, blocksize;
3611 gst_buffer_map (*buf, &map, GST_MAP_READ);
3612 buf_data = map.data;
3613 buf_size = map.size;
3616 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
3617 gst_buffer_unmap (*buf, &map);
3618 return GST_FLOW_ERROR;
3624 block_samples = GST_READ_UINT32_LE (data);
3629 flags = GST_READ_UINT32_LE (data);
3632 crc = GST_READ_UINT32_LE (data);
3635 blocksize = GST_READ_UINT32_LE (data);
3639 if (blocksize == 0 || size < blocksize)
3642 g_assert ((newbuf == NULL) == (outdata == NULL));
3644 if (newbuf == NULL) {
3645 out_size = sizeof (Wavpack4Header) + blocksize;
3646 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
3648 gst_buffer_copy_into (newbuf, *buf,
3649 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
3652 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3653 outdata = outmap.data;
3655 gst_buffer_unmap (newbuf, &outmap);
3656 out_size += sizeof (Wavpack4Header) + blocksize;
3657 gst_buffer_set_size (newbuf, out_size);
3658 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3659 outdata = outmap.data;
3662 outdata[outpos] = 'w';
3663 outdata[outpos + 1] = 'v';
3664 outdata[outpos + 2] = 'p';
3665 outdata[outpos + 3] = 'k';
3668 GST_WRITE_UINT32_LE (outdata + outpos,
3669 blocksize + sizeof (Wavpack4Header) - 8);
3670 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
3671 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
3672 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
3673 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
3674 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
3675 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
3676 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
3677 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
3680 memmove (outdata + outpos, data, blocksize);
3681 outpos += blocksize;
3685 gst_buffer_unmap (*buf, &map);
3686 gst_buffer_unref (*buf);
3689 gst_buffer_unmap (newbuf, &outmap);
3692 audiocontext->wvpk_block_index += block_samples;
3698 static GstFlowReturn
3699 gst_matroska_demux_add_prores_header (GstElement * element,
3700 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3702 GstBuffer *newbuf = gst_buffer_new_allocate (NULL, 8, NULL);
3706 if (!gst_buffer_map (newbuf, &map, GST_MAP_WRITE)) {
3707 GST_ERROR ("Failed to map newly allocated buffer");
3708 return GST_FLOW_ERROR;
3711 frame_size = gst_buffer_get_size (*buf);
3713 GST_WRITE_UINT32_BE (map.data, frame_size);
3719 gst_buffer_unmap (newbuf, &map);
3720 *buf = gst_buffer_append (newbuf, *buf);
3725 /* @text must be null-terminated */
3727 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
3732 g_return_val_if_fail (text != NULL, FALSE);
3734 /* yes, this might all lead to false positives ... */
3735 tag = (gchar *) text;
3736 while ((tag = strchr (tag, '<'))) {
3738 if (*tag != '\0' && *(tag + 1) == '>') {
3739 /* some common convenience ones */
3740 /* maybe any character will do here ? */
3753 if (strstr (text, "<span"))
3759 static GstFlowReturn
3760 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
3761 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3763 GstMatroskaTrackSubtitleContext *sub_stream;
3764 const gchar *encoding;
3769 gboolean needs_unmap = TRUE;
3771 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3773 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
3776 /* The subtitle buffer we push out should not include a NUL terminator as
3777 * part of the data. */
3778 if (map.data[map.size - 1] == '\0') {
3779 gst_buffer_set_size (*buf, map.size - 1);
3780 gst_buffer_unmap (*buf, &map);
3781 gst_buffer_map (*buf, &map, GST_MAP_READ);
3784 if (!sub_stream->invalid_utf8) {
3785 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
3788 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
3789 " is not valid UTF-8, this is broken according to the matroska"
3790 " specification", stream->num);
3791 sub_stream->invalid_utf8 = TRUE;
3794 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3795 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3796 if (encoding == NULL || *encoding == '\0') {
3797 /* if local encoding is UTF-8 and no encoding specified
3798 * via the environment variable, assume ISO-8859-15 */
3799 if (g_get_charset (&encoding)) {
3800 encoding = "ISO-8859-15";
3805 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3806 (char *) "*", NULL, NULL, &err);
3809 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3810 encoding, err->message);
3814 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3815 encoding = "ISO-8859-15";
3817 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3818 encoding, (char *) "*", NULL, NULL, NULL);
3821 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3822 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3825 utf8 = g_strdup ("invalid subtitle");
3827 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3828 gst_buffer_unmap (*buf, &map);
3829 gst_buffer_copy_into (newbuf, *buf,
3830 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3832 gst_buffer_unref (*buf);
3835 gst_buffer_map (*buf, &map, GST_MAP_READ);
3839 if (sub_stream->check_markup) {
3840 /* caps claim markup text, so we need to escape text,
3841 * except if text is already markup and then needs no further escaping */
3842 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3843 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3845 if (!sub_stream->seen_markup_tag) {
3846 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3848 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3849 gst_buffer_unmap (*buf, &map);
3850 gst_buffer_copy_into (newbuf, *buf,
3851 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3852 GST_BUFFER_COPY_META, 0, -1);
3853 gst_buffer_unref (*buf);
3856 needs_unmap = FALSE;
3861 gst_buffer_unmap (*buf, &map);
3866 static GstFlowReturn
3867 gst_matroska_demux_check_aac (GstElement * element,
3868 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3873 gst_buffer_extract (*buf, 0, data, 2);
3874 size = gst_buffer_get_size (*buf);
3876 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
3879 /* tss, ADTS data, remove codec_data
3880 * still assume it is at least parsed */
3881 stream->caps = gst_caps_make_writable (stream->caps);
3882 s = gst_caps_get_structure (stream->caps, 0);
3884 gst_structure_remove_field (s, "codec_data");
3885 gst_pad_set_caps (stream->pad, stream->caps);
3886 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
3887 "new caps: %" GST_PTR_FORMAT, stream->caps);
3890 /* disable subsequent checking */
3891 stream->postprocess_frame = NULL;
3897 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
3898 GstBuffer * buffer, gsize alignment)
3902 gst_buffer_map (buffer, &map, GST_MAP_READ);
3904 if (map.size < sizeof (guintptr)) {
3905 gst_buffer_unmap (buffer, &map);
3909 if (((guintptr) map.data) & (alignment - 1)) {
3910 GstBuffer *new_buffer;
3911 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
3913 new_buffer = gst_buffer_new_allocate (NULL,
3914 gst_buffer_get_size (buffer), ¶ms);
3916 /* Copy data "by hand", so ensure alignment is kept: */
3917 gst_buffer_fill (new_buffer, 0, map.data, map.size);
3919 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
3920 GST_DEBUG_OBJECT (demux,
3921 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
3924 gst_buffer_unmap (buffer, &map);
3925 gst_buffer_unref (buffer);
3930 gst_buffer_unmap (buffer, &map);
3934 static GstFlowReturn
3935 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
3936 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
3937 gboolean is_simpleblock)
3939 GstMatroskaTrackContext *stream = NULL;
3940 GstFlowReturn ret = GST_FLOW_OK;
3941 gboolean readblock = FALSE;
3943 guint64 block_duration = -1;
3944 gint64 block_discardpadding = 0;
3945 GstBuffer *buf = NULL;
3947 gint stream_num = -1, n, laces = 0;
3949 gint *lace_size = NULL;
3952 gint64 referenceblock = 0;
3954 GstClockTime buffer_timestamp;
3956 offset = gst_ebml_read_get_offset (ebml);
3958 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3959 if (!is_simpleblock) {
3960 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
3964 id = GST_MATROSKA_ID_SIMPLEBLOCK;
3968 /* one block inside the group. Note, block parsing is one
3969 * of the harder things, so this code is a bit complicated.
3970 * See http://www.matroska.org/ for documentation. */
3971 case GST_MATROSKA_ID_SIMPLEBLOCK:
3972 case GST_MATROSKA_ID_BLOCK:
3978 gst_buffer_unmap (buf, &map);
3979 gst_buffer_unref (buf);
3982 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
3985 gst_buffer_map (buf, &map, GST_MAP_READ);
3989 /* first byte(s): blocknum */
3990 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
3995 /* fetch stream from num */
3996 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
3998 if (G_UNLIKELY (size < 3)) {
3999 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
4000 /* non-fatal, try next block(group) */
4003 } else if (G_UNLIKELY (stream_num < 0 ||
4004 stream_num >= demux->common.num_streams)) {
4005 /* let's not give up on a stray invalid track number */
4006 GST_WARNING_OBJECT (demux,
4007 "Invalid stream %d for track number %" G_GUINT64_FORMAT
4008 "; ignoring block", stream_num, num);
4012 stream = g_ptr_array_index (demux->common.src, stream_num);
4014 /* time (relative to cluster time) */
4015 time = ((gint16) GST_READ_UINT16_BE (data));
4018 flags = GST_READ_UINT8 (data);
4022 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
4025 switch ((flags & 0x06) >> 1) {
4026 case 0x0: /* no lacing */
4028 lace_size = g_new (gint, 1);
4029 lace_size[0] = size;
4032 case 0x1: /* xiph lacing */
4033 case 0x2: /* fixed-size lacing */
4034 case 0x3: /* EBML lacing */
4036 goto invalid_lacing;
4037 laces = GST_READ_UINT8 (data) + 1;
4040 lace_size = g_new0 (gint, laces);
4042 switch ((flags & 0x06) >> 1) {
4043 case 0x1: /* xiph lacing */ {
4044 guint temp, total = 0;
4046 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
4049 goto invalid_lacing;
4050 temp = GST_READ_UINT8 (data);
4051 lace_size[n] += temp;
4057 total += lace_size[n];
4059 lace_size[n] = size - total;
4063 case 0x2: /* fixed-size lacing */
4064 for (n = 0; n < laces; n++)
4065 lace_size[n] = size / laces;
4068 case 0x3: /* EBML lacing */ {
4071 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
4075 total = lace_size[0] = num;
4076 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
4080 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
4084 lace_size[n] = lace_size[n - 1] + snum;
4085 total += lace_size[n];
4088 lace_size[n] = size - total;
4095 if (ret != GST_FLOW_OK)
4102 case GST_MATROSKA_ID_BLOCKDURATION:{
4103 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
4104 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
4109 case GST_MATROSKA_ID_DISCARDPADDING:{
4110 ret = gst_ebml_read_sint (ebml, &id, &block_discardpadding);
4111 GST_DEBUG_OBJECT (demux, "DiscardPadding: %" GST_STIME_FORMAT,
4112 GST_STIME_ARGS (block_discardpadding));
4116 case GST_MATROSKA_ID_REFERENCEBLOCK:{
4117 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
4118 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
4123 case GST_MATROSKA_ID_CODECSTATE:{
4125 guint64 data_len = 0;
4128 gst_ebml_read_binary (ebml, &id, &data,
4129 &data_len)) != GST_FLOW_OK)
4132 if (G_UNLIKELY (stream == NULL)) {
4133 GST_WARNING_OBJECT (demux,
4134 "Unexpected CodecState subelement - ignoring");
4138 g_free (stream->codec_state);
4139 stream->codec_state = data;
4140 stream->codec_state_size = data_len;
4142 /* Decode if necessary */
4143 if (stream->encodings && stream->encodings->len > 0
4144 && stream->codec_state && stream->codec_state_size > 0) {
4145 if (!gst_matroska_decode_data (stream->encodings,
4146 &stream->codec_state, &stream->codec_state_size,
4147 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
4148 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
4152 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
4153 stream->codec_state_size);
4158 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
4162 case GST_MATROSKA_ID_BLOCKVIRTUAL:
4163 case GST_MATROSKA_ID_BLOCKADDITIONS:
4164 case GST_MATROSKA_ID_REFERENCEPRIORITY:
4165 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
4166 case GST_MATROSKA_ID_SLICES:
4167 GST_DEBUG_OBJECT (demux,
4168 "Skipping BlockGroup subelement 0x%x - ignoring", id);
4169 ret = gst_ebml_read_skip (ebml);
4177 /* reading a number or so could have failed */
4178 if (ret != GST_FLOW_OK)
4181 if (ret == GST_FLOW_OK && readblock) {
4182 gboolean invisible_frame = FALSE;
4183 gboolean delta_unit = FALSE;
4184 guint64 duration = 0;
4185 gint64 lace_time = 0;
4187 stream = g_ptr_array_index (demux->common.src, stream_num);
4189 if (cluster_time != GST_CLOCK_TIME_NONE) {
4190 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
4191 * Drop unless the lace contains timestamp 0? */
4192 if (time < 0 && (-time) > cluster_time) {
4195 if (stream->timecodescale == 1.0)
4196 lace_time = (cluster_time + time) * demux->common.time_scale;
4199 gst_util_guint64_to_gdouble ((cluster_time + time) *
4200 demux->common.time_scale) * stream->timecodescale;
4203 lace_time = GST_CLOCK_TIME_NONE;
4206 /* need to refresh segment info ASAP */
4207 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
4208 GstSegment *segment = &demux->common.segment;
4210 GstEvent *segment_event;
4212 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
4213 demux->stream_start_time = lace_time;
4214 GST_DEBUG_OBJECT (demux,
4215 "Setting stream start time to %" GST_TIME_FORMAT,
4216 GST_TIME_ARGS (lace_time));
4218 clace_time = MAX (lace_time, demux->stream_start_time);
4219 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
4220 demux->common.segment.position != 0) {
4221 GST_DEBUG_OBJECT (demux,
4222 "using stored seek position %" GST_TIME_FORMAT,
4223 GST_TIME_ARGS (demux->common.segment.position));
4224 clace_time = demux->common.segment.position;
4225 segment->position = GST_CLOCK_TIME_NONE;
4227 segment->start = clace_time;
4228 segment->stop = GST_CLOCK_TIME_NONE;
4229 segment->time = segment->start - demux->stream_start_time;
4230 segment->position = segment->start - demux->stream_start_time;
4231 GST_DEBUG_OBJECT (demux,
4232 "generated segment starting at %" GST_TIME_FORMAT ": %"
4233 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
4234 /* now convey our segment notion downstream */
4235 segment_event = gst_event_new_segment (segment);
4236 if (demux->segment_seqnum)
4237 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
4238 gst_matroska_demux_send_event (demux, segment_event);
4239 demux->need_segment = FALSE;
4240 demux->segment_seqnum = 0;
4243 /* send pending codec data headers for all streams,
4244 * before we perform sync across all streams */
4245 gst_matroska_demux_push_codec_data_all (demux);
4247 if (block_duration != -1) {
4248 if (stream->timecodescale == 1.0)
4249 duration = gst_util_uint64_scale (block_duration,
4250 demux->common.time_scale, 1);
4253 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
4254 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
4255 1)) * stream->timecodescale);
4256 } else if (stream->default_duration) {
4257 duration = stream->default_duration * laces;
4259 /* else duration is diff between timecode of this and next block */
4261 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
4262 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
4263 a ReferenceBlock implies that this is not a keyframe. In either
4264 case, it only makes sense for video streams. */
4265 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
4267 invisible_frame = ((flags & 0x08)) &&
4268 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
4269 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9) ||
4270 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_AV1));
4273 /* If we're doing a keyframe-only trickmode, only push keyframes on video
4277 segment.flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) {
4278 GST_LOG_OBJECT (demux, "Skipping non-keyframe on stream %d",
4285 for (n = 0; n < laces; n++) {
4288 if (G_UNLIKELY (lace_size[n] > size)) {
4289 GST_WARNING_OBJECT (demux, "Invalid lace size");
4293 /* QoS for video track with an index. the assumption is that
4294 index entries point to keyframes, but if that is not true we
4295 will instad skip until the next keyframe. */
4296 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
4297 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
4298 stream->index_table && demux->common.segment.rate > 0.0) {
4299 GstMatroskaTrackVideoContext *videocontext =
4300 (GstMatroskaTrackVideoContext *) stream;
4301 GstClockTime earliest_time;
4302 GstClockTime earliest_stream_time;
4304 GST_OBJECT_LOCK (demux);
4305 earliest_time = videocontext->earliest_time;
4306 GST_OBJECT_UNLOCK (demux);
4307 earliest_stream_time =
4308 gst_segment_position_from_running_time (&demux->common.segment,
4309 GST_FORMAT_TIME, earliest_time);
4311 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
4312 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
4313 lace_time <= earliest_stream_time) {
4314 /* find index entry (keyframe) <= earliest_stream_time */
4315 GstMatroskaIndex *entry =
4316 gst_util_array_binary_search (stream->index_table->data,
4317 stream->index_table->len, sizeof (GstMatroskaIndex),
4318 (GCompareDataFunc) gst_matroska_index_seek_find,
4319 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
4321 /* if that entry (keyframe) is after the current the current
4322 buffer, we can skip pushing (and thus decoding) all
4323 buffers until that keyframe. */
4324 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
4325 entry->time > lace_time) {
4326 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
4327 stream->set_discont = TRUE;
4333 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
4334 gst_buffer_get_size (buf) - size, lace_size[n]);
4335 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
4338 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4340 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4342 if (invisible_frame)
4343 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
4345 if (stream->encodings != NULL && stream->encodings->len > 0)
4346 sub = gst_matroska_decode_buffer (stream, sub);
4349 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
4353 if (!stream->dts_only) {
4354 GST_BUFFER_PTS (sub) = lace_time;
4356 GST_BUFFER_DTS (sub) = lace_time;
4357 if (stream->intra_only)
4358 GST_BUFFER_PTS (sub) = lace_time;
4361 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
4363 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
4364 GstClockTime last_stop_end;
4366 /* Check if this stream is after segment stop */
4367 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
4368 lace_time >= demux->common.segment.stop) {
4369 GST_DEBUG_OBJECT (demux,
4370 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
4371 GST_TIME_ARGS (demux->common.segment.stop));
4372 gst_buffer_unref (sub);
4375 if (offset >= stream->to_offset
4376 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
4377 && lace_time > demux->to_time)) {
4378 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
4380 gst_buffer_unref (sub);
4384 /* handle gaps, e.g. non-zero start-time, or an cue index entry
4385 * that landed us with timestamps not quite intended */
4386 GST_OBJECT_LOCK (demux);
4387 if (demux->max_gap_time &&
4388 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
4389 demux->common.segment.rate > 0.0) {
4390 GstClockTimeDiff diff;
4392 /* only send segments with increasing start times,
4393 * otherwise if these go back and forth downstream (sinks) increase
4394 * accumulated time and running_time */
4395 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
4396 if (diff > 0 && diff > demux->max_gap_time
4397 && lace_time > demux->common.segment.start
4398 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
4399 || lace_time < demux->common.segment.stop)) {
4401 GST_DEBUG_OBJECT (demux,
4402 "Gap of %" G_GINT64_FORMAT " ns detected in"
4403 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
4404 "Sending updated SEGMENT events", diff,
4405 stream->index, GST_TIME_ARGS (stream->pos),
4406 GST_TIME_ARGS (lace_time));
4408 event = gst_event_new_gap (demux->last_stop_end, diff);
4409 GST_OBJECT_UNLOCK (demux);
4410 gst_pad_push_event (stream->pad, event);
4411 GST_OBJECT_LOCK (demux);
4415 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
4416 || demux->common.segment.position < lace_time) {
4417 demux->common.segment.position = lace_time;
4419 GST_OBJECT_UNLOCK (demux);
4421 last_stop_end = lace_time;
4423 GST_BUFFER_DURATION (sub) = duration / laces;
4424 last_stop_end += GST_BUFFER_DURATION (sub);
4427 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
4428 demux->last_stop_end < last_stop_end)
4429 demux->last_stop_end = last_stop_end;
4431 GST_OBJECT_LOCK (demux);
4432 if (demux->common.segment.duration == -1 ||
4433 demux->stream_start_time + demux->common.segment.duration <
4435 demux->common.segment.duration =
4436 last_stop_end - demux->stream_start_time;
4437 GST_OBJECT_UNLOCK (demux);
4438 if (!demux->invalid_duration) {
4439 gst_element_post_message (GST_ELEMENT_CAST (demux),
4440 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
4441 demux->invalid_duration = TRUE;
4444 GST_OBJECT_UNLOCK (demux);
4448 stream->pos = lace_time;
4450 gst_matroska_demux_sync_streams (demux);
4452 if (stream->set_discont) {
4453 GST_DEBUG_OBJECT (demux, "marking DISCONT");
4454 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
4455 stream->set_discont = FALSE;
4457 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
4460 /* reverse playback book-keeping */
4461 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
4462 stream->from_time = lace_time;
4463 if (stream->from_offset == -1)
4464 stream->from_offset = offset;
4466 GST_DEBUG_OBJECT (demux,
4467 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
4468 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
4469 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
4470 GST_TIME_ARGS (buffer_timestamp),
4471 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
4474 if (demux->common.element_index) {
4475 if (stream->index_writer_id == -1)
4476 gst_index_get_writer_id (demux->common.element_index,
4477 GST_OBJECT (stream->pad), &stream->index_writer_id);
4479 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4480 G_GUINT64_FORMAT " for writer id %d",
4481 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
4482 stream->index_writer_id);
4483 gst_index_add_association (demux->common.element_index,
4484 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
4485 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
4486 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
4491 /* Postprocess the buffers depending on the codec used */
4492 if (stream->postprocess_frame) {
4493 GST_LOG_OBJECT (demux, "running post process");
4494 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
4497 /* At this point, we have a sub-buffer pointing at data within a larger
4498 buffer. This data might not be aligned with anything. If the data is
4499 raw samples though, we want it aligned to the raw type (eg, 4 bytes
4500 for 32 bit samples, etc), or bad things will happen downstream as
4501 elements typically assume minimal alignment.
4502 Therefore, create an aligned copy if necessary. */
4503 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
4505 if (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
4506 guint64 start_clip = 0, end_clip = 0;
4508 /* Codec delay is part of the timestamps */
4509 if (GST_BUFFER_PTS_IS_VALID (sub) && stream->codec_delay) {
4510 if (GST_BUFFER_PTS (sub) > stream->codec_delay) {
4511 GST_BUFFER_PTS (sub) -= stream->codec_delay;
4513 GST_BUFFER_PTS (sub) = 0;
4515 /* Opus GstAudioClippingMeta units are scaled by 48000/sample_rate.
4516 That is, if a Opus track has audio encoded at 24000 Hz and 132
4517 samples need to be clipped, GstAudioClippingMeta.start will be
4518 set to 264. (This is also the case for buffer offsets.)
4519 Opus sample rates are always divisors of 48000 Hz, which is the
4520 maximum allowed sample rate. */
4522 gst_util_uint64_scale_round (stream->codec_delay, 48000,
4525 if (GST_BUFFER_DURATION_IS_VALID (sub)) {
4526 if (GST_BUFFER_DURATION (sub) > stream->codec_delay)
4527 GST_BUFFER_DURATION (sub) -= stream->codec_delay;
4529 GST_BUFFER_DURATION (sub) = 0;
4534 if (block_discardpadding) {
4536 gst_util_uint64_scale_round (block_discardpadding, 48000,
4540 if (start_clip || end_clip) {
4541 gst_buffer_add_audio_clipping_meta (sub, GST_FORMAT_DEFAULT,
4542 start_clip, end_clip);
4546 if (GST_BUFFER_PTS_IS_VALID (sub)) {
4547 stream->pos = GST_BUFFER_PTS (sub);
4548 if (GST_BUFFER_DURATION_IS_VALID (sub))
4549 stream->pos += GST_BUFFER_DURATION (sub);
4550 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
4551 stream->pos = GST_BUFFER_DTS (sub);
4552 if (GST_BUFFER_DURATION_IS_VALID (sub))
4553 stream->pos += GST_BUFFER_DURATION (sub);
4556 ret = gst_pad_push (stream->pad, sub);
4558 if (demux->common.segment.rate < 0) {
4559 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
4560 /* In reverse playback we can get a GST_FLOW_EOS when
4561 * we are at the end of the segment, so we just need to jump
4562 * back to the previous section. */
4563 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
4568 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
4572 size -= lace_size[n];
4573 if (lace_time != GST_CLOCK_TIME_NONE && duration)
4574 lace_time += duration / laces;
4576 lace_time = GST_CLOCK_TIME_NONE;
4582 gst_buffer_unmap (buf, &map);
4583 gst_buffer_unref (buf);
4595 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
4601 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
4602 /* non-fatal, try next block(group) */
4608 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
4609 /* non-fatal, try next block(group) */
4615 /* return FALSE if block(group) should be skipped (due to a seek) */
4616 static inline gboolean
4617 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
4619 if (G_UNLIKELY (demux->seek_block)) {
4620 if (!(--demux->seek_block)) {
4623 GST_LOG_OBJECT (demux, "should skip block due to seek");
4631 static GstFlowReturn
4632 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
4636 guint64 seek_pos = (guint64) - 1;
4637 guint32 seek_id = 0;
4640 DEBUG_ELEMENT_START (demux, ebml, "Seek");
4642 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4643 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4647 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4648 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4652 case GST_MATROSKA_ID_SEEKID:
4656 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4659 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
4664 case GST_MATROSKA_ID_SEEKPOSITION:
4668 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4671 if (t > G_MAXINT64) {
4672 GST_WARNING_OBJECT (demux,
4673 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
4677 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
4683 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
4689 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
4692 if (!seek_id || seek_pos == (guint64) - 1) {
4693 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
4694 G_GUINT64_FORMAT ")", seek_id, seek_pos);
4699 case GST_MATROSKA_ID_SEEKHEAD:
4702 case GST_MATROSKA_ID_CUES:
4703 case GST_MATROSKA_ID_TAGS:
4704 case GST_MATROSKA_ID_TRACKS:
4705 case GST_MATROSKA_ID_SEGMENTINFO:
4706 case GST_MATROSKA_ID_ATTACHMENTS:
4707 case GST_MATROSKA_ID_CHAPTERS:
4709 guint64 before_pos, length;
4713 length = gst_matroska_read_common_get_length (&demux->common);
4714 before_pos = demux->common.offset;
4716 if (length == (guint64) - 1) {
4717 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
4721 /* check for validity */
4722 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
4723 GST_WARNING_OBJECT (demux,
4724 "SeekHead reference lies outside file!" " (%"
4725 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
4726 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
4731 /* only pick up index location when streaming */
4732 if (demux->streaming) {
4733 if (seek_id == GST_MATROSKA_ID_CUES) {
4734 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
4735 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
4736 demux->index_offset);
4742 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
4745 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4746 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
4750 if (id != seek_id) {
4751 GST_WARNING_OBJECT (demux,
4752 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
4753 seek_id, id, seek_pos + demux->common.ebml_segment_start);
4756 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4761 demux->common.offset = before_pos;
4765 case GST_MATROSKA_ID_CLUSTER:
4767 guint64 pos = seek_pos + demux->common.ebml_segment_start;
4769 GST_LOG_OBJECT (demux, "Cluster position");
4770 if (G_UNLIKELY (!demux->clusters))
4771 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
4772 g_array_append_val (demux->clusters, pos);
4777 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
4780 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4785 static GstFlowReturn
4786 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4788 GstFlowReturn ret = GST_FLOW_OK;
4791 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4793 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4794 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4798 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4799 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4803 case GST_MATROSKA_ID_SEEKENTRY:
4805 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
4806 /* Ignore EOS and errors here */
4807 if (ret != GST_FLOW_OK) {
4808 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4815 ret = gst_matroska_read_common_parse_skip (&demux->common,
4816 ebml, "SeekHead", id);
4821 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4823 /* Sort clusters by position for easier searching */
4824 if (demux->clusters)
4825 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4830 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
4832 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4834 static inline GstFlowReturn
4835 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4837 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4838 /* only a few blocks are expected/allowed to be large,
4839 * and will be recursed into, whereas others will be read and must fit */
4840 if (demux->streaming) {
4841 /* fatal in streaming case, as we can't step over easily */
4842 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4843 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4844 "file might be corrupt.", bytes));
4845 return GST_FLOW_ERROR;
4847 /* indicate higher level to quietly give up */
4848 GST_DEBUG_OBJECT (demux,
4849 "too large block of size %" G_GUINT64_FORMAT, bytes);
4850 return GST_FLOW_ERROR;
4857 /* returns TRUE if we truely are in error state, and should give up */
4858 static inline GstFlowReturn
4859 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4861 if (!demux->streaming && demux->next_cluster_offset > 0) {
4862 /* just repositioning to where next cluster should be and try from there */
4863 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4864 G_GUINT64_FORMAT, demux->next_cluster_offset);
4865 demux->common.offset = demux->next_cluster_offset;
4866 demux->next_cluster_offset = 0;
4872 /* sigh, one last attempt above and beyond call of duty ...;
4873 * search for cluster mark following current pos */
4874 pos = demux->common.offset;
4875 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4876 if ((ret = gst_matroska_demux_search_cluster (demux, &pos, TRUE)) !=
4878 /* did not work, give up */
4881 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
4882 /* try that position */
4883 demux->common.offset = pos;
4889 static inline GstFlowReturn
4890 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4892 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4893 demux->common.offset += flush;
4894 if (demux->streaming) {
4897 /* hard to skip large blocks when streaming */
4898 ret = gst_matroska_demux_check_read_size (demux, flush);
4899 if (ret != GST_FLOW_OK)
4901 if (flush <= gst_adapter_available (demux->common.adapter))
4902 gst_adapter_flush (demux->common.adapter, flush);
4904 return GST_FLOW_EOS;
4909 /* initializes @ebml with @bytes from input stream at current offset.
4910 * Returns EOS if insufficient available,
4911 * ERROR if too much was attempted to read. */
4912 static inline GstFlowReturn
4913 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4916 GstBuffer *buffer = NULL;
4917 GstFlowReturn ret = GST_FLOW_OK;
4919 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4921 ret = gst_matroska_demux_check_read_size (demux, bytes);
4922 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4923 if (!demux->streaming) {
4924 /* in pull mode, we can skip */
4925 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4926 ret = GST_FLOW_OVERFLOW;
4928 /* otherwise fatal */
4929 ret = GST_FLOW_ERROR;
4933 if (demux->streaming) {
4934 if (gst_adapter_available (demux->common.adapter) >= bytes)
4935 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4939 ret = gst_matroska_read_common_peek_bytes (&demux->common,
4940 demux->common.offset, bytes, &buffer, NULL);
4941 if (G_LIKELY (buffer)) {
4942 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4943 demux->common.offset);
4944 demux->common.offset += bytes;
4951 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4954 gboolean seekable = FALSE;
4955 gint64 start = -1, stop = -1;
4957 query = gst_query_new_seeking (GST_FORMAT_BYTES);
4958 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4959 GST_DEBUG_OBJECT (demux, "seeking query failed");
4963 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4965 /* try harder to query upstream size if we didn't get it the first time */
4966 if (seekable && stop == -1) {
4967 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4968 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4972 /* if upstream doesn't know the size, it's likely that it's not seekable in
4973 * practice even if it technically may be seekable */
4974 if (seekable && (start != 0 || stop <= start)) {
4975 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4980 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4981 G_GUINT64_FORMAT ")", seekable, start, stop);
4982 demux->seekable = seekable;
4984 gst_query_unref (query);
4987 static GstFlowReturn
4988 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4994 GstFlowReturn ret = GST_FLOW_OK;
4996 GST_WARNING_OBJECT (demux,
4997 "Found Cluster element before Tracks, searching Tracks");
5000 before_pos = demux->common.offset;
5002 /* Search Tracks element */
5004 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
5005 GST_ELEMENT_CAST (demux), &id, &length, &needed);
5006 if (ret != GST_FLOW_OK)
5009 if (id != GST_MATROSKA_ID_TRACKS) {
5010 /* we may be skipping large cluster here, so forego size check etc */
5011 /* ... but we can't skip undefined size; force error */
5012 if (length == G_MAXUINT64) {
5013 ret = gst_matroska_demux_check_read_size (demux, length);
5016 demux->common.offset += needed;
5017 demux->common.offset += length;
5022 /* will lead to track parsing ... */
5023 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5028 demux->common.offset = before_pos;
5033 #define GST_READ_CHECK(stmt) \
5035 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
5036 if (ret == GST_FLOW_OVERFLOW) { \
5037 ret = GST_FLOW_OK; \
5043 static GstFlowReturn
5044 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
5045 guint64 length, guint needed)
5047 GstEbmlRead ebml = { 0, };
5048 GstFlowReturn ret = GST_FLOW_OK;
5051 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
5052 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
5054 /* if we plan to read and parse this element, we need prefix (id + length)
5055 * and the contents */
5056 /* mind about overflow wrap-around when dealing with undefined size */
5058 if (G_LIKELY (length != G_MAXUINT64))
5061 switch (demux->common.state) {
5062 case GST_MATROSKA_READ_STATE_START:
5064 case GST_EBML_ID_HEADER:
5065 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5066 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
5067 if (ret != GST_FLOW_OK)
5069 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
5070 gst_matroska_demux_check_seekability (demux);
5073 goto invalid_header;
5077 case GST_MATROSKA_READ_STATE_SEGMENT:
5079 case GST_MATROSKA_ID_SEGMENT:
5080 /* eat segment prefix */
5081 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
5082 GST_DEBUG_OBJECT (demux,
5083 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
5084 G_GUINT64_FORMAT, demux->common.offset, length);
5085 /* seeks are from the beginning of the segment,
5086 * after the segment ID/length */
5087 demux->common.ebml_segment_start = demux->common.offset;
5089 length = G_MAXUINT64;
5090 demux->common.ebml_segment_length = length;
5091 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
5094 GST_WARNING_OBJECT (demux,
5095 "Expected a Segment ID (0x%x), but received 0x%x!",
5096 GST_MATROSKA_ID_SEGMENT, id);
5097 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5101 case GST_MATROSKA_READ_STATE_SCANNING:
5102 if (id != GST_MATROSKA_ID_CLUSTER &&
5103 id != GST_MATROSKA_ID_PREVSIZE &&
5104 id != GST_MATROSKA_ID_CLUSTERTIMECODE) {
5105 if (demux->common.start_resync_offset != -1) {
5106 /* we need to skip byte per byte if we are scanning for a new cluster
5107 * after invalid data is found
5113 if (demux->common.start_resync_offset != -1) {
5114 GST_LOG_OBJECT (demux, "Resync done, new cluster found!");
5115 demux->common.start_resync_offset = -1;
5116 demux->common.state = demux->common.state_to_restore;
5120 case GST_MATROSKA_READ_STATE_HEADER:
5121 case GST_MATROSKA_READ_STATE_DATA:
5122 case GST_MATROSKA_READ_STATE_SEEK:
5124 case GST_EBML_ID_HEADER:
5125 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5126 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
5127 gst_matroska_demux_check_seekability (demux);
5129 case GST_MATROSKA_ID_SEGMENTINFO:
5130 if (!demux->common.segmentinfo_parsed) {
5131 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5132 ret = gst_matroska_read_common_parse_info (&demux->common,
5133 GST_ELEMENT_CAST (demux), &ebml);
5134 if (ret == GST_FLOW_OK)
5135 gst_matroska_demux_send_tags (demux);
5137 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5140 case GST_MATROSKA_ID_TRACKS:
5141 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5142 if (!demux->tracks_parsed) {
5143 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
5145 ret = gst_matroska_demux_update_tracks (demux, &ebml);
5148 case GST_MATROSKA_ID_CLUSTER:
5149 if (G_UNLIKELY (!demux->tracks_parsed)) {
5150 if (demux->streaming) {
5151 GST_DEBUG_OBJECT (demux, "Cluster before Track");
5152 goto not_streamable;
5154 ret = gst_matroska_demux_find_tracks (demux);
5155 if (!demux->tracks_parsed)
5159 if (demux->common.state == GST_MATROSKA_READ_STATE_HEADER) {
5160 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
5161 demux->first_cluster_offset = demux->common.offset;
5163 if (!demux->streaming &&
5164 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.duration)) {
5165 GstMatroskaIndex *last = NULL;
5167 GST_DEBUG_OBJECT (demux,
5168 "estimating duration using last cluster");
5169 if ((last = gst_matroska_demux_search_pos (demux,
5170 GST_CLOCK_TIME_NONE)) != NULL) {
5171 demux->last_cluster_offset =
5172 last->pos + demux->common.ebml_segment_start;
5173 demux->stream_last_time = last->time;
5174 demux->common.segment.duration =
5175 demux->stream_last_time - demux->stream_start_time;
5176 /* above estimate should not be taken all too strongly */
5177 demux->invalid_duration = TRUE;
5178 GST_DEBUG_OBJECT (demux,
5179 "estimated duration as %" GST_TIME_FORMAT,
5180 GST_TIME_ARGS (demux->common.segment.duration));
5184 /* Peek at second cluster in order to figure out if we have cluster
5185 * prev_size or not (which is never set on the first cluster for
5186 * obvious reasons). This is useful in case someone initiates a
5187 * seek or direction change before we reach the second cluster. */
5188 if (!demux->streaming) {
5189 ClusterInfo cluster = { 0, };
5191 if (gst_matroska_demux_peek_cluster_info (demux, &cluster,
5192 demux->first_cluster_offset) && cluster.size > 0) {
5193 gst_matroska_demux_peek_cluster_info (demux, &cluster,
5194 demux->first_cluster_offset + cluster.size);
5196 demux->common.offset = demux->first_cluster_offset;
5199 GST_DEBUG_OBJECT (demux, "signaling no more pads");
5200 gst_element_no_more_pads (GST_ELEMENT (demux));
5201 /* send initial segment - we wait till we know the first
5202 incoming timestamp, so we can properly set the start of
5204 demux->need_segment = TRUE;
5206 demux->cluster_time = GST_CLOCK_TIME_NONE;
5207 demux->cluster_offset = demux->common.offset;
5208 demux->cluster_prevsize = 0;
5209 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
5210 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
5211 " not found in Cluster, trying next Cluster's first block instead",
5213 demux->seek_block = 0;
5215 demux->seek_first = FALSE;
5216 /* record next cluster for recovery */
5217 if (read != G_MAXUINT64)
5218 demux->next_cluster_offset = demux->cluster_offset + read;
5219 /* eat cluster prefix */
5220 gst_matroska_demux_flush (demux, needed);
5222 case GST_MATROSKA_ID_CLUSTERTIMECODE:
5226 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5227 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
5229 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
5230 demux->cluster_time = num;
5231 /* track last cluster */
5232 if (demux->cluster_offset > demux->last_cluster_offset) {
5233 demux->last_cluster_offset = demux->cluster_offset;
5234 demux->stream_last_time =
5235 demux->cluster_time * demux->common.time_scale;
5238 if (demux->common.element_index) {
5239 if (demux->common.element_index_writer_id == -1)
5240 gst_index_get_writer_id (demux->common.element_index,
5241 GST_OBJECT (demux), &demux->common.element_index_writer_id);
5242 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
5243 G_GUINT64_FORMAT " for writer id %d",
5244 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
5245 demux->common.element_index_writer_id);
5246 gst_index_add_association (demux->common.element_index,
5247 demux->common.element_index_writer_id,
5248 GST_ASSOCIATION_FLAG_KEY_UNIT,
5249 GST_FORMAT_TIME, demux->cluster_time,
5250 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
5255 case GST_MATROSKA_ID_BLOCKGROUP:
5256 if (!gst_matroska_demux_seek_block (demux))
5258 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5259 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
5260 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
5261 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
5262 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
5264 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
5266 case GST_MATROSKA_ID_SIMPLEBLOCK:
5267 if (!gst_matroska_demux_seek_block (demux))
5269 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5270 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
5271 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
5272 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
5273 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
5275 case GST_MATROSKA_ID_ATTACHMENTS:
5276 if (!demux->common.attachments_parsed) {
5277 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5278 ret = gst_matroska_read_common_parse_attachments (&demux->common,
5279 GST_ELEMENT_CAST (demux), &ebml);
5280 if (ret == GST_FLOW_OK)
5281 gst_matroska_demux_send_tags (demux);
5283 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5286 case GST_MATROSKA_ID_TAGS:
5287 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5288 ret = gst_matroska_read_common_parse_metadata (&demux->common,
5289 GST_ELEMENT_CAST (demux), &ebml);
5290 if (ret == GST_FLOW_OK)
5291 gst_matroska_demux_send_tags (demux);
5293 case GST_MATROSKA_ID_CHAPTERS:
5294 if (!demux->common.chapters_parsed) {
5295 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5297 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
5299 if (demux->common.toc) {
5300 gst_matroska_demux_send_event (demux,
5301 gst_event_new_toc (demux->common.toc, FALSE));
5304 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5306 case GST_MATROSKA_ID_SEEKHEAD:
5307 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5308 ret = gst_matroska_demux_parse_contents (demux, &ebml);
5310 case GST_MATROSKA_ID_CUES:
5311 if (demux->common.index_parsed) {
5312 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5315 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5316 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
5317 /* only push based; delayed index building */
5318 if (ret == GST_FLOW_OK
5319 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
5322 GST_OBJECT_LOCK (demux);
5323 event = demux->seek_event;
5324 demux->seek_event = NULL;
5325 GST_OBJECT_UNLOCK (demux);
5328 /* unlikely to fail, since we managed to seek to this point */
5329 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
5330 gst_event_unref (event);
5333 gst_event_unref (event);
5334 /* resume data handling, main thread clear to seek again */
5335 GST_OBJECT_LOCK (demux);
5336 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
5337 GST_OBJECT_UNLOCK (demux);
5340 case GST_MATROSKA_ID_PREVSIZE:{
5343 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5344 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
5346 GST_LOG_OBJECT (demux, "ClusterPrevSize: %" G_GUINT64_FORMAT, num);
5347 demux->cluster_prevsize = num;
5348 demux->seen_cluster_prevsize = TRUE;
5351 case GST_MATROSKA_ID_POSITION:
5352 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
5353 case GST_MATROSKA_ID_SILENTTRACKS:
5354 GST_DEBUG_OBJECT (demux,
5355 "Skipping Cluster subelement 0x%x - ignoring", id);
5359 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
5360 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5366 if (ret == GST_FLOW_PARSE)
5370 gst_ebml_read_clear (&ebml);
5376 /* simply exit, maybe not enough data yet */
5377 /* no ebml to clear if read error */
5382 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5383 ("Failed to parse Element 0x%x", id));
5384 ret = GST_FLOW_ERROR;
5389 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5390 ("File layout does not permit streaming"));
5391 ret = GST_FLOW_ERROR;
5396 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5397 ("No Tracks element found"));
5398 ret = GST_FLOW_ERROR;
5403 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
5404 ret = GST_FLOW_ERROR;
5409 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
5410 ret = GST_FLOW_ERROR;
5416 gst_matroska_demux_loop (GstPad * pad)
5418 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
5424 /* If we have to close a segment, send a new segment to do this now */
5425 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
5426 if (G_UNLIKELY (demux->new_segment)) {
5427 gst_matroska_demux_send_event (demux, demux->new_segment);
5428 demux->new_segment = NULL;
5432 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
5433 GST_ELEMENT_CAST (demux), &id, &length, &needed);
5434 if (ret == GST_FLOW_EOS) {
5436 } else if (ret == GST_FLOW_FLUSHING) {
5438 } else if (ret != GST_FLOW_OK) {
5439 ret = gst_matroska_demux_check_parse_error (demux);
5441 /* Only handle EOS as no error if we're outside the segment already */
5442 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
5443 && demux->common.offset >=
5444 demux->common.ebml_segment_start +
5445 demux->common.ebml_segment_length))
5447 else if (ret != GST_FLOW_OK)
5453 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
5454 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
5457 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5458 if (ret == GST_FLOW_EOS)
5460 if (ret != GST_FLOW_OK)
5463 /* check if we're at the end of a configured segment */
5464 if (G_LIKELY (demux->common.src->len)) {
5467 g_assert (demux->common.num_streams == demux->common.src->len);
5468 for (i = 0; i < demux->common.src->len; i++) {
5469 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
5471 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
5472 GST_TIME_ARGS (context->pos));
5473 if (context->eos == FALSE)
5477 GST_INFO_OBJECT (demux, "All streams are EOS");
5483 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
5484 demux->common.offset >= demux->cached_length)) {
5485 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
5486 if (demux->common.offset == demux->cached_length) {
5487 GST_LOG_OBJECT (demux, "Reached end of stream");
5498 if (demux->common.segment.rate < 0.0) {
5499 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
5500 if (ret == GST_FLOW_OK)
5507 const gchar *reason = gst_flow_get_name (ret);
5508 gboolean push_eos = FALSE;
5510 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
5511 gst_pad_pause_task (demux->common.sinkpad);
5513 if (ret == GST_FLOW_EOS) {
5514 /* perform EOS logic */
5516 /* If we were in the headers, make sure we send no-more-pads.
5517 This will ensure decodebin does not get stuck thinking
5518 the chain is not complete yet, and waiting indefinitely. */
5519 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
5520 if (demux->common.src->len == 0) {
5521 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
5522 ("No pads created"));
5524 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
5525 ("Failed to finish reading headers"));
5527 gst_element_no_more_pads (GST_ELEMENT (demux));
5530 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
5535 /* for segment playback we need to post when (in stream time)
5536 * we stopped, this is either stop (when set) or the duration. */
5537 if ((stop = demux->common.segment.stop) == -1)
5538 stop = demux->last_stop_end;
5540 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
5541 msg = gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
5543 if (demux->segment_seqnum)
5544 gst_message_set_seqnum (msg, demux->segment_seqnum);
5545 gst_element_post_message (GST_ELEMENT (demux), msg);
5547 event = gst_event_new_segment_done (GST_FORMAT_TIME, stop);
5548 if (demux->segment_seqnum)
5549 gst_event_set_seqnum (event, demux->segment_seqnum);
5550 gst_matroska_demux_send_event (demux, event);
5554 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
5555 /* for fatal errors we post an error message */
5556 GST_ELEMENT_FLOW_ERROR (demux, ret);
5562 /* send EOS, and prevent hanging if no streams yet */
5563 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
5564 event = gst_event_new_eos ();
5565 if (demux->segment_seqnum)
5566 gst_event_set_seqnum (event, demux->segment_seqnum);
5567 if (!gst_matroska_demux_send_event (demux, event) &&
5568 (ret == GST_FLOW_EOS)) {
5569 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5570 (NULL), ("got eos but no streams (yet)"));
5578 * Create and push a flushing seek event upstream
5581 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
5582 guint32 seqnum, GstSeekFlags flags)
5587 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
5590 gst_event_new_seek (rate, GST_FORMAT_BYTES,
5591 flags | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
5592 GST_SEEK_TYPE_SET, offset, GST_SEEK_TYPE_NONE, -1);
5593 gst_event_set_seqnum (event, seqnum);
5595 res = gst_pad_push_event (demux->common.sinkpad, event);
5597 /* segment event will update offset */
5601 static GstFlowReturn
5602 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
5604 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5606 GstFlowReturn ret = GST_FLOW_OK;
5611 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
5612 GST_DEBUG_OBJECT (demux, "got DISCONT");
5613 gst_adapter_clear (demux->common.adapter);
5614 GST_OBJECT_LOCK (demux);
5615 gst_matroska_read_common_reset_streams (&demux->common,
5616 GST_CLOCK_TIME_NONE, FALSE);
5617 GST_OBJECT_UNLOCK (demux);
5620 gst_adapter_push (demux->common.adapter, buffer);
5624 available = gst_adapter_available (demux->common.adapter);
5626 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
5627 GST_ELEMENT_CAST (demux), &id, &length, &needed);
5628 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
5629 if (demux->common.ebml_segment_length != G_MAXUINT64
5630 && demux->common.offset >=
5631 demux->common.ebml_segment_start + demux->common.ebml_segment_length) {
5634 gint64 bytes_scanned;
5635 if (demux->common.start_resync_offset == -1) {
5636 demux->common.start_resync_offset = demux->common.offset;
5637 demux->common.state_to_restore = demux->common.state;
5639 bytes_scanned = demux->common.offset - demux->common.start_resync_offset;
5640 if (bytes_scanned <= INVALID_DATA_THRESHOLD) {
5641 GST_WARNING_OBJECT (demux,
5642 "parse error, looking for next cluster, actual offset %"
5643 G_GUINT64_FORMAT ", start resync offset %" G_GUINT64_FORMAT,
5644 demux->common.offset, demux->common.start_resync_offset);
5645 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
5648 GST_WARNING_OBJECT (demux,
5649 "unrecoverable parse error, next cluster not found and threshold "
5650 "exceeded, bytes scanned %" G_GINT64_FORMAT, bytes_scanned);
5656 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
5657 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
5658 demux->common.offset, id, length, needed, available);
5660 if (needed > available)
5663 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5664 if (ret == GST_FLOW_EOS) {
5665 /* need more data */
5667 } else if (ret != GST_FLOW_OK) {
5674 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
5677 gboolean res = TRUE;
5678 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5680 GST_DEBUG_OBJECT (demux,
5681 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
5683 switch (GST_EVENT_TYPE (event)) {
5684 case GST_EVENT_SEGMENT:
5686 const GstSegment *segment;
5688 /* some debug output */
5689 gst_event_parse_segment (event, &segment);
5690 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
5691 GST_DEBUG_OBJECT (demux,
5692 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
5695 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
5696 GST_DEBUG_OBJECT (demux, "still starting");
5700 /* we only expect a BYTE segment, e.g. following a seek */
5701 if (segment->format != GST_FORMAT_BYTES) {
5702 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
5706 GST_DEBUG_OBJECT (demux, "clearing segment state");
5707 GST_OBJECT_LOCK (demux);
5708 /* clear current segment leftover */
5709 gst_adapter_clear (demux->common.adapter);
5710 /* and some streaming setup */
5711 demux->common.offset = segment->start;
5712 /* accumulate base based on current position */
5713 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
5714 demux->common.segment.base +=
5715 (MAX (demux->common.segment.position, demux->stream_start_time)
5716 - demux->stream_start_time) / fabs (demux->common.segment.rate);
5717 /* do not know where we are;
5718 * need to come across a cluster and generate segment */
5719 demux->common.segment.position = GST_CLOCK_TIME_NONE;
5720 demux->cluster_time = GST_CLOCK_TIME_NONE;
5721 demux->cluster_offset = 0;
5722 demux->cluster_prevsize = 0;
5723 demux->need_segment = TRUE;
5724 demux->segment_seqnum = gst_event_get_seqnum (event);
5725 /* but keep some of the upstream segment */
5726 demux->common.segment.rate = segment->rate;
5727 demux->common.segment.flags = segment->flags;
5728 /* also check if need to keep some of the requested seek position */
5729 if (demux->seek_offset == segment->start) {
5730 GST_DEBUG_OBJECT (demux, "position matches requested seek");
5731 demux->common.segment.position = demux->requested_seek_time;
5733 GST_DEBUG_OBJECT (demux, "unexpected segment position");
5735 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
5736 demux->seek_offset = -1;
5737 GST_OBJECT_UNLOCK (demux);
5739 /* chain will send initial segment after pads have been added,
5740 * or otherwise come up with one */
5741 GST_DEBUG_OBJECT (demux, "eating event");
5742 gst_event_unref (event);
5748 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA
5749 && demux->common.state != GST_MATROSKA_READ_STATE_SCANNING) {
5750 gst_event_unref (event);
5751 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5752 (NULL), ("got eos and didn't receive a complete header object"));
5753 } else if (demux->common.num_streams == 0) {
5754 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5755 (NULL), ("got eos but no streams (yet)"));
5757 gst_matroska_demux_send_event (demux, event);
5761 case GST_EVENT_FLUSH_STOP:
5765 gst_adapter_clear (demux->common.adapter);
5766 GST_OBJECT_LOCK (demux);
5767 gst_matroska_read_common_reset_streams (&demux->common,
5768 GST_CLOCK_TIME_NONE, TRUE);
5769 gst_flow_combiner_reset (demux->flowcombiner);
5770 dur = demux->common.segment.duration;
5771 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
5772 demux->common.segment.duration = dur;
5773 demux->cluster_time = GST_CLOCK_TIME_NONE;
5774 demux->cluster_offset = 0;
5775 demux->cluster_prevsize = 0;
5776 GST_OBJECT_UNLOCK (demux);
5780 res = gst_pad_event_default (pad, parent, event);
5788 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
5790 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5792 gboolean pull_mode = FALSE;
5794 query = gst_query_new_scheduling ();
5796 if (gst_pad_peer_query (sinkpad, query))
5797 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
5798 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
5800 gst_query_unref (query);
5803 GST_DEBUG ("going to pull mode");
5804 demux->streaming = FALSE;
5805 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
5807 GST_DEBUG ("going to push (streaming) mode");
5808 demux->streaming = TRUE;
5809 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
5814 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
5815 GstPadMode mode, gboolean active)
5818 case GST_PAD_MODE_PULL:
5820 /* if we have a scheduler we can start the task */
5821 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
5824 gst_pad_stop_task (sinkpad);
5827 case GST_PAD_MODE_PUSH:
5835 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
5836 videocontext, const gchar * codec_id, guint8 * data, guint size,
5837 gchar ** codec_name, guint32 * riff_fourcc)
5839 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
5840 GstCaps *caps = NULL;
5842 g_assert (videocontext != NULL);
5843 g_assert (codec_name != NULL);
5848 /* TODO: check if we have all codec types from matroska-ids.h
5849 * check if we have to do more special things with codec_private
5852 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
5853 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
5856 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
5857 gst_riff_strf_vids *vids = NULL;
5860 GstBuffer *buf = NULL;
5862 vids = (gst_riff_strf_vids *) data;
5864 /* assure size is big enough */
5866 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
5869 if (size < sizeof (gst_riff_strf_vids)) {
5870 vids = g_new (gst_riff_strf_vids, 1);
5871 memcpy (vids, data, size);
5874 context->dts_only = TRUE; /* VFW files only store DTS */
5876 /* little-endian -> byte-order */
5877 vids->size = GUINT32_FROM_LE (vids->size);
5878 vids->width = GUINT32_FROM_LE (vids->width);
5879 vids->height = GUINT32_FROM_LE (vids->height);
5880 vids->planes = GUINT16_FROM_LE (vids->planes);
5881 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
5882 vids->compression = GUINT32_FROM_LE (vids->compression);
5883 vids->image_size = GUINT32_FROM_LE (vids->image_size);
5884 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
5885 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
5886 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
5887 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
5889 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
5890 gsize offset = sizeof (gst_riff_strf_vids);
5893 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
5894 size - offset), size - offset);
5898 *riff_fourcc = vids->compression;
5900 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
5901 buf, NULL, codec_name);
5904 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
5905 GST_FOURCC_ARGS (vids->compression));
5907 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
5908 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
5909 "video/x-compressed-yuv");
5910 context->intra_only =
5911 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
5915 gst_buffer_unref (buf);
5917 if (vids != (gst_riff_strf_vids *) data)
5920 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
5922 GstVideoFormat format;
5924 gst_video_info_init (&info);
5925 switch (videocontext->fourcc) {
5926 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5927 format = GST_VIDEO_FORMAT_I420;
5929 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5930 format = GST_VIDEO_FORMAT_YUY2;
5932 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5933 format = GST_VIDEO_FORMAT_YV12;
5935 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5936 format = GST_VIDEO_FORMAT_UYVY;
5938 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5939 format = GST_VIDEO_FORMAT_AYUV;
5941 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
5942 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
5943 format = GST_VIDEO_FORMAT_GRAY8;
5945 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
5946 format = GST_VIDEO_FORMAT_RGB;
5948 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
5949 format = GST_VIDEO_FORMAT_BGR;
5952 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5953 GST_FOURCC_ARGS (videocontext->fourcc));
5957 context->intra_only = TRUE;
5959 gst_video_info_set_format (&info, format, videocontext->pixel_width,
5960 videocontext->pixel_height);
5961 caps = gst_video_info_to_caps (&info);
5962 *codec_name = gst_pb_utils_get_codec_description (caps);
5963 context->alignment = 32;
5964 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5965 caps = gst_caps_new_simple ("video/x-divx",
5966 "divxversion", G_TYPE_INT, 4, NULL);
5967 *codec_name = g_strdup ("MPEG-4 simple profile");
5968 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5969 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5970 caps = gst_caps_new_simple ("video/mpeg",
5971 "mpegversion", G_TYPE_INT, 4,
5972 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5976 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5977 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5978 gst_buffer_unref (priv);
5980 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
5982 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5983 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5985 *codec_name = g_strdup ("MPEG-4 advanced profile");
5986 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5988 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5989 "divxversion", G_TYPE_INT, 3, NULL),
5990 gst_structure_new ("video/x-msmpeg",
5991 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5993 caps = gst_caps_new_simple ("video/x-msmpeg",
5994 "msmpegversion", G_TYPE_INT, 43, NULL);
5995 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5996 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5997 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
6000 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
6005 caps = gst_caps_new_simple ("video/mpeg",
6006 "systemstream", G_TYPE_BOOLEAN, FALSE,
6007 "mpegversion", G_TYPE_INT, mpegversion, NULL);
6008 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
6009 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
6010 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
6011 caps = gst_caps_new_empty_simple ("image/jpeg");
6012 *codec_name = g_strdup ("Motion-JPEG");
6013 context->intra_only = TRUE;
6014 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
6015 caps = gst_caps_new_empty_simple ("video/x-h264");
6019 /* First byte is the version, second is the profile indication, and third
6020 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
6021 * level indication. */
6022 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
6025 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
6026 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6027 gst_buffer_unref (priv);
6029 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
6030 "alignment", G_TYPE_STRING, "au", NULL);
6032 GST_WARNING ("No codec data found, assuming output is byte-stream");
6033 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
6036 *codec_name = g_strdup ("H264");
6037 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
6038 caps = gst_caps_new_empty_simple ("video/x-h265");
6042 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
6045 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
6046 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6047 gst_buffer_unref (priv);
6049 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
6050 "alignment", G_TYPE_STRING, "au", NULL);
6052 GST_WARNING ("No codec data found, assuming output is byte-stream");
6053 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
6056 *codec_name = g_strdup ("HEVC");
6057 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
6058 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
6059 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
6060 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
6061 gint rmversion = -1;
6063 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
6065 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
6067 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
6069 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
6072 caps = gst_caps_new_simple ("video/x-pn-realvideo",
6073 "rmversion", G_TYPE_INT, rmversion, NULL);
6074 GST_DEBUG ("data:%p, size:0x%x", data, size);
6075 /* We need to extract the extradata ! */
6076 if (data && (size >= 0x22)) {
6081 subformat = GST_READ_UINT32_BE (data + 0x1a);
6082 rformat = GST_READ_UINT32_BE (data + 0x1e);
6085 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
6087 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
6088 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
6089 gst_buffer_unref (priv);
6092 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
6093 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
6094 caps = gst_caps_new_empty_simple ("video/x-theora");
6095 context->stream_headers =
6096 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6097 context->codec_priv_size);
6098 /* FIXME: mark stream as broken and skip if there are no stream headers */
6099 context->send_stream_headers = TRUE;
6100 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
6101 caps = gst_caps_new_empty_simple ("video/x-dirac");
6102 *codec_name = g_strdup_printf ("Dirac");
6103 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
6104 caps = gst_caps_new_empty_simple ("video/x-vp8");
6105 *codec_name = g_strdup_printf ("On2 VP8");
6106 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
6107 caps = gst_caps_new_empty_simple ("video/x-vp9");
6108 *codec_name = g_strdup_printf ("On2 VP9");
6109 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_AV1)) {
6110 caps = gst_caps_new_empty_simple ("video/x-av1");
6114 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
6115 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6116 gst_buffer_unref (priv);
6118 GST_WARNING ("No codec data found, assuming output is byte-stream");
6119 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
6122 *codec_name = g_strdup_printf ("AOM AV1");
6123 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
6125 const gchar *variant, *variant_descr = "";
6127 /* Expect a fourcc in the codec private data */
6128 if (!data || size < 4) {
6129 GST_WARNING ("No or too small PRORESS fourcc (%d bytes)", size);
6133 fourcc = GST_STR_FOURCC (data);
6135 case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
6136 variant_descr = " 4:2:2 LT";
6139 case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
6141 variant_descr = " 4:2:2 HQ";
6143 case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
6145 variant_descr = " 4:4:4:4";
6147 case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
6149 variant_descr = " 4:2:2 Proxy";
6151 case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
6153 variant = "standard";
6154 variant_descr = " 4:2:2 SD";
6158 GST_LOG ("Prores video, codec fourcc %" GST_FOURCC_FORMAT,
6159 GST_FOURCC_ARGS (fourcc));
6161 caps = gst_caps_new_simple ("video/x-prores",
6162 "format", G_TYPE_STRING, variant, NULL);
6163 *codec_name = g_strdup_printf ("Apple ProRes%s", variant_descr);
6164 context->postprocess_frame = gst_matroska_demux_add_prores_header;
6166 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6172 GstStructure *structure;
6174 for (i = 0; i < gst_caps_get_size (caps); i++) {
6175 structure = gst_caps_get_structure (caps, i);
6177 /* FIXME: use the real unit here! */
6178 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
6179 videocontext->pixel_width,
6180 videocontext->pixel_height,
6181 videocontext->display_width, videocontext->display_height);
6183 /* pixel width and height are the w and h of the video in pixels */
6184 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
6185 gint w = videocontext->pixel_width;
6186 gint h = videocontext->pixel_height;
6188 gst_structure_set (structure,
6189 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
6192 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
6195 if (videocontext->display_width <= 0)
6196 videocontext->display_width = videocontext->pixel_width;
6197 if (videocontext->display_height <= 0)
6198 videocontext->display_height = videocontext->pixel_height;
6200 /* calculate the pixel aspect ratio using the display and pixel w/h */
6201 n = videocontext->display_width * videocontext->pixel_height;
6202 d = videocontext->display_height * videocontext->pixel_width;
6203 GST_DEBUG ("setting PAR to %d/%d", n, d);
6204 gst_structure_set (structure, "pixel-aspect-ratio",
6206 videocontext->display_width * videocontext->pixel_height,
6207 videocontext->display_height * videocontext->pixel_width, NULL);
6210 if (videocontext->default_fps > 0.0) {
6213 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
6215 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
6217 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
6219 } else if (context->default_duration > 0) {
6222 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
6224 GST_INFO ("using default duration %" G_GUINT64_FORMAT
6225 " framerate %d/%d", context->default_duration, fps_n, fps_d);
6227 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
6228 fps_n, fps_d, NULL);
6230 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
6234 switch (videocontext->interlace_mode) {
6235 case GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE:
6236 gst_structure_set (structure,
6237 "interlace-mode", G_TYPE_STRING, "progressive", NULL);
6239 case GST_MATROSKA_INTERLACE_MODE_INTERLACED:
6240 gst_structure_set (structure,
6241 "interlace-mode", G_TYPE_STRING, "mixed", NULL);
6247 if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
6248 if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
6249 videocontext->pixel_width, videocontext->pixel_height,
6250 videocontext->display_width * videocontext->pixel_height,
6251 videocontext->display_height * videocontext->pixel_width)) {
6252 videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
6254 gst_caps_set_simple (caps,
6255 "multiview-mode", G_TYPE_STRING,
6256 gst_video_multiview_mode_to_caps_string
6257 (videocontext->multiview_mode), "multiview-flags",
6258 GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
6259 GST_FLAG_SET_MASK_EXACT, NULL);
6262 if (videocontext->colorimetry.range != GST_VIDEO_COLOR_RANGE_UNKNOWN ||
6263 videocontext->colorimetry.matrix != GST_VIDEO_COLOR_MATRIX_UNKNOWN ||
6264 videocontext->colorimetry.transfer != GST_VIDEO_TRANSFER_UNKNOWN ||
6265 videocontext->colorimetry.primaries !=
6266 GST_VIDEO_COLOR_PRIMARIES_UNKNOWN) {
6267 gchar *colorimetry =
6268 gst_video_colorimetry_to_string (&videocontext->colorimetry);
6269 gst_caps_set_simple (caps, "colorimetry", G_TYPE_STRING, colorimetry,
6271 GST_DEBUG ("setting colorimetry to %s", colorimetry);
6272 g_free (colorimetry);
6275 caps = gst_caps_simplify (caps);
6282 * Some AAC specific code... *sigh*
6283 * FIXME: maybe we should use '15' and code the sample rate explicitly
6284 * if the sample rate doesn't match the predefined rates exactly? (tpm)
6288 aac_rate_idx (gint rate)
6292 else if (75132 <= rate)
6294 else if (55426 <= rate)
6296 else if (46009 <= rate)
6298 else if (37566 <= rate)
6300 else if (27713 <= rate)
6302 else if (23004 <= rate)
6304 else if (18783 <= rate)
6306 else if (13856 <= rate)
6308 else if (11502 <= rate)
6310 else if (9391 <= rate)
6317 aac_profile_idx (const gchar * codec_id)
6321 if (strlen (codec_id) <= 12)
6323 else if (!strncmp (&codec_id[12], "MAIN", 4))
6325 else if (!strncmp (&codec_id[12], "LC", 2))
6327 else if (!strncmp (&codec_id[12], "SSR", 3))
6336 round_up_pow2 (guint n)
6347 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
6350 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
6351 audiocontext, const gchar * codec_id, guint8 * data, guint size,
6352 gchar ** codec_name, guint16 * riff_audio_fmt)
6354 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
6355 GstCaps *caps = NULL;
6357 g_assert (audiocontext != NULL);
6358 g_assert (codec_name != NULL);
6361 *riff_audio_fmt = 0;
6363 /* TODO: check if we have all codec types from matroska-ids.h
6364 * check if we have to do more special things with codec_private
6365 * check if we need bitdepth in different places too
6366 * implement channel position magic
6368 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
6369 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
6370 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
6371 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
6374 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
6375 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
6376 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
6379 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
6381 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
6386 caps = gst_caps_new_simple ("audio/mpeg",
6387 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
6388 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
6389 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
6390 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
6393 GstAudioFormat format;
6395 sign = (audiocontext->bitdepth != 8);
6396 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
6397 endianness = G_BIG_ENDIAN;
6399 endianness = G_LITTLE_ENDIAN;
6401 format = gst_audio_format_build_integer (sign, endianness,
6402 audiocontext->bitdepth, audiocontext->bitdepth);
6404 /* FIXME: Channel mask and reordering */
6405 caps = gst_caps_new_simple ("audio/x-raw",
6406 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
6407 "layout", G_TYPE_STRING, "interleaved",
6408 "channel-mask", GST_TYPE_BITMASK,
6409 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
6411 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
6412 audiocontext->bitdepth);
6413 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
6414 context->alignment = round_up_pow2 (context->alignment);
6415 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
6416 const gchar *format;
6417 if (audiocontext->bitdepth == 32)
6421 /* FIXME: Channel mask and reordering */
6422 caps = gst_caps_new_simple ("audio/x-raw",
6423 "format", G_TYPE_STRING, format,
6424 "layout", G_TYPE_STRING, "interleaved",
6425 "channel-mask", GST_TYPE_BITMASK,
6426 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
6427 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
6428 audiocontext->bitdepth);
6429 context->alignment = audiocontext->bitdepth / 8;
6430 context->alignment = round_up_pow2 (context->alignment);
6431 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
6432 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
6433 caps = gst_caps_new_simple ("audio/x-ac3",
6434 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6435 *codec_name = g_strdup ("AC-3 audio");
6436 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
6437 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
6438 caps = gst_caps_new_simple ("audio/x-eac3",
6439 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6440 *codec_name = g_strdup ("E-AC-3 audio");
6441 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
6442 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
6443 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
6444 *codec_name = g_strdup ("Dolby TrueHD");
6445 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
6446 caps = gst_caps_new_empty_simple ("audio/x-dts");
6447 *codec_name = g_strdup ("DTS audio");
6448 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
6449 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
6450 context->stream_headers =
6451 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6452 context->codec_priv_size);
6453 /* FIXME: mark stream as broken and skip if there are no stream headers */
6454 context->send_stream_headers = TRUE;
6455 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
6456 caps = gst_caps_new_empty_simple ("audio/x-flac");
6457 context->stream_headers =
6458 gst_matroska_parse_flac_stream_headers (context->codec_priv,
6459 context->codec_priv_size);
6460 /* FIXME: mark stream as broken and skip if there are no stream headers */
6461 context->send_stream_headers = TRUE;
6462 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
6463 caps = gst_caps_new_empty_simple ("audio/x-speex");
6464 context->stream_headers =
6465 gst_matroska_parse_speex_stream_headers (context->codec_priv,
6466 context->codec_priv_size);
6467 /* FIXME: mark stream as broken and skip if there are no stream headers */
6468 context->send_stream_headers = TRUE;
6469 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
6472 if (context->codec_priv_size >= 19) {
6473 if (audiocontext->samplerate)
6474 GST_WRITE_UINT32_LE ((guint8 *) context->codec_priv + 12,
6475 audiocontext->samplerate);
6476 if (context->codec_delay) {
6478 gst_util_uint64_scale_round (context->codec_delay, 48000,
6480 GST_WRITE_UINT16_LE ((guint8 *) context->codec_priv + 10, delay);
6484 gst_buffer_new_wrapped (g_memdup (context->codec_priv,
6485 context->codec_priv_size), context->codec_priv_size);
6486 caps = gst_codec_utils_opus_create_caps_from_header (tmp, NULL);
6487 gst_buffer_unref (tmp);
6488 *codec_name = g_strdup ("Opus");
6489 } else if (context->codec_priv_size == 0) {
6490 GST_WARNING ("No Opus codec data found, trying to create one");
6491 if (audiocontext->channels <= 2) {
6492 guint8 streams, coupled, channels;
6496 audiocontext->samplerate == 0 ? 48000 : audiocontext->samplerate;
6497 channels = audiocontext->channels == 0 ? 2 : audiocontext->channels;
6498 if (channels == 1) {
6507 gst_codec_utils_opus_create_caps (samplerate, channels, 0, streams,
6510 *codec_name = g_strdup ("Opus");
6512 GST_WARNING ("Failed to create Opus caps from audio context");
6515 GST_WARNING ("No Opus codec data, and not enough info to create one");
6518 GST_WARNING ("Invalid Opus codec data size (got %" G_GSIZE_FORMAT
6519 ", expected 19)", context->codec_priv_size);
6521 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
6522 gst_riff_strf_auds auds;
6524 if (data && size >= 18) {
6525 GstBuffer *codec_data = NULL;
6527 /* little-endian -> byte-order */
6528 auds.format = GST_READ_UINT16_LE (data);
6529 auds.channels = GST_READ_UINT16_LE (data + 2);
6530 auds.rate = GST_READ_UINT32_LE (data + 4);
6531 auds.av_bps = GST_READ_UINT32_LE (data + 8);
6532 auds.blockalign = GST_READ_UINT16_LE (data + 12);
6533 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
6535 /* 18 is the waveformatex size */
6537 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
6538 data + 18, size - 18, 0, size - 18, NULL, NULL);
6542 *riff_audio_fmt = auds.format;
6544 /* FIXME: Handle reorder map */
6545 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
6546 codec_data, codec_name, NULL);
6548 gst_buffer_unref (codec_data);
6551 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
6554 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
6556 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
6557 GstBuffer *priv = NULL;
6559 gint rate_idx, profile;
6560 guint8 *data = NULL;
6562 /* unspecified AAC profile with opaque private codec data */
6563 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
6564 if (context->codec_priv_size >= 2) {
6565 guint obj_type, freq_index, explicit_freq_bytes = 0;
6567 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6569 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
6570 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
6571 if (freq_index == 15)
6572 explicit_freq_bytes = 3;
6573 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
6574 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
6575 context->codec_priv_size), context->codec_priv_size);
6576 /* assume SBR if samplerate <= 24kHz */
6577 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
6578 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
6579 audiocontext->samplerate *= 2;
6582 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
6583 /* this is pretty broken;
6584 * maybe we need to make up some default private,
6585 * or maybe ADTS data got dumped in.
6586 * Let's set up some private data now, and check actual data later */
6587 /* just try this and see what happens ... */
6588 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6589 context->postprocess_frame = gst_matroska_demux_check_aac;
6593 /* make up decoder-specific data if it is not supplied */
6597 priv = gst_buffer_new_allocate (NULL, 5, NULL);
6598 gst_buffer_map (priv, &map, GST_MAP_WRITE);
6600 rate_idx = aac_rate_idx (audiocontext->samplerate);
6601 profile = aac_profile_idx (codec_id);
6603 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
6604 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
6606 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
6607 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
6609 gst_buffer_unmap (priv, &map);
6610 gst_buffer_set_size (priv, 2);
6611 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
6612 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
6615 if (g_strrstr (codec_id, "SBR")) {
6616 /* HE-AAC (aka SBR AAC) */
6617 audiocontext->samplerate *= 2;
6618 rate_idx = aac_rate_idx (audiocontext->samplerate);
6619 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
6620 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
6621 data[4] = (1 << 7) | (rate_idx << 3);
6622 gst_buffer_unmap (priv, &map);
6624 gst_buffer_unmap (priv, &map);
6625 gst_buffer_set_size (priv, 2);
6628 gst_buffer_unmap (priv, &map);
6629 gst_buffer_unref (priv);
6631 GST_ERROR ("Unknown AAC profile and no codec private data");
6636 caps = gst_caps_new_simple ("audio/mpeg",
6637 "mpegversion", G_TYPE_INT, mpegversion,
6638 "framed", G_TYPE_BOOLEAN, TRUE,
6639 "stream-format", G_TYPE_STRING, "raw", NULL);
6640 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6641 if (context->codec_priv && context->codec_priv_size > 0)
6642 gst_codec_utils_aac_caps_set_level_and_profile (caps,
6643 context->codec_priv, context->codec_priv_size);
6644 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
6645 gst_buffer_unref (priv);
6647 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
6648 caps = gst_caps_new_simple ("audio/x-tta",
6649 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
6650 *codec_name = g_strdup ("TTA audio");
6651 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
6652 caps = gst_caps_new_simple ("audio/x-wavpack",
6653 "width", G_TYPE_INT, audiocontext->bitdepth,
6654 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6655 *codec_name = g_strdup ("Wavpack audio");
6656 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
6657 audiocontext->wvpk_block_index = 0;
6658 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
6659 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
6660 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
6661 gint raversion = -1;
6663 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
6665 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
6670 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
6671 "raversion", G_TYPE_INT, raversion, NULL);
6672 /* Extract extra information from caps, mapping varies based on codec */
6673 if (data && (size >= 0x50)) {
6680 guint extra_data_size;
6682 GST_DEBUG ("real audio raversion:%d", raversion);
6683 if (raversion == 8) {
6685 flavor = GST_READ_UINT16_BE (data + 22);
6686 packet_size = GST_READ_UINT32_BE (data + 24);
6687 height = GST_READ_UINT16_BE (data + 40);
6688 leaf_size = GST_READ_UINT16_BE (data + 44);
6689 sample_width = GST_READ_UINT16_BE (data + 58);
6690 extra_data_size = GST_READ_UINT32_BE (data + 74);
6693 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
6694 flavor, packet_size, height, leaf_size, sample_width,
6696 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
6697 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
6698 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
6700 if ((size - 78) >= extra_data_size) {
6701 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
6703 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6704 gst_buffer_unref (priv);
6709 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
6710 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
6711 caps = gst_caps_new_empty_simple ("audio/x-sipro");
6712 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
6713 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
6714 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
6715 *codec_name = g_strdup ("Real Audio Lossless");
6716 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
6717 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
6718 *codec_name = g_strdup ("Sony ATRAC3");
6720 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6725 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
6728 for (i = 0; i < gst_caps_get_size (caps); i++) {
6729 gst_structure_set (gst_caps_get_structure (caps, i),
6730 "channels", G_TYPE_INT, audiocontext->channels,
6731 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
6735 caps = gst_caps_simplify (caps);
6742 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
6743 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
6745 GstCaps *caps = NULL;
6746 GstMatroskaTrackContext *context =
6747 (GstMatroskaTrackContext *) subtitlecontext;
6749 /* for backwards compatibility */
6750 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
6751 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
6752 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
6753 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
6754 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
6755 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
6756 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
6757 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
6759 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
6760 * Check if we have to do something with codec_private */
6761 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
6762 /* well, plain text simply does not have a lot of markup ... */
6763 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
6764 "pango-markup", NULL);
6765 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6766 subtitlecontext->check_markup = TRUE;
6767 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
6768 caps = gst_caps_new_empty_simple ("application/x-ssa");
6769 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6770 subtitlecontext->check_markup = FALSE;
6771 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
6772 caps = gst_caps_new_empty_simple ("application/x-ass");
6773 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6774 subtitlecontext->check_markup = FALSE;
6775 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
6776 caps = gst_caps_new_empty_simple ("application/x-usf");
6777 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6778 subtitlecontext->check_markup = FALSE;
6779 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
6780 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
6781 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
6782 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
6783 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
6784 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
6785 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
6786 context->stream_headers =
6787 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6788 context->codec_priv_size);
6789 /* FIXME: mark stream as broken and skip if there are no stream headers */
6790 context->send_stream_headers = TRUE;
6792 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
6793 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
6796 if (data != NULL && size > 0) {
6799 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
6800 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
6801 gst_buffer_unref (buf);
6809 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
6811 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6813 GST_OBJECT_LOCK (demux);
6814 if (demux->common.element_index)
6815 gst_object_unref (demux->common.element_index);
6816 demux->common.element_index = index ? gst_object_ref (index) : NULL;
6817 GST_OBJECT_UNLOCK (demux);
6818 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
6819 demux->common.element_index);
6823 gst_matroska_demux_get_index (GstElement * element)
6825 GstIndex *result = NULL;
6826 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6828 GST_OBJECT_LOCK (demux);
6829 if (demux->common.element_index)
6830 result = gst_object_ref (demux->common.element_index);
6831 GST_OBJECT_UNLOCK (demux);
6833 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
6839 static GstStateChangeReturn
6840 gst_matroska_demux_change_state (GstElement * element,
6841 GstStateChange transition)
6843 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6844 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
6846 /* handle upwards state changes here */
6847 switch (transition) {
6852 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
6854 /* handle downwards state changes */
6855 switch (transition) {
6856 case GST_STATE_CHANGE_PAUSED_TO_READY:
6857 gst_matroska_demux_reset (GST_ELEMENT (demux));
6867 gst_matroska_demux_set_property (GObject * object,
6868 guint prop_id, const GValue * value, GParamSpec * pspec)
6870 GstMatroskaDemux *demux;
6872 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6873 demux = GST_MATROSKA_DEMUX (object);
6876 case PROP_MAX_GAP_TIME:
6877 GST_OBJECT_LOCK (demux);
6878 demux->max_gap_time = g_value_get_uint64 (value);
6879 GST_OBJECT_UNLOCK (demux);
6881 case PROP_MAX_BACKTRACK_DISTANCE:
6882 GST_OBJECT_LOCK (demux);
6883 demux->max_backtrack_distance = g_value_get_uint (value);
6884 GST_OBJECT_UNLOCK (demux);
6887 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6893 gst_matroska_demux_get_property (GObject * object,
6894 guint prop_id, GValue * value, GParamSpec * pspec)
6896 GstMatroskaDemux *demux;
6898 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6899 demux = GST_MATROSKA_DEMUX (object);
6902 case PROP_MAX_GAP_TIME:
6903 GST_OBJECT_LOCK (demux);
6904 g_value_set_uint64 (value, demux->max_gap_time);
6905 GST_OBJECT_UNLOCK (demux);
6907 case PROP_MAX_BACKTRACK_DISTANCE:
6908 GST_OBJECT_LOCK (demux);
6909 g_value_set_uint (value, demux->max_backtrack_distance);
6910 GST_OBJECT_UNLOCK (demux);
6913 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6919 gst_matroska_demux_plugin_init (GstPlugin * plugin)
6923 /* parser helper separate debug */
6924 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
6925 0, "EBML stream helper class");
6927 /* create an elementfactory for the matroska_demux element */
6928 if (!gst_element_register (plugin, "matroskademux",
6929 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))