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 gboolean gst_matroska_demux_handle_sink_query (GstPad * pad,
155 GstObject * parent, GstQuery * query);
156 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
157 GstObject * object, GstBuffer * buffer);
159 static GstStateChangeReturn
160 gst_matroska_demux_change_state (GstElement * element,
161 GstStateChange transition);
164 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
165 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
169 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
170 * videocontext, const gchar * codec_id, guint8 * data, guint size,
171 gchar ** codec_name, guint32 * riff_fourcc);
172 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
173 * audiocontext, const gchar * codec_id, guint8 * data, guint size,
174 gchar ** codec_name, guint16 * riff_audio_fmt);
176 * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
177 subtitlecontext, const gchar * codec_id, gpointer data, guint size);
178 static const gchar *gst_matroska_track_encryption_algorithm_name (gint val);
179 static const gchar *gst_matroska_track_encryption_cipher_mode_name (gint val);
180 static const gchar *gst_matroska_track_encoding_scope_name (gint val);
183 static void gst_matroska_demux_reset (GstElement * element);
184 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
185 gdouble rate, guint64 offset, guint32 seqnum, GstSeekFlags flags);
187 /* gobject functions */
188 static void gst_matroska_demux_set_property (GObject * object,
189 guint prop_id, const GValue * value, GParamSpec * pspec);
190 static void gst_matroska_demux_get_property (GObject * object,
191 guint prop_id, GValue * value, GParamSpec * pspec);
193 GType gst_matroska_demux_get_type (void);
194 #define parent_class gst_matroska_demux_parent_class
195 G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
198 gst_matroska_demux_finalize (GObject * object)
200 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
202 gst_matroska_read_common_finalize (&demux->common);
203 gst_flow_combiner_free (demux->flowcombiner);
204 G_OBJECT_CLASS (parent_class)->finalize (object);
208 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
210 GObjectClass *gobject_class = (GObjectClass *) klass;
211 GstElementClass *gstelement_class = (GstElementClass *) klass;
213 GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
216 gobject_class->finalize = gst_matroska_demux_finalize;
218 gobject_class->get_property = gst_matroska_demux_get_property;
219 gobject_class->set_property = gst_matroska_demux_set_property;
221 g_object_class_install_property (gobject_class, PROP_MAX_GAP_TIME,
222 g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
223 "The demuxer sends out segment events for skipping "
224 "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
225 DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
227 g_object_class_install_property (gobject_class, PROP_MAX_BACKTRACK_DISTANCE,
228 g_param_spec_uint ("max-backtrack-distance",
229 "Maximum backtrack distance",
230 "Maximum backtrack distance in seconds when seeking without "
231 "and index in pull mode and search for a keyframe "
232 "(0 = disable backtracking).",
233 0, G_MAXUINT, DEFAULT_MAX_BACKTRACK_DISTANCE,
234 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
236 gstelement_class->change_state =
237 GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
238 gstelement_class->send_event =
239 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
240 gstelement_class->query =
241 GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
243 gstelement_class->set_index =
244 GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
245 gstelement_class->get_index =
246 GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
249 gst_element_class_add_static_pad_template (gstelement_class,
251 gst_element_class_add_static_pad_template (gstelement_class,
253 gst_element_class_add_static_pad_template (gstelement_class,
254 &subtitle_src_templ);
255 gst_element_class_add_static_pad_template (gstelement_class, &sink_templ);
257 gst_element_class_set_static_metadata (gstelement_class, "Matroska demuxer",
259 "Demuxes Matroska/WebM streams into video/audio/subtitles",
260 "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
264 gst_matroska_demux_init (GstMatroskaDemux * demux)
266 demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
268 gst_pad_set_activate_function (demux->common.sinkpad,
269 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
270 gst_pad_set_activatemode_function (demux->common.sinkpad,
271 GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
272 gst_pad_set_chain_function (demux->common.sinkpad,
273 GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
274 gst_pad_set_event_function (demux->common.sinkpad,
275 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
276 gst_pad_set_query_function (demux->common.sinkpad,
277 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_query));
278 gst_element_add_pad (GST_ELEMENT (demux), demux->common.sinkpad);
280 /* init defaults for common read context */
281 gst_matroska_read_common_init (&demux->common);
283 /* property defaults */
284 demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
285 demux->max_backtrack_distance = DEFAULT_MAX_BACKTRACK_DISTANCE;
287 GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);
289 demux->flowcombiner = gst_flow_combiner_new ();
292 gst_matroska_demux_reset (GST_ELEMENT (demux));
296 gst_matroska_demux_reset (GstElement * element)
298 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
300 GST_DEBUG_OBJECT (demux, "Resetting state");
302 gst_matroska_read_common_reset (GST_ELEMENT (demux), &demux->common);
304 demux->num_a_streams = 0;
305 demux->num_t_streams = 0;
306 demux->num_v_streams = 0;
307 demux->have_nonintraonly_v_streams = FALSE;
309 demux->have_group_id = FALSE;
310 demux->group_id = G_MAXUINT;
313 demux->tracks_parsed = FALSE;
315 if (demux->clusters) {
316 g_array_free (demux->clusters, TRUE);
317 demux->clusters = NULL;
320 g_list_foreach (demux->seek_parsed,
321 (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
322 g_list_free (demux->seek_parsed);
323 demux->seek_parsed = NULL;
325 demux->last_stop_end = GST_CLOCK_TIME_NONE;
326 demux->seek_block = 0;
327 demux->stream_start_time = GST_CLOCK_TIME_NONE;
328 demux->to_time = GST_CLOCK_TIME_NONE;
329 demux->cluster_time = GST_CLOCK_TIME_NONE;
330 demux->cluster_offset = 0;
331 demux->cluster_prevsize = 0;
332 demux->seen_cluster_prevsize = FALSE;
333 demux->next_cluster_offset = 0;
334 demux->stream_last_time = GST_CLOCK_TIME_NONE;
335 demux->last_cluster_offset = 0;
336 demux->index_offset = 0;
337 demux->seekable = FALSE;
338 demux->need_segment = FALSE;
339 demux->segment_seqnum = 0;
340 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
341 demux->seek_offset = -1;
342 demux->building_index = FALSE;
343 if (demux->seek_event) {
344 gst_event_unref (demux->seek_event);
345 demux->seek_event = NULL;
348 demux->seek_index = NULL;
349 demux->seek_entry = 0;
351 if (demux->new_segment) {
352 gst_event_unref (demux->new_segment);
353 demux->new_segment = NULL;
356 demux->invalid_duration = FALSE;
358 demux->cached_length = G_MAXUINT64;
360 gst_flow_combiner_clear (demux->flowcombiner);
364 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
369 GstBuffer *out_buf = buf;
371 g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
373 GST_DEBUG ("decoding buffer %p", buf);
375 gst_buffer_map (out_buf, &map, GST_MAP_READ);
379 g_return_val_if_fail (size > 0, buf);
381 if (gst_matroska_decode_data (context->encodings, &data, &size,
382 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
383 if (data != map.data) {
384 gst_buffer_unmap (out_buf, &map);
385 gst_buffer_unref (out_buf);
386 out_buf = gst_buffer_new_wrapped (data, size);
388 gst_buffer_unmap (out_buf, &map);
391 GST_DEBUG ("decode data failed");
392 gst_buffer_unmap (out_buf, &map);
393 gst_buffer_unref (out_buf);
396 /* Encrypted stream */
397 if (context->protection_info) {
399 GstStructure *info_protect = gst_structure_copy (context->protection_info);
400 gboolean encrypted = FALSE;
402 gst_buffer_map (out_buf, &map, GST_MAP_READ);
406 if (gst_matroska_parse_protection_meta (&data, &size, info_protect,
408 if (data != map.data) {
411 gst_buffer_unmap (out_buf, &map);
413 out_buf = gst_buffer_copy_region (tmp_buf, GST_BUFFER_COPY_ALL,
414 gst_buffer_get_size (tmp_buf) - size, size);
415 gst_buffer_unref (tmp_buf);
417 gst_buffer_add_protection_meta (out_buf, info_protect);
419 gst_structure_free (info_protect);
421 gst_buffer_unmap (out_buf, &map);
422 gst_structure_free (info_protect);
425 GST_WARNING ("Adding protection metadata failed");
426 gst_buffer_unmap (out_buf, &map);
427 gst_buffer_unref (out_buf);
428 gst_structure_free (info_protect);
437 gst_matroska_demux_add_stream_headers_to_caps (GstMatroskaDemux * demux,
438 GstBufferList * list, GstCaps * caps)
441 GValue arr_val = G_VALUE_INIT;
442 GValue buf_val = G_VALUE_INIT;
445 g_assert (gst_caps_is_writable (caps));
447 g_value_init (&arr_val, GST_TYPE_ARRAY);
448 g_value_init (&buf_val, GST_TYPE_BUFFER);
450 num = gst_buffer_list_length (list);
451 for (i = 0; i < num; ++i) {
452 g_value_set_boxed (&buf_val, gst_buffer_list_get (list, i));
453 gst_value_array_append_value (&arr_val, &buf_val);
456 s = gst_caps_get_structure (caps, 0);
457 gst_structure_take_value (s, "streamheader", &arr_val);
458 g_value_unset (&buf_val);
462 gst_matroska_demux_parse_colour (GstMatroskaDemux * demux, GstEbmlRead * ebml,
463 GstMatroskaTrackVideoContext * video_context)
466 GstVideoColorimetry colorimetry;
470 colorimetry.range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
471 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
472 colorimetry.transfer = GST_VIDEO_TRANSFER_UNKNOWN;
473 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
475 DEBUG_ELEMENT_START (demux, ebml, "TrackVideoColour");
477 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
480 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
481 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
485 case GST_MATROSKA_ID_VIDEOMATRIXCOEFFICIENTS:{
486 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
491 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
494 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT709;
497 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
500 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_FCC;
502 /* FIXME: "5: BT470BG" is undefined in GstVideoColorMatrix
503 * but it's functionally same as "6: BT601" */
506 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT601;
509 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_SMPTE240M;
512 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
515 GST_FIXME_OBJECT (demux, "Unsupported color matrix coefficients %"
516 G_GUINT64_FORMAT, num);
522 case GST_MATROSKA_ID_VIDEORANGE:{
523 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
528 colorimetry.range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
531 colorimetry.range = GST_VIDEO_COLOR_RANGE_16_235;
534 colorimetry.range = GST_VIDEO_COLOR_RANGE_0_255;
537 GST_FIXME_OBJECT (demux, "Unsupported color range %"
538 G_GUINT64_FORMAT, num);
544 case GST_MATROSKA_ID_VIDEOTRANSFERCHARACTERISTICS:{
545 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
549 /* FIXME: "6: BT601" and "14: BT2020_10" are undefined in
550 * GstVideoTransferFunction, but functionally same as "1: BT709" */
554 colorimetry.transfer = GST_VIDEO_TRANSFER_BT709;
557 colorimetry.transfer = GST_VIDEO_TRANSFER_UNKNOWN;
560 colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA22;
563 colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA28;
566 colorimetry.transfer = GST_VIDEO_TRANSFER_SMPTE240M;
569 colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA10;
572 colorimetry.transfer = GST_VIDEO_TRANSFER_LOG100;
575 colorimetry.transfer = GST_VIDEO_TRANSFER_LOG316;
578 colorimetry.transfer = GST_VIDEO_TRANSFER_SRGB;
581 colorimetry.transfer = GST_VIDEO_TRANSFER_BT2020_12;
584 GST_FIXME_OBJECT (demux,
585 "Unsupported color transfer characteristics %"
586 G_GUINT64_FORMAT, num);
592 case GST_MATROSKA_ID_VIDEOPRIMARIES:{
593 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
598 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
601 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
604 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT470M;
607 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT470BG;
610 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE170M;
613 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE240M;
616 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_FILM;
619 colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
622 GST_FIXME_OBJECT (demux, "Unsupported color primaries %"
623 G_GUINT64_FORMAT, num);
630 GST_FIXME_OBJECT (demux, "Unsupported subelement 0x%x in Colour", id);
631 ret = gst_ebml_read_skip (ebml);
636 memcpy (&video_context->colorimetry, &colorimetry,
637 sizeof (GstVideoColorimetry));
640 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideoColour", ret);
645 gst_matroska_demux_parse_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml,
646 GstMatroskaTrackContext ** dest_context)
648 GstMatroskaTrackContext *context;
649 GstCaps *caps = NULL;
650 GstTagList *cached_taglist;
652 guint32 id, riff_fourcc = 0;
653 guint16 riff_audio_fmt = 0;
656 DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
658 /* start with the master */
659 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
660 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
664 /* allocate generic... if we know the type, we'll g_renew()
665 * with the precise type */
666 context = g_new0 (GstMatroskaTrackContext, 1);
667 context->index_writer_id = -1;
668 context->type = 0; /* no type yet */
669 context->default_duration = 0;
671 context->set_discont = TRUE;
672 context->timecodescale = 1.0;
674 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
675 GST_MATROSKA_TRACK_LACING;
676 context->from_time = GST_CLOCK_TIME_NONE;
677 context->from_offset = -1;
678 context->to_offset = G_MAXINT64;
679 context->alignment = 1;
680 context->dts_only = FALSE;
681 context->intra_only = FALSE;
682 context->tags = gst_tag_list_new_empty ();
683 g_queue_init (&context->protection_event_queue);
684 context->protection_info = NULL;
686 GST_DEBUG_OBJECT (demux, "Parsing a TrackEntry (%d tracks parsed so far)",
687 demux->common.num_streams);
689 /* try reading the trackentry headers */
690 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
691 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
695 /* track number (unique stream ID) */
696 case GST_MATROSKA_ID_TRACKNUMBER:{
699 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
703 GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
704 ret = GST_FLOW_ERROR;
708 GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
712 /* track UID (unique identifier) */
713 case GST_MATROSKA_ID_TRACKUID:{
716 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
720 GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
721 ret = GST_FLOW_ERROR;
725 GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
730 /* track type (video, audio, combined, subtitle, etc.) */
731 case GST_MATROSKA_ID_TRACKTYPE:{
734 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
738 if (context->type != 0 && context->type != track_type) {
739 GST_WARNING_OBJECT (demux,
740 "More than one tracktype defined in a TrackEntry - skipping");
742 } else if (track_type < 1 || track_type > 254) {
743 GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
748 GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
750 /* ok, so we're actually going to reallocate this thing */
751 switch (track_type) {
752 case GST_MATROSKA_TRACK_TYPE_VIDEO:
753 gst_matroska_track_init_video_context (&context);
755 case GST_MATROSKA_TRACK_TYPE_AUDIO:
756 gst_matroska_track_init_audio_context (&context);
758 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
759 gst_matroska_track_init_subtitle_context (&context);
761 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
762 case GST_MATROSKA_TRACK_TYPE_LOGO:
763 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
764 case GST_MATROSKA_TRACK_TYPE_CONTROL:
766 GST_WARNING_OBJECT (demux,
767 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
775 /* tracktype specific stuff for video */
776 case GST_MATROSKA_ID_TRACKVIDEO:{
777 GstMatroskaTrackVideoContext *videocontext;
779 DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
781 if (!gst_matroska_track_init_video_context (&context)) {
782 GST_WARNING_OBJECT (demux,
783 "TrackVideo element in non-video track - ignoring track");
784 ret = GST_FLOW_ERROR;
786 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
789 videocontext = (GstMatroskaTrackVideoContext *) context;
791 while (ret == GST_FLOW_OK &&
792 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
793 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
797 /* Should be one level up but some broken muxers write it here. */
798 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
801 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
805 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
809 GST_DEBUG_OBJECT (demux,
810 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
811 context->default_duration = num;
815 /* video framerate */
816 /* NOTE: This one is here only for backward compatibility.
817 * Use _TRACKDEFAULDURATION one level up. */
818 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
821 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
825 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
829 GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
830 if (context->default_duration == 0)
831 context->default_duration =
832 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
833 videocontext->default_fps = num;
837 /* width of the size to display the video at */
838 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
841 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
845 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
849 GST_DEBUG_OBJECT (demux,
850 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
851 videocontext->display_width = num;
855 /* height of the size to display the video at */
856 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
859 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
863 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
867 GST_DEBUG_OBJECT (demux,
868 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
869 videocontext->display_height = num;
873 /* width of the video in the file */
874 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
877 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
881 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
885 GST_DEBUG_OBJECT (demux,
886 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
887 videocontext->pixel_width = num;
891 /* height of the video in the file */
892 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
895 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
899 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
903 GST_DEBUG_OBJECT (demux,
904 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
905 videocontext->pixel_height = num;
909 /* whether the video is interlaced */
910 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
913 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
917 videocontext->interlace_mode =
918 GST_MATROSKA_INTERLACE_MODE_INTERLACED;
920 videocontext->interlace_mode =
921 GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
923 videocontext->interlace_mode =
924 GST_MATROSKA_INTERLACE_MODE_UNKNOWN;
926 GST_DEBUG_OBJECT (demux, "video track interlacing mode: %d",
927 videocontext->interlace_mode);
931 /* aspect ratio behaviour */
932 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
935 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
938 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
939 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
940 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
941 GST_WARNING_OBJECT (demux,
942 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
945 GST_DEBUG_OBJECT (demux,
946 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
947 videocontext->asr_mode = num;
951 /* colourspace (only matters for raw video) fourcc */
952 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
957 gst_ebml_read_binary (ebml, &id, &data,
958 &datalen)) != GST_FLOW_OK)
963 GST_WARNING_OBJECT (demux,
964 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
969 memcpy (&videocontext->fourcc, data, 4);
970 GST_DEBUG_OBJECT (demux,
971 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
972 GST_FOURCC_ARGS (videocontext->fourcc));
978 case GST_MATROSKA_ID_VIDEOCOLOUR:{
979 ret = gst_matroska_demux_parse_colour (demux, ebml, videocontext);
983 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
987 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
990 GST_DEBUG_OBJECT (demux, "StereoMode: %" G_GUINT64_FORMAT, num);
993 case GST_MATROSKA_STEREO_MODE_SBS_RL:
994 videocontext->multiview_flags =
995 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
997 case GST_MATROSKA_STEREO_MODE_SBS_LR:
998 videocontext->multiview_mode =
999 GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
1001 case GST_MATROSKA_STEREO_MODE_TB_RL:
1002 videocontext->multiview_flags =
1003 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1005 case GST_MATROSKA_STEREO_MODE_TB_LR:
1006 videocontext->multiview_mode =
1007 GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM;
1009 case GST_MATROSKA_STEREO_MODE_CHECKER_RL:
1010 videocontext->multiview_flags =
1011 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1013 case GST_MATROSKA_STEREO_MODE_CHECKER_LR:
1014 videocontext->multiview_mode =
1015 GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD;
1017 case GST_MATROSKA_STEREO_MODE_FBF_RL:
1018 videocontext->multiview_flags =
1019 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1021 case GST_MATROSKA_STEREO_MODE_FBF_LR:
1022 videocontext->multiview_mode =
1023 GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
1024 /* FIXME: In frame-by-frame mode, left/right frame buffers are
1025 * laced within one block, and we'll need to apply FIRST_IN_BUNDLE
1026 * accordingly. See http://www.matroska.org/technical/specs/index.html#StereoMode */
1027 GST_FIXME_OBJECT (demux,
1028 "Frame-by-frame stereoscopic mode not fully implemented");
1035 GST_WARNING_OBJECT (demux,
1036 "Unknown TrackVideo subelement 0x%x - ignoring", id);
1038 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
1039 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
1040 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
1041 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
1042 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
1043 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
1044 ret = gst_ebml_read_skip (ebml);
1049 DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
1053 /* tracktype specific stuff for audio */
1054 case GST_MATROSKA_ID_TRACKAUDIO:{
1055 GstMatroskaTrackAudioContext *audiocontext;
1057 DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
1059 if (!gst_matroska_track_init_audio_context (&context)) {
1060 GST_WARNING_OBJECT (demux,
1061 "TrackAudio element in non-audio track - ignoring track");
1062 ret = GST_FLOW_ERROR;
1066 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
1069 audiocontext = (GstMatroskaTrackAudioContext *) context;
1071 while (ret == GST_FLOW_OK &&
1072 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1073 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1078 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
1081 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1086 GST_WARNING_OBJECT (demux,
1087 "Invalid TrackAudioSamplingFrequency %lf", num);
1091 GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
1092 audiocontext->samplerate = num;
1097 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
1100 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1104 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
1108 GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
1110 audiocontext->bitdepth = num;
1115 case GST_MATROSKA_ID_AUDIOCHANNELS:{
1118 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1122 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
1126 GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
1128 audiocontext->channels = num;
1133 GST_WARNING_OBJECT (demux,
1134 "Unknown TrackAudio subelement 0x%x - ignoring", id);
1136 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
1137 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
1138 ret = gst_ebml_read_skip (ebml);
1143 DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
1148 /* codec identifier */
1149 case GST_MATROSKA_ID_CODECID:{
1152 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
1155 GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
1156 context->codec_id = text;
1160 /* codec private data */
1161 case GST_MATROSKA_ID_CODECPRIVATE:{
1166 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
1169 context->codec_priv = data;
1170 context->codec_priv_size = size;
1172 GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1177 /* name of the codec */
1178 case GST_MATROSKA_ID_CODECNAME:{
1181 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1184 GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1185 context->codec_name = text;
1190 case GST_MATROSKA_ID_CODECDELAY:{
1193 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1196 context->codec_delay = num;
1198 GST_DEBUG_OBJECT (demux, "CodecDelay: %" GST_TIME_FORMAT,
1199 GST_TIME_ARGS (num));
1204 case GST_MATROSKA_ID_SEEKPREROLL:{
1207 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1210 context->seek_preroll = num;
1212 GST_DEBUG_OBJECT (demux, "SeekPreroll: %" GST_TIME_FORMAT,
1213 GST_TIME_ARGS (num));
1217 /* name of this track */
1218 case GST_MATROSKA_ID_TRACKNAME:{
1221 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1224 context->name = text;
1225 GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1229 /* language (matters for audio/subtitles, mostly) */
1230 case GST_MATROSKA_ID_TRACKLANGUAGE:{
1233 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1237 context->language = text;
1240 if (strlen (context->language) >= 4 && context->language[3] == '-')
1241 context->language[3] = '\0';
1243 GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1244 GST_STR_NULL (context->language));
1248 /* whether this is actually used */
1249 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1252 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1256 context->flags |= GST_MATROSKA_TRACK_ENABLED;
1258 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1260 GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1261 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1265 /* whether it's the default for this track type */
1266 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1269 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1273 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1275 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1277 GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1278 (context->flags & GST_MATROSKA_TRACK_DEFAULT) ? 1 : 0);
1282 /* whether the track must be used during playback */
1283 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1286 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1290 context->flags |= GST_MATROSKA_TRACK_FORCED;
1292 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1294 GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1295 (context->flags & GST_MATROSKA_TRACK_FORCED) ? 1 : 0);
1299 /* lacing (like MPEG, where blocks don't end/start on frame
1301 case GST_MATROSKA_ID_TRACKFLAGLACING:{
1304 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1308 context->flags |= GST_MATROSKA_TRACK_LACING;
1310 context->flags &= ~GST_MATROSKA_TRACK_LACING;
1312 GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1313 (context->flags & GST_MATROSKA_TRACK_LACING) ? 1 : 0);
1317 /* default length (in time) of one data block in this track */
1318 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1321 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1326 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1330 GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1332 context->default_duration = num;
1336 case GST_MATROSKA_ID_CONTENTENCODINGS:{
1337 ret = gst_matroska_read_common_read_track_encodings (&demux->common,
1342 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1345 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1349 GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1353 GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1354 context->timecodescale = num;
1359 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1362 /* we ignore these because they're nothing useful (i.e. crap)
1363 * or simply not implemented yet. */
1364 case GST_MATROSKA_ID_TRACKMINCACHE:
1365 case GST_MATROSKA_ID_TRACKMAXCACHE:
1366 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1367 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1368 case GST_MATROSKA_ID_TRACKOVERLAY:
1369 case GST_MATROSKA_ID_TRACKTRANSLATE:
1370 case GST_MATROSKA_ID_TRACKOFFSET:
1371 case GST_MATROSKA_ID_CODECSETTINGS:
1372 case GST_MATROSKA_ID_CODECINFOURL:
1373 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1374 case GST_MATROSKA_ID_CODECDECODEALL:
1375 ret = gst_ebml_read_skip (ebml);
1380 DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1382 /* Decode codec private data if necessary */
1383 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1384 && context->codec_priv_size > 0) {
1385 if (!gst_matroska_decode_data (context->encodings,
1386 &context->codec_priv, &context->codec_priv_size,
1387 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1388 GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1389 ret = GST_FLOW_ERROR;
1393 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1394 && ret != GST_FLOW_EOS)) {
1395 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1396 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1398 gst_matroska_track_free (context);
1400 *dest_context = NULL;
1404 /* check for a cached track taglist */
1406 (GstTagList *) g_hash_table_lookup (demux->common.cached_track_taglists,
1407 GUINT_TO_POINTER (context->uid));
1409 gst_tag_list_insert (context->tags, cached_taglist, GST_TAG_MERGE_APPEND);
1412 switch (context->type) {
1413 case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1414 GstMatroskaTrackVideoContext *videocontext =
1415 (GstMatroskaTrackVideoContext *) context;
1417 caps = gst_matroska_demux_video_caps (videocontext,
1418 context->codec_id, context->codec_priv,
1419 context->codec_priv_size, &codec, &riff_fourcc);
1422 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1423 GST_TAG_VIDEO_CODEC, codec, NULL);
1424 context->tags_changed = TRUE;
1430 case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1431 GstMatroskaTrackAudioContext *audiocontext =
1432 (GstMatroskaTrackAudioContext *) context;
1434 caps = gst_matroska_demux_audio_caps (audiocontext,
1435 context->codec_id, context->codec_priv, context->codec_priv_size,
1436 &codec, &riff_audio_fmt);
1439 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1440 GST_TAG_AUDIO_CODEC, codec, NULL);
1441 context->tags_changed = TRUE;
1447 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1448 GstMatroskaTrackSubtitleContext *subtitlecontext =
1449 (GstMatroskaTrackSubtitleContext *) context;
1451 caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1452 context->codec_id, context->codec_priv, context->codec_priv_size);
1456 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1457 case GST_MATROSKA_TRACK_TYPE_LOGO:
1458 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1459 case GST_MATROSKA_TRACK_TYPE_CONTROL:
1461 /* we should already have quit by now */
1462 g_assert_not_reached ();
1465 if ((context->language == NULL || *context->language == '\0') &&
1466 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1467 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1468 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1469 context->language = g_strdup ("eng");
1472 if (context->language) {
1475 /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1476 lang = gst_tag_get_language_code (context->language);
1477 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1478 GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1480 if (context->name) {
1481 gst_tag_list_add (context->tags, GST_TAG_MERGE_REPLACE,
1482 GST_TAG_TITLE, context->name, NULL);
1484 context->tags_changed = TRUE;
1488 GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1489 "codec_id='%s'", context->codec_id);
1490 switch (context->type) {
1491 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1492 caps = gst_caps_new_empty_simple ("video/x-unknown");
1494 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1495 caps = gst_caps_new_empty_simple ("audio/x-unknown");
1497 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1498 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
1500 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1502 caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
1505 gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1508 /* add any unrecognised riff fourcc / audio format, but after codec-id */
1509 if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1510 gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1511 else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
1512 gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1513 GST_FOURCC_ARGS (riff_fourcc));
1514 gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
1517 } else if (context->stream_headers != NULL) {
1518 gst_matroska_demux_add_stream_headers_to_caps (demux,
1519 context->stream_headers, caps);
1522 if (context->encodings) {
1523 GstMatroskaTrackEncoding *enc;
1526 for (i = 0; i < context->encodings->len; i++) {
1527 enc = &g_array_index (context->encodings, GstMatroskaTrackEncoding, i);
1528 if (enc->type == GST_MATROSKA_ENCODING_ENCRYPTION /* encryption */ ) {
1529 GstStructure *s = gst_caps_get_structure (caps, 0);
1530 if (!gst_structure_has_name (s, "application/x-webm-enc")) {
1531 gst_structure_set (s, "original-media-type", G_TYPE_STRING,
1532 gst_structure_get_name (s), NULL);
1533 gst_structure_set (s, "encryption-algorithm", G_TYPE_STRING,
1534 gst_matroska_track_encryption_algorithm_name (enc->enc_algo),
1536 gst_structure_set (s, "encoding-scope", G_TYPE_STRING,
1537 gst_matroska_track_encoding_scope_name (enc->scope), NULL);
1538 gst_structure_set (s, "cipher-mode", G_TYPE_STRING,
1539 gst_matroska_track_encryption_cipher_mode_name
1540 (enc->enc_cipher_mode), NULL);
1541 gst_structure_set_name (s, "application/x-webm-enc");
1547 context->caps = caps;
1550 *dest_context = context;
1555 gst_matroska_demux_add_stream (GstMatroskaDemux * demux,
1556 GstMatroskaTrackContext * context)
1558 GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
1559 gchar *padname = NULL;
1560 GstPadTemplate *templ = NULL;
1561 GstStreamFlags stream_flags;
1563 GstEvent *stream_start;
1567 g_ptr_array_add (demux->common.src, context);
1568 context->index = demux->common.num_streams++;
1569 g_assert (demux->common.src->len == demux->common.num_streams);
1570 g_ptr_array_index (demux->common.src, demux->common.num_streams - 1) =
1573 /* now create the GStreamer connectivity */
1574 switch (context->type) {
1575 case GST_MATROSKA_TRACK_TYPE_VIDEO:
1576 padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
1577 templ = gst_element_class_get_pad_template (klass, "video_%u");
1579 if (!context->intra_only)
1580 demux->have_nonintraonly_v_streams = TRUE;
1583 case GST_MATROSKA_TRACK_TYPE_AUDIO:
1584 padname = g_strdup_printf ("audio_%u", demux->num_a_streams++);
1585 templ = gst_element_class_get_pad_template (klass, "audio_%u");
1588 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1589 padname = g_strdup_printf ("subtitle_%u", demux->num_t_streams++);
1590 templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
1594 /* we should already have quit by now */
1595 g_assert_not_reached ();
1598 /* the pad in here */
1599 context->pad = gst_pad_new_from_template (templ, padname);
1601 gst_pad_set_event_function (context->pad,
1602 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1603 gst_pad_set_query_function (context->pad,
1604 GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
1606 GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
1607 padname, context->caps);
1609 gst_pad_set_element_private (context->pad, context);
1611 gst_pad_use_fixed_caps (context->pad);
1612 gst_pad_set_active (context->pad, TRUE);
1615 gst_pad_create_stream_id_printf (context->pad, GST_ELEMENT_CAST (demux),
1616 "%03" G_GUINT64_FORMAT ":%03" G_GUINT64_FORMAT,
1617 context->num, context->uid);
1619 gst_pad_get_sticky_event (demux->common.sinkpad, GST_EVENT_STREAM_START,
1622 if (gst_event_parse_group_id (stream_start, &demux->group_id))
1623 demux->have_group_id = TRUE;
1625 demux->have_group_id = FALSE;
1626 gst_event_unref (stream_start);
1627 } else if (!demux->have_group_id) {
1628 demux->have_group_id = TRUE;
1629 demux->group_id = gst_util_group_id_next ();
1632 stream_start = gst_event_new_stream_start (stream_id);
1634 if (demux->have_group_id)
1635 gst_event_set_group_id (stream_start, demux->group_id);
1636 stream_flags = GST_STREAM_FLAG_NONE;
1637 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
1638 stream_flags |= GST_STREAM_FLAG_SPARSE;
1639 if (context->flags & GST_MATROSKA_TRACK_DEFAULT)
1640 stream_flags |= GST_STREAM_FLAG_SELECT;
1641 else if (!(context->flags & GST_MATROSKA_TRACK_ENABLED))
1642 stream_flags |= GST_STREAM_FLAG_UNSELECT;
1644 gst_event_set_stream_flags (stream_start, stream_flags);
1645 gst_pad_push_event (context->pad, stream_start);
1646 gst_pad_set_caps (context->pad, context->caps);
1649 if (demux->common.global_tags) {
1650 GstEvent *tag_event;
1652 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1653 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1654 GST_DEBUG_OBJECT (context->pad, "Sending global_tags %p: %" GST_PTR_FORMAT,
1655 demux->common.global_tags, demux->common.global_tags);
1658 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1660 gst_pad_push_event (context->pad, tag_event);
1663 if (G_UNLIKELY (context->tags_changed)) {
1664 GST_DEBUG_OBJECT (context->pad, "Sending tags %p: %"
1665 GST_PTR_FORMAT, context->tags, context->tags);
1666 gst_pad_push_event (context->pad,
1667 gst_event_new_tag (gst_tag_list_copy (context->tags)));
1668 context->tags_changed = FALSE;
1671 gst_element_add_pad (GST_ELEMENT (demux), context->pad);
1672 gst_flow_combiner_add_pad (demux->flowcombiner, context->pad);
1678 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
1681 gboolean res = FALSE;
1682 GstMatroskaTrackContext *context = NULL;
1685 context = gst_pad_get_element_private (pad);
1688 switch (GST_QUERY_TYPE (query)) {
1689 case GST_QUERY_POSITION:
1693 gst_query_parse_position (query, &format, NULL);
1696 if (format == GST_FORMAT_TIME) {
1697 GST_OBJECT_LOCK (demux);
1699 gst_query_set_position (query, GST_FORMAT_TIME,
1700 MAX (context->pos, demux->stream_start_time) -
1701 demux->stream_start_time);
1703 gst_query_set_position (query, GST_FORMAT_TIME,
1704 MAX (demux->common.segment.position, demux->stream_start_time) -
1705 demux->stream_start_time);
1706 GST_OBJECT_UNLOCK (demux);
1707 } else if (format == GST_FORMAT_DEFAULT && context
1708 && context->default_duration) {
1709 GST_OBJECT_LOCK (demux);
1710 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1711 context->pos / context->default_duration);
1712 GST_OBJECT_UNLOCK (demux);
1714 GST_DEBUG_OBJECT (demux,
1715 "only position query in TIME and DEFAULT format is supported");
1721 case GST_QUERY_DURATION:
1725 gst_query_parse_duration (query, &format, NULL);
1728 if (format == GST_FORMAT_TIME) {
1729 GST_OBJECT_LOCK (demux);
1730 gst_query_set_duration (query, GST_FORMAT_TIME,
1731 demux->common.segment.duration);
1732 GST_OBJECT_UNLOCK (demux);
1733 } else if (format == GST_FORMAT_DEFAULT && context
1734 && context->default_duration) {
1735 GST_OBJECT_LOCK (demux);
1736 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1737 demux->common.segment.duration / context->default_duration);
1738 GST_OBJECT_UNLOCK (demux);
1740 GST_DEBUG_OBJECT (demux,
1741 "only duration query in TIME and DEFAULT format is supported");
1747 case GST_QUERY_SEEKING:
1751 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1752 GST_OBJECT_LOCK (demux);
1753 if (fmt == GST_FORMAT_TIME) {
1756 if (demux->streaming) {
1757 /* assuming we'll be able to get an index ... */
1758 seekable = demux->seekable;
1763 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1764 0, demux->common.segment.duration);
1767 GST_OBJECT_UNLOCK (demux);
1770 case GST_QUERY_SEGMENT:
1775 format = demux->common.segment.format;
1778 gst_segment_to_stream_time (&demux->common.segment, format,
1779 demux->common.segment.start);
1780 if ((stop = demux->common.segment.stop) == -1)
1781 stop = demux->common.segment.duration;
1784 gst_segment_to_stream_time (&demux->common.segment, format, stop);
1786 gst_query_set_segment (query, demux->common.segment.rate, format, start,
1793 res = gst_pad_query_default (pad, (GstObject *) demux, query);
1796 GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (demux),
1805 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
1807 return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
1811 gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
1814 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
1816 return gst_matroska_demux_query (demux, pad, query);
1819 /* returns FALSE if there are no pads to deliver event to,
1820 * otherwise TRUE (whatever the outcome of event sending),
1821 * takes ownership of the passed event! */
1823 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
1825 gboolean ret = FALSE;
1828 g_return_val_if_fail (event != NULL, FALSE);
1830 GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
1831 GST_EVENT_TYPE_NAME (event));
1833 g_assert (demux->common.src->len == demux->common.num_streams);
1834 for (i = 0; i < demux->common.src->len; i++) {
1835 GstMatroskaTrackContext *stream;
1837 stream = g_ptr_array_index (demux->common.src, i);
1838 gst_event_ref (event);
1839 gst_pad_push_event (stream->pad, event);
1843 gst_event_unref (event);
1848 gst_matroska_demux_send_tags (GstMatroskaDemux * demux)
1852 if (G_UNLIKELY (demux->common.global_tags_changed)) {
1853 GstEvent *tag_event;
1854 gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
1855 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1856 GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
1857 demux->common.global_tags, demux->common.global_tags);
1860 gst_event_new_tag (gst_tag_list_copy (demux->common.global_tags));
1862 for (i = 0; i < demux->common.src->len; i++) {
1863 GstMatroskaTrackContext *stream;
1865 stream = g_ptr_array_index (demux->common.src, i);
1866 gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
1869 gst_event_unref (tag_event);
1870 demux->common.global_tags_changed = FALSE;
1873 g_assert (demux->common.src->len == demux->common.num_streams);
1874 for (i = 0; i < demux->common.src->len; i++) {
1875 GstMatroskaTrackContext *stream;
1877 stream = g_ptr_array_index (demux->common.src, i);
1879 if (G_UNLIKELY (stream->tags_changed)) {
1880 GST_DEBUG_OBJECT (demux, "Sending tags %p for pad %s:%s : %"
1881 GST_PTR_FORMAT, stream->tags,
1882 GST_DEBUG_PAD_NAME (stream->pad), stream->tags);
1883 gst_pad_push_event (stream->pad,
1884 gst_event_new_tag (gst_tag_list_copy (stream->tags)));
1885 stream->tags_changed = FALSE;
1891 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
1893 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1896 g_return_val_if_fail (event != NULL, FALSE);
1898 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1899 /* no seeking until we are (safely) ready */
1900 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
1901 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
1902 gst_event_unref (event);
1905 res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
1907 GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
1908 GST_EVENT_TYPE_NAME (event));
1911 gst_event_unref (event);
1916 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
1917 GstMatroskaIndex * entry, gboolean reset, gboolean update)
1921 GST_OBJECT_LOCK (demux);
1924 /* seek (relative to matroska segment) */
1925 /* position might be invalid; will error when streaming resumes ... */
1926 demux->common.offset = entry->pos + demux->common.ebml_segment_start;
1927 demux->next_cluster_offset = 0;
1929 GST_DEBUG_OBJECT (demux,
1930 "Seeked to offset %" G_GUINT64_FORMAT ", block %d, " "time %"
1931 GST_TIME_FORMAT, entry->pos + demux->common.ebml_segment_start,
1932 entry->block, GST_TIME_ARGS (entry->time));
1934 /* update the time */
1935 gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
1936 gst_flow_combiner_reset (demux->flowcombiner);
1937 demux->common.segment.position = entry->time;
1938 demux->seek_block = entry->block;
1939 demux->seek_first = TRUE;
1940 demux->last_stop_end = GST_CLOCK_TIME_NONE;
1943 for (i = 0; i < demux->common.src->len; i++) {
1944 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
1947 stream->to_offset = G_MAXINT64;
1949 if (stream->from_offset != -1)
1950 stream->to_offset = stream->from_offset;
1952 stream->from_offset = -1;
1953 stream->from_time = GST_CLOCK_TIME_NONE;
1956 GST_OBJECT_UNLOCK (demux);
1962 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
1972 /* searches for a cluster start from @pos,
1973 * return GST_FLOW_OK and cluster position in @pos if found */
1974 static GstFlowReturn
1975 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos,
1978 gint64 newpos = *pos;
1980 GstFlowReturn ret = GST_FLOW_OK;
1981 const guint chunk = 128 * 1024;
1982 GstBuffer *buf = NULL;
1984 gpointer data = NULL;
1989 gint64 oldpos, oldlength;
1991 orig_offset = demux->common.offset;
1993 GST_LOG_OBJECT (demux, "searching cluster %s offset %" G_GINT64_FORMAT,
1994 forward ? "following" : "preceding", *pos);
1996 if (demux->clusters) {
1999 cpos = gst_util_array_binary_search (demux->clusters->data,
2000 demux->clusters->len, sizeof (gint64),
2001 (GCompareDataFunc) gst_matroska_cluster_compare,
2002 forward ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE, pos, NULL);
2005 GST_DEBUG_OBJECT (demux,
2006 "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
2007 demux->common.offset = *cpos;
2008 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2009 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2010 if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
2017 /* read in at newpos and scan for ebml cluster id */
2018 oldpos = oldlength = -1;
2020 GstByteReader reader;
2022 guint toread = chunk;
2025 /* never read beyond the requested target */
2026 if (G_UNLIKELY (newpos < chunk)) {
2034 gst_buffer_unmap (buf, &map);
2035 gst_buffer_unref (buf);
2038 ret = gst_pad_pull_range (demux->common.sinkpad, newpos, toread, &buf);
2039 if (ret != GST_FLOW_OK)
2041 GST_DEBUG_OBJECT (demux,
2042 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
2043 gst_buffer_get_size (buf), newpos);
2044 gst_buffer_map (buf, &map, GST_MAP_READ);
2047 if (oldpos == newpos && oldlength == map.size) {
2048 GST_ERROR_OBJECT (demux, "Stuck at same position");
2049 ret = GST_FLOW_ERROR;
2053 oldlength = map.size;
2056 gst_byte_reader_init (&reader, data, size);
2059 gint found = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
2060 GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
2062 cluster_pos = found;
2065 /* need last occurrence when searching backwards */
2067 cluster_pos = gst_byte_reader_get_pos (&reader) + found;
2068 gst_byte_reader_skip (&reader, found + 4);
2074 if (cluster_pos >= 0) {
2075 newpos += cluster_pos;
2076 GST_DEBUG_OBJECT (demux,
2077 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
2078 /* extra checks whether we really sync'ed to a cluster:
2079 * - either it is the first and only cluster
2080 * - either there is a cluster after this one
2081 * - either cluster length is undefined
2083 /* ok if first cluster (there may not a subsequent one) */
2084 if (newpos == demux->first_cluster_offset) {
2085 GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
2088 demux->common.offset = newpos;
2089 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2090 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2091 if (ret != GST_FLOW_OK) {
2092 GST_DEBUG_OBJECT (demux, "need more data -> continue");
2095 g_assert (id == GST_MATROSKA_ID_CLUSTER);
2096 GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
2098 /* ok if undefined length or first cluster */
2099 if (length == GST_EBML_SIZE_UNKNOWN || length == G_MAXUINT64) {
2100 GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
2104 demux->common.offset += length + needed;
2105 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2106 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2107 if (ret != GST_FLOW_OK)
2109 GST_DEBUG_OBJECT (demux, "next element is %scluster",
2110 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
2111 if (id == GST_MATROSKA_ID_CLUSTER)
2117 /* partial cluster id may have been in tail of buffer */
2119 forward ? MAX (gst_byte_reader_get_remaining (&reader), 4) - 3 : 3;
2124 gst_buffer_unmap (buf, &map);
2125 gst_buffer_unref (buf);
2130 demux->common.offset = orig_offset;
2135 /* Three states to express: starts with I-frame, starts with delta, don't know */
2138 CLUSTER_STATUS_NONE = 0,
2139 CLUSTER_STATUS_STARTS_WITH_KEYFRAME,
2140 CLUSTER_STATUS_STARTS_WITH_DELTAUNIT,
2149 ClusterStatus status;
2152 static const gchar *
2153 cluster_status_get_nick (ClusterStatus status)
2156 case CLUSTER_STATUS_NONE:
2158 case CLUSTER_STATUS_STARTS_WITH_KEYFRAME:
2160 case CLUSTER_STATUS_STARTS_WITH_DELTAUNIT:
2166 /* Skip ebml-coded number:
2169 * 001x.. = 3 bytes, etc.
2172 bit_reader_skip_ebml_num (GstBitReader * br)
2176 if (!gst_bit_reader_peek_bits_uint8 (br, &v, 8))
2179 for (i = 0; i < 8; i++) {
2180 if ((v & (0x80 >> i)) != 0)
2183 return gst_bit_reader_skip (br, (i + 1) * 8);
2186 /* Don't probe more than that many bytes into the cluster for keyframe info
2187 * (random value, mostly for sanity checking) */
2188 #define MAX_CLUSTER_INFO_PROBE_LENGTH 256
2191 gst_matroska_demux_peek_cluster_info (GstMatroskaDemux * demux,
2192 ClusterInfo * cluster, guint64 offset)
2194 demux->common.offset = offset;
2195 demux->cluster_time = GST_CLOCK_TIME_NONE;
2197 cluster->offset = offset;
2199 cluster->prev_size = 0;
2200 cluster->time = GST_CLOCK_TIME_NONE;
2201 cluster->status = CLUSTER_STATUS_NONE;
2203 /* parse first few elements in cluster */
2210 flow = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2211 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2213 if (flow != GST_FLOW_OK)
2216 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2217 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
2220 /* Reached start of next cluster without finding data, stop processing */
2221 if (id == GST_MATROSKA_ID_CLUSTER && cluster->offset != offset)
2224 /* Not going to parse into these for now, stop processing */
2225 if (id == GST_MATROSKA_ID_ENCRYPTEDBLOCK
2226 || id == GST_MATROSKA_ID_BLOCKGROUP || id == GST_MATROSKA_ID_BLOCK)
2229 /* SimpleBlock: peek at headers to check if it's a keyframe */
2230 if (id == GST_MATROSKA_ID_SIMPLEBLOCK) {
2232 guint8 *d, hdr_len, v = 0;
2234 GST_DEBUG_OBJECT (demux, "SimpleBlock found");
2236 /* SimpleBlock header is max. 21 bytes */
2237 hdr_len = MIN (21, length);
2239 flow = gst_matroska_read_common_peek_bytes (&demux->common,
2240 demux->common.offset, hdr_len, NULL, &d);
2242 if (flow != GST_FLOW_OK)
2245 gst_bit_reader_init (&br, d, hdr_len);
2247 /* skip prefix: ebml id (SimpleBlock) + element length */
2248 if (!gst_bit_reader_skip (&br, 8 * needed))
2251 /* skip track number (ebml coded) */
2252 if (!bit_reader_skip_ebml_num (&br))
2256 if (!gst_bit_reader_skip (&br, 16))
2260 if (!gst_bit_reader_get_bits_uint8 (&br, &v, 8))
2263 if ((v & 0x80) != 0)
2264 cluster->status = CLUSTER_STATUS_STARTS_WITH_KEYFRAME;
2266 cluster->status = CLUSTER_STATUS_STARTS_WITH_DELTAUNIT;
2271 flow = gst_matroska_demux_parse_id (demux, id, length, needed);
2273 if (flow != GST_FLOW_OK)
2277 case GST_MATROSKA_ID_CLUSTER:
2278 if (length == G_MAXUINT64)
2281 cluster->size = length + needed;
2283 case GST_MATROSKA_ID_PREVSIZE:
2284 cluster->prev_size = demux->cluster_prevsize;
2286 case GST_MATROSKA_ID_CLUSTERTIMECODE:
2287 cluster->time = demux->cluster_time * demux->common.time_scale;
2289 case GST_MATROSKA_ID_SILENTTRACKS:
2290 /* ignore and continue */
2293 GST_WARNING_OBJECT (demux, "Unknown ebml id 0x%08x (possibly garbage), "
2297 } while (demux->common.offset - offset < MAX_CLUSTER_INFO_PROBE_LENGTH);
2301 GST_INFO_OBJECT (demux, "Cluster @ %" G_GUINT64_FORMAT ": "
2302 "time %" GST_TIME_FORMAT ", size %" G_GUINT64_FORMAT ", "
2303 "prev_size %" G_GUINT64_FORMAT ", %s", cluster->offset,
2304 GST_TIME_ARGS (cluster->time), cluster->size, cluster->prev_size,
2305 cluster_status_get_nick (cluster->status));
2307 /* return success as long as we could extract the minimum useful information */
2308 return cluster->time != GST_CLOCK_TIME_NONE;
2311 /* returns TRUE if the cluster offset was updated */
2313 gst_matroska_demux_scan_back_for_keyframe_cluster (GstMatroskaDemux * demux,
2314 gint64 * cluster_offset, GstClockTime * cluster_time)
2316 GstClockTime stream_start_time = demux->stream_start_time;
2317 guint64 first_cluster_offset = demux->first_cluster_offset;
2318 gint64 off = *cluster_offset;
2319 ClusterInfo cluster = { 0, };
2321 GST_INFO_OBJECT (demux, "Checking if cluster starts with keyframe");
2322 while (off > first_cluster_offset) {
2323 if (!gst_matroska_demux_peek_cluster_info (demux, &cluster, off)) {
2324 GST_LOG_OBJECT (demux,
2325 "Couldn't get info on cluster @ %" G_GUINT64_FORMAT, off);
2329 /* Keyframe? Then we're done */
2330 if (cluster.status == CLUSTER_STATUS_STARTS_WITH_KEYFRAME) {
2331 GST_LOG_OBJECT (demux,
2332 "Found keyframe at start of cluster @ %" G_GUINT64_FORMAT, off);
2336 /* We only scan back if we *know* we landed on a cluster that
2337 * starts with a delta frame. */
2338 if (cluster.status != CLUSTER_STATUS_STARTS_WITH_DELTAUNIT) {
2339 GST_LOG_OBJECT (demux,
2340 "No delta frame at start of cluster @ %" G_GUINT64_FORMAT, off);
2344 GST_DEBUG_OBJECT (demux, "Cluster starts with delta frame, backtracking");
2346 /* Don't scan back more than this much in time from the cluster we
2347 * originally landed on. This is mostly a sanity check in case a file
2348 * always has keyframes in the middle of clusters and never at the
2349 * beginning. Without this we would always scan back to the beginning
2350 * of the file in that case. */
2351 if (cluster.time != GST_CLOCK_TIME_NONE) {
2352 GstClockTimeDiff distance = GST_CLOCK_DIFF (cluster.time, *cluster_time);
2354 if (distance < 0 || distance > demux->max_backtrack_distance * GST_SECOND) {
2355 GST_DEBUG_OBJECT (demux, "Haven't found cluster with keyframe within "
2356 "%u secs of original seek target cluster, stopping",
2357 demux->max_backtrack_distance);
2362 /* If we have cluster prev_size we can skip back efficiently. If not,
2363 * we'll just do a brute force search for a cluster identifier */
2364 if (cluster.prev_size > 0 && off >= cluster.prev_size) {
2365 off -= cluster.prev_size;
2369 GST_LOG_OBJECT (demux, "Cluster has no or invalid prev size, searching "
2370 "for previous cluster instead then");
2372 flow = gst_matroska_demux_search_cluster (demux, &off, FALSE);
2373 if (flow != GST_FLOW_OK) {
2374 GST_DEBUG_OBJECT (demux, "cluster search yielded flow %s, stopping",
2375 gst_flow_get_name (flow));
2380 if (off <= first_cluster_offset) {
2381 GST_LOG_OBJECT (demux, "Reached first cluster, stopping");
2382 *cluster_offset = first_cluster_offset;
2383 *cluster_time = stream_start_time;
2386 GST_LOG_OBJECT (demux, "Trying prev cluster @ %" G_GUINT64_FORMAT, off);
2389 /* If we found a cluster starting with a keyframe jump to that instead,
2390 * otherwise leave everything as it was before */
2391 if (cluster.time != GST_CLOCK_TIME_NONE
2392 && (cluster.offset == first_cluster_offset
2393 || cluster.status == CLUSTER_STATUS_STARTS_WITH_KEYFRAME)) {
2394 *cluster_offset = cluster.offset;
2395 *cluster_time = cluster.time;
2402 /* bisect and scan through file for cluster starting before @time,
2403 * returns fake index entry with corresponding info on cluster */
2404 static GstMatroskaIndex *
2405 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
2407 GstMatroskaIndex *entry = NULL;
2408 GstMatroskaReadState current_state;
2409 GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
2411 gint64 opos, newpos, current_offset;
2412 gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
2413 gint64 apos, maxpos;
2414 guint64 cluster_size = 0;
2420 /* estimate new position, resync using cluster ebml id,
2421 * and bisect further or scan forward to appropriate cluster */
2423 /* save some current global state which will be touched by our scanning */
2424 current_state = demux->common.state;
2425 g_return_val_if_fail (current_state == GST_MATROSKA_READ_STATE_DATA, NULL);
2427 current_cluster_offset = demux->cluster_offset;
2428 current_cluster_time = demux->cluster_time;
2429 current_offset = demux->common.offset;
2431 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
2433 /* estimate using start and last known cluster */
2434 GST_OBJECT_LOCK (demux);
2435 apos = demux->first_cluster_offset;
2436 atime = demux->stream_start_time;
2437 opos = demux->last_cluster_offset;
2438 otime = demux->stream_last_time;
2439 GST_OBJECT_UNLOCK (demux);
2442 time = MAX (time, atime);
2443 otime = MAX (otime, atime);
2444 opos = MAX (opos, apos);
2446 maxpos = gst_matroska_read_common_get_length (&demux->common);
2451 * apos always refer to a cluster before target time;
2452 * opos may or may not be after target time, but if it is once so,
2453 * then also in next iteration
2457 GST_LOG_OBJECT (demux,
2458 "apos: %" G_GUINT64_FORMAT ", atime: %" GST_TIME_FORMAT ", %"
2459 GST_TIME_FORMAT " in stream time, "
2460 "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
2461 GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
2462 GST_TIME_FORMAT, apos, GST_TIME_ARGS (atime),
2463 GST_TIME_ARGS (atime - demux->stream_start_time), opos,
2464 GST_TIME_ARGS (otime), GST_TIME_ARGS (otime - demux->stream_start_time),
2465 GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
2467 g_assert (atime <= otime);
2468 g_assert (apos <= opos);
2469 if (time == GST_CLOCK_TIME_NONE) {
2470 GST_DEBUG_OBJECT (demux, "searching last cluster");
2473 GST_DEBUG_OBJECT (demux, "unknown file size; bailing out");
2476 } else if (otime <= atime) {
2480 gst_util_uint64_scale (opos - apos, time - atime, otime - atime);
2481 if (maxpos != -1 && newpos > maxpos)
2485 GST_DEBUG_OBJECT (demux,
2486 "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
2487 GST_TIME_ARGS (time), newpos);
2489 /* search backwards */
2490 if (newpos > apos) {
2491 ret = gst_matroska_demux_search_cluster (demux, &newpos, FALSE);
2492 if (ret != GST_FLOW_OK)
2496 /* then start scanning and parsing for cluster time,
2497 * re-estimate if possible, otherwise next cluster and so on */
2498 /* note that each re-estimate is entered with a change in apos or opos,
2499 * avoiding infinite loop */
2500 demux->common.offset = newpos;
2501 demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
2503 prev_cluster_time = GST_CLOCK_TIME_NONE;
2505 /* peek and parse some elements */
2506 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
2507 GST_ELEMENT_CAST (demux), &id, &length, &needed);
2508 if (ret != GST_FLOW_OK)
2510 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2511 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
2513 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
2514 if (ret != GST_FLOW_OK)
2517 if (id == GST_MATROSKA_ID_CLUSTER) {
2518 cluster_time = GST_CLOCK_TIME_NONE;
2519 if (length == G_MAXUINT64)
2522 cluster_size = length + needed;
2524 if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
2525 cluster_time == GST_CLOCK_TIME_NONE) {
2526 cluster_time = demux->cluster_time * demux->common.time_scale;
2527 cluster_offset = demux->cluster_offset;
2528 GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
2529 " with time %" GST_TIME_FORMAT, cluster_offset,
2530 GST_TIME_ARGS (cluster_time));
2531 if (time == GST_CLOCK_TIME_NONE) {
2532 GST_DEBUG_OBJECT (demux, "found last cluster");
2533 prev_cluster_time = cluster_time;
2534 prev_cluster_offset = cluster_offset;
2537 if (cluster_time > time) {
2538 GST_DEBUG_OBJECT (demux, "overshot target");
2539 /* cluster overshoots */
2540 if (cluster_offset == demux->first_cluster_offset) {
2541 /* but no prev one */
2542 GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
2543 prev_cluster_time = cluster_time;
2544 prev_cluster_offset = cluster_offset;
2547 if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
2548 /* prev cluster did not overshoot, so prev cluster is target */
2551 /* re-estimate using this new position info */
2552 opos = cluster_offset;
2553 otime = cluster_time;
2557 /* cluster undershoots */
2558 GST_DEBUG_OBJECT (demux, "undershot target");
2559 /* ok if close enough */
2560 if (GST_CLOCK_DIFF (cluster_time, time) < 5 * GST_SECOND) {
2561 GST_DEBUG_OBJECT (demux, "target close enough");
2562 prev_cluster_time = cluster_time;
2563 prev_cluster_offset = cluster_offset;
2567 /* we are in between atime and otime => can bisect if worthwhile */
2568 if (prev_cluster_time != GST_CLOCK_TIME_NONE &&
2569 cluster_time > prev_cluster_time &&
2570 (GST_CLOCK_DIFF (prev_cluster_time, cluster_time) * 10 <
2571 GST_CLOCK_DIFF (cluster_time, time))) {
2572 /* we moved at least one cluster forward,
2573 * and it looks like target is still far away,
2574 * let's estimate again */
2575 GST_DEBUG_OBJECT (demux, "bisecting with new apos");
2576 apos = cluster_offset;
2577 atime = cluster_time;
2581 /* cluster undershoots, goto next one */
2582 prev_cluster_time = cluster_time;
2583 prev_cluster_offset = cluster_offset;
2584 /* skip cluster if length is defined,
2585 * otherwise will be skippingly parsed into */
2587 GST_DEBUG_OBJECT (demux, "skipping to next cluster");
2588 demux->common.offset = cluster_offset + cluster_size;
2589 demux->cluster_time = GST_CLOCK_TIME_NONE;
2591 GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
2598 if (ret == GST_FLOW_EOS) {
2599 if (prev_cluster_time != GST_CLOCK_TIME_NONE)
2605 /* In the bisect loop above we always undershoot and then jump forward
2606 * cluster-by-cluster until we overshoot, so if we get here we've gone
2607 * over and the previous cluster is where we need to go to. */
2608 cluster_offset = prev_cluster_offset;
2609 cluster_time = prev_cluster_time;
2611 /* If we have video and can easily backtrack, check if we landed on a cluster
2612 * that starts with a keyframe - and if not backtrack until we find one that
2614 if (demux->have_nonintraonly_v_streams && demux->max_backtrack_distance > 0) {
2615 if (gst_matroska_demux_scan_back_for_keyframe_cluster (demux,
2616 &cluster_offset, &cluster_time)) {
2617 GST_INFO_OBJECT (demux, "Adjusted cluster to %" GST_TIME_FORMAT " @ "
2618 "%" G_GUINT64_FORMAT, GST_TIME_ARGS (cluster_time), cluster_offset);
2622 entry = g_new0 (GstMatroskaIndex, 1);
2623 entry->time = cluster_time;
2624 entry->pos = cluster_offset - demux->common.ebml_segment_start;
2625 GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
2626 ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
2630 /* restore some state */
2631 demux->cluster_offset = current_cluster_offset;
2632 demux->cluster_time = current_cluster_time;
2633 demux->common.offset = current_offset;
2634 demux->common.state = current_state;
2640 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
2641 GstPad * pad, GstEvent * event)
2643 GstMatroskaIndex *entry = NULL;
2644 GstMatroskaIndex scan_entry;
2646 GstSeekType cur_type, stop_type;
2648 gboolean flush, keyunit, before, after, snap_next;
2651 GstMatroskaTrackContext *track = NULL;
2652 GstSegment seeksegment = { 0, };
2653 gboolean update = TRUE;
2654 gboolean pad_locked = FALSE;
2656 GstSearchMode snap_dir;
2658 g_return_val_if_fail (event != NULL, FALSE);
2661 track = gst_pad_get_element_private (pad);
2663 GST_DEBUG_OBJECT (demux, "Have seek %" GST_PTR_FORMAT, event);
2665 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2667 seqnum = gst_event_get_seqnum (event);
2669 /* we can only seek on time */
2670 if (format != GST_FORMAT_TIME) {
2671 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2675 /* copy segment, we need this because we still need the old
2676 * segment when we close the current segment. */
2677 memcpy (&seeksegment, &demux->common.segment, sizeof (GstSegment));
2679 /* pull mode without index means that the actual duration is not known,
2680 * we might be playing a file that's still being recorded
2681 * so, invalidate our current duration, which is only a moving target,
2682 * and should not be used to clamp anything */
2683 if (!demux->streaming && !demux->common.index && demux->invalid_duration) {
2684 seeksegment.duration = GST_CLOCK_TIME_NONE;
2687 GST_DEBUG_OBJECT (demux, "configuring seek");
2688 /* Subtract stream_start_time so we always seek on a segment
2690 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2691 seeksegment.start -= demux->stream_start_time;
2692 seeksegment.position -= demux->stream_start_time;
2693 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2694 seeksegment.stop -= demux->stream_start_time;
2696 seeksegment.stop = seeksegment.duration;
2699 gst_segment_do_seek (&seeksegment, rate, format, flags,
2700 cur_type, cur, stop_type, stop, &update);
2702 /* Restore the clip timestamp offset */
2703 if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
2704 seeksegment.position += demux->stream_start_time;
2705 seeksegment.start += demux->stream_start_time;
2706 if (!GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2707 seeksegment.stop = seeksegment.duration;
2708 if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
2709 seeksegment.stop += demux->stream_start_time;
2712 /* restore segment duration (if any effect),
2713 * would be determined again when parsing, but anyway ... */
2714 seeksegment.duration = demux->common.segment.duration;
2716 flush = !!(flags & GST_SEEK_FLAG_FLUSH);
2717 keyunit = !!(flags & GST_SEEK_FLAG_KEY_UNIT);
2718 after = !!(flags & GST_SEEK_FLAG_SNAP_AFTER);
2719 before = !!(flags & GST_SEEK_FLAG_SNAP_BEFORE);
2721 /* always do full update if flushing,
2722 * otherwise problems might arise downstream with missing keyframes etc */
2723 update = update || flush;
2725 GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2727 /* check sanity before we start flushing and all that */
2728 snap_next = after && !before;
2729 if (seeksegment.rate < 0)
2730 snap_dir = snap_next ? GST_SEARCH_MODE_BEFORE : GST_SEARCH_MODE_AFTER;
2732 snap_dir = snap_next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE;
2734 GST_OBJECT_LOCK (demux);
2735 track = gst_matroska_read_common_get_seek_track (&demux->common, track);
2736 if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
2737 seeksegment.position, &demux->seek_index, &demux->seek_entry,
2738 snap_dir)) == NULL) {
2739 /* pull mode without index can scan later on */
2740 if (demux->streaming) {
2741 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
2742 GST_OBJECT_UNLOCK (demux);
2744 } else if (rate < 0.0) {
2745 /* FIXME: We should build an index during playback or when scanning
2746 * that can be used here. The reverse playback code requires seek_index
2747 * and seek_entry to be set!
2749 GST_DEBUG_OBJECT (demux,
2750 "No matching seek entry in index, needed for reverse playback");
2751 GST_OBJECT_UNLOCK (demux);
2755 GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2756 GST_OBJECT_UNLOCK (demux);
2759 /* only have to update some segment,
2760 * but also still have to honour flush and so on */
2761 GST_DEBUG_OBJECT (demux, "... no update");
2762 /* bad goto, bad ... */
2766 if (demux->streaming)
2771 GstEvent *flush_event = gst_event_new_flush_start ();
2772 gst_event_set_seqnum (flush_event, seqnum);
2773 GST_DEBUG_OBJECT (demux, "Starting flush");
2774 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2775 gst_matroska_demux_send_event (demux, flush_event);
2777 GST_DEBUG_OBJECT (demux, "Non-flushing seek, pausing task");
2778 gst_pad_pause_task (demux->common.sinkpad);
2782 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2787 /* now grab the stream lock so that streaming cannot continue, for
2788 * non flushing seeks when the element is in PAUSED this could block
2790 GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
2791 GST_PAD_STREAM_LOCK (demux->common.sinkpad);
2794 /* pull mode without index can do some scanning */
2795 if (!demux->streaming && !entry) {
2796 GstEvent *flush_event;
2798 /* need to stop flushing upstream as we need it next */
2800 flush_event = gst_event_new_flush_stop (TRUE);
2801 gst_event_set_seqnum (flush_event, seqnum);
2802 gst_pad_push_event (demux->common.sinkpad, flush_event);
2804 entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
2805 /* keep local copy */
2807 scan_entry = *entry;
2809 entry = &scan_entry;
2811 GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
2813 flush_event = gst_event_new_flush_stop (TRUE);
2814 gst_event_set_seqnum (flush_event, seqnum);
2815 gst_matroska_demux_send_event (demux, flush_event);
2822 if (keyunit && seeksegment.rate > 0) {
2823 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
2824 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2825 GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
2826 seeksegment.start = MAX (entry->time, demux->stream_start_time);
2827 seeksegment.position = seeksegment.start;
2828 seeksegment.time = seeksegment.start - demux->stream_start_time;
2829 } else if (keyunit) {
2830 GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment stop from %"
2831 GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
2832 GST_TIME_ARGS (seeksegment.stop), GST_TIME_ARGS (entry->time));
2833 seeksegment.stop = MAX (entry->time, demux->stream_start_time);
2834 seeksegment.position = seeksegment.stop;
2837 if (demux->streaming) {
2838 GST_OBJECT_LOCK (demux);
2839 /* track real position we should start at */
2840 GST_DEBUG_OBJECT (demux, "storing segment start");
2841 demux->requested_seek_time = seeksegment.position;
2842 demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
2843 GST_OBJECT_UNLOCK (demux);
2844 /* need to seek to cluster start to pick up cluster time */
2845 /* upstream takes care of flushing and all that
2846 * ... and newsegment event handling takes care of the rest */
2847 return perform_seek_to_offset (demux, rate,
2848 entry->pos + demux->common.ebml_segment_start, seqnum, flags);
2853 GstEvent *flush_event = gst_event_new_flush_stop (TRUE);
2854 gst_event_set_seqnum (flush_event, seqnum);
2855 GST_DEBUG_OBJECT (demux, "Stopping flush");
2856 gst_pad_push_event (demux->common.sinkpad, gst_event_ref (flush_event));
2857 gst_matroska_demux_send_event (demux, flush_event);
2860 GST_OBJECT_LOCK (demux);
2861 /* now update the real segment info */
2862 GST_DEBUG_OBJECT (demux, "Committing new seek segment");
2863 memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
2864 GST_OBJECT_UNLOCK (demux);
2866 /* update some (segment) state */
2867 if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE, update))
2870 /* notify start of new segment */
2871 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
2874 msg = gst_message_new_segment_start (GST_OBJECT (demux),
2875 GST_FORMAT_TIME, demux->common.segment.start);
2876 gst_message_set_seqnum (msg, seqnum);
2877 gst_element_post_message (GST_ELEMENT (demux), msg);
2880 GST_OBJECT_LOCK (demux);
2881 if (demux->new_segment)
2882 gst_event_unref (demux->new_segment);
2884 /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
2885 demux->new_segment = gst_event_new_segment (&demux->common.segment);
2886 gst_event_set_seqnum (demux->new_segment, seqnum);
2887 if (demux->common.segment.rate < 0 && demux->common.segment.stop == -1)
2888 demux->to_time = demux->common.segment.position;
2890 demux->to_time = GST_CLOCK_TIME_NONE;
2891 demux->segment_seqnum = seqnum;
2892 GST_OBJECT_UNLOCK (demux);
2894 /* restart our task since it might have been stopped when we did the
2896 gst_pad_start_task (demux->common.sinkpad,
2897 (GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad, NULL);
2899 /* streaming can continue now */
2901 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2909 GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
2911 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2917 * Handle whether we can perform the seek event or if we have to let the chain
2918 * function handle seeks to build the seek indexes first.
2921 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2925 GstSeekType cur_type, stop_type;
2930 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2935 /* we can only seek on time */
2936 if (format != GST_FORMAT_TIME) {
2937 GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2941 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
2942 GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
2946 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
2947 GST_DEBUG_OBJECT (demux,
2948 "Non-flushing seek not supported in streaming mode");
2952 if (flags & GST_SEEK_FLAG_SEGMENT) {
2953 GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
2957 /* check for having parsed index already */
2958 if (!demux->common.index_parsed) {
2959 gboolean building_index;
2962 if (!demux->index_offset) {
2963 GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
2967 GST_OBJECT_LOCK (demux);
2968 /* handle the seek event in the chain function */
2969 demux->common.state = GST_MATROSKA_READ_STATE_SEEK;
2970 /* no more seek can be issued until state reset to _DATA */
2972 /* copy the event */
2973 if (demux->seek_event)
2974 gst_event_unref (demux->seek_event);
2975 demux->seek_event = gst_event_ref (event);
2977 /* set the building_index flag so that only one thread can setup the
2978 * structures for index seeking. */
2979 building_index = demux->building_index;
2980 if (!building_index) {
2981 demux->building_index = TRUE;
2982 offset = demux->index_offset;
2984 GST_OBJECT_UNLOCK (demux);
2986 if (!building_index) {
2987 /* seek to the first subindex or legacy index */
2988 GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
2989 return perform_seek_to_offset (demux, rate, offset,
2990 gst_event_get_seqnum (event), GST_SEEK_FLAG_NONE);
2993 /* well, we are handling it already */
2997 /* delegate to tweaked regular seek */
2998 return gst_matroska_demux_handle_seek_event (demux, pad, event);
3002 gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent,
3005 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
3006 gboolean res = TRUE;
3008 switch (GST_EVENT_TYPE (event)) {
3009 case GST_EVENT_SEEK:
3010 /* no seeking until we are (safely) ready */
3011 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA) {
3012 GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
3013 gst_event_unref (event);
3018 guint32 seqnum = gst_event_get_seqnum (event);
3019 if (seqnum == demux->segment_seqnum) {
3020 GST_LOG_OBJECT (pad,
3021 "Drop duplicated SEEK event seqnum %" G_GUINT32_FORMAT, seqnum);
3022 gst_event_unref (event);
3027 if (!demux->streaming)
3028 res = gst_matroska_demux_handle_seek_event (demux, pad, event);
3030 res = gst_matroska_demux_handle_seek_push (demux, pad, event);
3031 gst_event_unref (event);
3036 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
3037 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3038 GstMatroskaTrackVideoContext *videocontext =
3039 (GstMatroskaTrackVideoContext *) context;
3041 GstClockTimeDiff diff;
3042 GstClockTime timestamp;
3044 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
3046 GST_OBJECT_LOCK (demux);
3047 videocontext->earliest_time = timestamp + diff;
3048 GST_OBJECT_UNLOCK (demux);
3051 gst_event_unref (event);
3055 case GST_EVENT_TOC_SELECT:
3058 GstTocEntry *entry = NULL;
3059 GstEvent *seek_event;
3062 if (!demux->common.toc) {
3063 GST_DEBUG_OBJECT (demux, "no TOC to select");
3066 gst_event_parse_toc_select (event, &uid);
3068 GST_OBJECT_LOCK (demux);
3069 entry = gst_toc_find_entry (demux->common.toc, uid);
3070 if (entry == NULL) {
3071 GST_OBJECT_UNLOCK (demux);
3072 GST_WARNING_OBJECT (demux, "no TOC entry with given UID: %s", uid);
3075 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
3076 GST_OBJECT_UNLOCK (demux);
3077 seek_event = gst_event_new_seek (1.0,
3079 GST_SEEK_FLAG_FLUSH,
3080 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_SET, -1);
3081 res = gst_matroska_demux_handle_seek_event (demux, pad, seek_event);
3082 gst_event_unref (seek_event);
3086 GST_WARNING_OBJECT (demux, "received empty TOC select event");
3090 gst_event_unref (event);
3094 /* events we don't need to handle */
3095 case GST_EVENT_NAVIGATION:
3096 gst_event_unref (event);
3100 case GST_EVENT_LATENCY:
3102 res = gst_pad_push_event (demux->common.sinkpad, event);
3110 gst_matroska_demux_handle_sink_query (GstPad * pad, GstObject * parent,
3113 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
3114 gboolean res = FALSE;
3116 switch (GST_QUERY_TYPE (query)) {
3117 case GST_QUERY_BITRATE:
3119 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
3120 demux->common.offset >= demux->cached_length)) {
3121 demux->cached_length =
3122 gst_matroska_read_common_get_length (&demux->common);
3125 if (demux->cached_length < G_MAXUINT64
3126 && demux->common.segment.duration > 0) {
3127 /* TODO: better results based on ranges/index tables */
3129 gst_util_uint64_scale (8 * demux->cached_length, GST_SECOND,
3130 demux->common.segment.duration);
3132 GST_LOG_OBJECT (demux, "bitrate query byte length: %" G_GUINT64_FORMAT
3133 " duration %" GST_TIME_FORMAT " resulting in a bitrate of %u",
3134 demux->cached_length,
3135 GST_TIME_ARGS (demux->common.segment.duration), bitrate);
3137 gst_query_set_bitrate (query, bitrate);
3143 res = gst_pad_query_default (pad, (GstObject *) demux, query);
3150 static GstFlowReturn
3151 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
3153 GstFlowReturn ret = GST_FLOW_EOS;
3154 gboolean done = TRUE;
3157 g_return_val_if_fail (demux->seek_index, GST_FLOW_EOS);
3158 g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
3161 GST_DEBUG_OBJECT (demux, "locating previous keyframe");
3163 if (!demux->seek_entry) {
3164 GST_DEBUG_OBJECT (demux, "no earlier index entry");
3168 for (i = 0; i < demux->common.src->len; i++) {
3169 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->common.src, i);
3171 GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
3172 ", stream %d at %" GST_TIME_FORMAT,
3173 GST_TIME_ARGS (demux->common.segment.start), stream->index,
3174 GST_TIME_ARGS (stream->from_time));
3175 if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
3176 if (stream->from_time > demux->common.segment.start) {
3177 GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
3181 /* nothing pushed for this stream;
3182 * likely seek entry did not start at keyframe, so all was skipped.
3183 * So we need an earlier entry */
3189 GstMatroskaIndex *entry;
3191 entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
3192 --demux->seek_entry);
3193 if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE, TRUE))
3203 static GstFlowReturn
3204 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3206 GstFlowReturn ret = GST_FLOW_OK;
3209 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
3211 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3212 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3216 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3217 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3221 /* one track within the "all-tracks" header */
3222 case GST_MATROSKA_ID_TRACKENTRY:{
3223 GstMatroskaTrackContext *track;
3224 ret = gst_matroska_demux_parse_stream (demux, ebml, &track);
3225 if (track != NULL) {
3226 if (gst_matroska_read_common_tracknumber_unique (&demux->common,
3228 gst_matroska_demux_add_stream (demux, track);
3230 GST_ERROR_OBJECT (demux,
3231 "TrackNumber %" G_GUINT64_FORMAT " is not unique", track->num);
3232 ret = GST_FLOW_ERROR;
3233 gst_matroska_track_free (track);
3241 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3246 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3248 demux->tracks_parsed = TRUE;
3249 GST_DEBUG_OBJECT (demux, "signaling no more pads");
3250 gst_element_no_more_pads (GST_ELEMENT (demux));
3255 static GstFlowReturn
3256 gst_matroska_demux_update_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3258 GstFlowReturn ret = GST_FLOW_OK;
3259 guint num_tracks_found = 0;
3262 GST_INFO_OBJECT (demux, "Reparsing Tracks element");
3264 DEBUG_ELEMENT_START (demux, ebml, "Tracks");
3266 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3267 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3271 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3272 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3276 /* one track within the "all-tracks" header */
3277 case GST_MATROSKA_ID_TRACKENTRY:{
3278 GstMatroskaTrackContext *new_track;
3279 gint old_track_index;
3280 GstMatroskaTrackContext *old_track;
3281 ret = gst_matroska_demux_parse_stream (demux, ebml, &new_track);
3282 if (new_track == NULL)
3286 if (gst_matroska_read_common_tracknumber_unique (&demux->common,
3288 GST_ERROR_OBJECT (demux,
3289 "Unexpected new TrackNumber: %" G_GUINT64_FORMAT, new_track->num);
3290 goto track_mismatch_error;
3294 gst_matroska_read_common_stream_from_num (&demux->common,
3296 g_assert (old_track_index != -1);
3297 old_track = g_ptr_array_index (demux->common.src, old_track_index);
3299 if (old_track->type != new_track->type) {
3300 GST_ERROR_OBJECT (demux,
3301 "Mismatch reparsing track %" G_GUINT64_FORMAT
3302 " on track type. Expected %d, found %d", new_track->num,
3303 old_track->type, new_track->type);
3304 goto track_mismatch_error;
3307 if (g_strcmp0 (old_track->codec_id, new_track->codec_id) != 0) {
3308 GST_ERROR_OBJECT (demux,
3309 "Mismatch reparsing track %" G_GUINT64_FORMAT
3310 " on codec id. Expected '%s', found '%s'", new_track->num,
3311 old_track->codec_id, new_track->codec_id);
3312 goto track_mismatch_error;
3315 /* The new track matches the old track. No problems on our side.
3316 * Let's make it replace the old track. */
3317 new_track->pad = old_track->pad;
3318 new_track->index = old_track->index;
3319 new_track->pos = old_track->pos;
3320 g_ptr_array_index (demux->common.src, old_track_index) = new_track;
3321 gst_pad_set_element_private (new_track->pad, new_track);
3323 if (!gst_caps_is_equal (old_track->caps, new_track->caps)) {
3324 gst_pad_set_caps (new_track->pad, new_track->caps);
3326 gst_caps_replace (&old_track->caps, NULL);
3328 if (!gst_tag_list_is_equal (old_track->tags, new_track->tags)) {
3329 GST_DEBUG_OBJECT (old_track->pad, "Sending tags %p: %"
3330 GST_PTR_FORMAT, new_track->tags, new_track->tags);
3331 gst_pad_push_event (new_track->pad,
3332 gst_event_new_tag (gst_tag_list_copy (new_track->tags)));
3335 gst_matroska_track_free (old_track);
3338 track_mismatch_error:
3339 gst_matroska_track_free (new_track);
3341 ret = GST_FLOW_ERROR;
3346 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
3351 DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3353 if (ret != GST_FLOW_ERROR && demux->common.num_streams != num_tracks_found) {
3354 GST_ERROR_OBJECT (demux,
3355 "Mismatch on the number of tracks. Expected %du tracks, found %du",
3356 demux->common.num_streams, num_tracks_found);
3357 ret = GST_FLOW_ERROR;
3364 * Read signed/unsigned "EBML" numbers.
3365 * Return: number of bytes processed.
3369 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
3371 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
3379 while (read <= 8 && !(total & len_mask)) {
3386 if ((total &= (len_mask - 1)) == len_mask - 1)
3391 if (data[n] == 0xff)
3393 total = (total << 8) | data[n];
3397 if (read == num_ffs && total != 0)
3406 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
3411 /* read as unsigned number first */
3412 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
3416 if (unum == G_MAXUINT64)
3419 *num = unum - ((1 << ((7 * res) - 1)) - 1);
3425 * Mostly used for subtitles. We add void filler data for each
3426 * lagging stream to make sure we don't deadlock.
3430 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
3432 GstClockTime gap_threshold;
3435 GST_OBJECT_LOCK (demux);
3437 GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
3438 GST_TIME_ARGS (demux->common.segment.position));
3440 g_assert (demux->common.num_streams == demux->common.src->len);
3441 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
3442 GstMatroskaTrackContext *context;
3444 context = g_ptr_array_index (demux->common.src, stream_nr);
3446 GST_LOG_OBJECT (demux,
3447 "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
3448 GST_TIME_ARGS (context->pos));
3450 /* Only send gap events on non-subtitle streams if lagging way behind.
3451 * The 0.5 second threshold for subtitle streams is also quite random. */
3452 if (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)
3453 gap_threshold = GST_SECOND / 2;
3455 gap_threshold = 3 * GST_SECOND;
3457 /* Lag need only be considered if we have advanced into requested segment */
3458 if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
3459 GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
3460 demux->common.segment.position > demux->common.segment.start &&
3461 context->pos + gap_threshold < demux->common.segment.position) {
3464 guint64 start = context->pos;
3465 guint64 stop = demux->common.segment.position - gap_threshold;
3467 GST_DEBUG_OBJECT (demux,
3468 "Synchronizing stream %d with other by advancing time from %"
3469 GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
3470 GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
3472 context->pos = stop;
3474 event = gst_event_new_gap (start, stop - start);
3475 GST_OBJECT_UNLOCK (demux);
3476 gst_pad_push_event (context->pad, event);
3477 GST_OBJECT_LOCK (demux);
3481 GST_OBJECT_UNLOCK (demux);
3484 static GstFlowReturn
3485 gst_matroska_demux_push_stream_headers (GstMatroskaDemux * demux,
3486 GstMatroskaTrackContext * stream)
3488 GstFlowReturn ret = GST_FLOW_OK;
3491 num = gst_buffer_list_length (stream->stream_headers);
3492 for (i = 0; i < num; ++i) {
3495 buf = gst_buffer_list_get (stream->stream_headers, i);
3496 buf = gst_buffer_copy (buf);
3498 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
3500 if (stream->set_discont) {
3501 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
3502 stream->set_discont = FALSE;
3504 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
3507 /* push out all headers in one go and use last flow return */
3508 ret = gst_pad_push (stream->pad, buf);
3511 /* don't need these any longer */
3512 gst_buffer_list_unref (stream->stream_headers);
3513 stream->stream_headers = NULL;
3516 ret = gst_flow_combiner_update_flow (demux->flowcombiner, ret);
3522 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
3523 GstMatroskaTrackContext * stream)
3527 g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
3529 if (!stream->codec_priv)
3532 /* ideally, VobSub private data should be parsed and stored more convenient
3533 * elsewhere, but for now, only interested in a small part */
3535 /* make sure we have terminating 0 */
3536 buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
3538 /* just locate and parse palette part */
3539 start = strstr (buf, "palette:");
3544 guint8 r, g, b, y, u, v;
3547 while (g_ascii_isspace (*start))
3549 for (i = 0; i < 16; i++) {
3550 if (sscanf (start, "%06x", &col) != 1)
3553 while ((*start == ',') || g_ascii_isspace (*start))
3555 /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
3556 r = (col >> 16) & 0xff;
3557 g = (col >> 8) & 0xff;
3559 y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
3561 u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
3562 v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
3563 clut[i] = (y << 16) | (u << 8) | v;
3566 /* got them all without problems; build and send event */
3570 s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
3571 "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
3572 G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
3573 G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
3574 G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
3575 G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
3576 G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
3577 G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
3578 G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
3579 G_TYPE_INT, clut[15], NULL);
3581 gst_pad_push_event (stream->pad,
3582 gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s));
3589 gst_matroska_demux_push_codec_data_all (GstMatroskaDemux * demux)
3593 g_assert (demux->common.num_streams == demux->common.src->len);
3594 for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
3595 GstMatroskaTrackContext *stream;
3597 stream = g_ptr_array_index (demux->common.src, stream_nr);
3599 if (stream->send_stream_headers) {
3600 if (stream->stream_headers != NULL) {
3601 gst_matroska_demux_push_stream_headers (demux, stream);
3603 /* FIXME: perhaps we can just disable and skip this stream then */
3604 GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
3605 ("Failed to extract stream headers from codec private data"));
3607 stream->send_stream_headers = FALSE;
3610 if (stream->send_dvd_event) {
3611 gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
3612 /* FIXME: should we send this event again after (flushing) seek ? */
3613 stream->send_dvd_event = FALSE;
3619 static GstFlowReturn
3620 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
3621 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3624 guint seq_header_len;
3625 guint32 header, tmp;
3627 if (stream->codec_state) {
3628 seq_header = stream->codec_state;
3629 seq_header_len = stream->codec_state_size;
3630 } else if (stream->codec_priv) {
3631 seq_header = stream->codec_priv;
3632 seq_header_len = stream->codec_priv_size;
3637 /* Sequence header only needed for keyframes */
3638 if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
3641 if (gst_buffer_get_size (*buf) < 4)
3644 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
3645 header = GUINT32_FROM_BE (tmp);
3647 /* Sequence start code, if not found prepend */
3648 if (header != 0x000001b3) {
3651 GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
3653 newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
3656 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
3657 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
3658 gst_buffer_get_size (*buf));
3660 gst_buffer_unref (*buf);
3667 static GstFlowReturn
3668 gst_matroska_demux_add_wvpk_header (GstElement * element,
3669 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3671 GstMatroskaTrackAudioContext *audiocontext =
3672 (GstMatroskaTrackAudioContext *) stream;
3673 GstBuffer *newbuf = NULL;
3674 GstMapInfo map, outmap;
3675 guint8 *buf_data, *data;
3683 wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
3686 wvh.total_samples = -1;
3687 wvh.block_index = audiocontext->wvpk_block_index;
3689 if (audiocontext->channels <= 2) {
3690 guint32 block_samples, tmp;
3691 gsize size = gst_buffer_get_size (*buf);
3693 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
3694 block_samples = GUINT32_FROM_LE (tmp);
3695 /* we need to reconstruct the header of the wavpack block */
3697 /* -20 because ck_size is the size of the wavpack block -8
3698 * and lace_size is the size of the wavpack block + 12
3699 * (the three guint32 of the header that already are in the buffer) */
3700 wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
3702 /* block_samples, flags and crc are already in the buffer */
3703 newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
3705 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3711 GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
3712 GST_WRITE_UINT16_LE (data + 8, wvh.version);
3713 GST_WRITE_UINT8 (data + 10, wvh.track_no);
3714 GST_WRITE_UINT8 (data + 11, wvh.index_no);
3715 GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
3716 GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
3717 gst_buffer_unmap (newbuf, &outmap);
3719 /* Append data from buf: */
3720 gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
3721 GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
3723 gst_buffer_unref (*buf);
3725 audiocontext->wvpk_block_index += block_samples;
3727 guint8 *outdata = NULL;
3729 gsize buf_size, size, out_size = 0;
3730 guint32 block_samples, flags, crc, blocksize;
3732 gst_buffer_map (*buf, &map, GST_MAP_READ);
3733 buf_data = map.data;
3734 buf_size = map.size;
3737 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
3738 gst_buffer_unmap (*buf, &map);
3739 return GST_FLOW_ERROR;
3745 block_samples = GST_READ_UINT32_LE (data);
3750 flags = GST_READ_UINT32_LE (data);
3753 crc = GST_READ_UINT32_LE (data);
3756 blocksize = GST_READ_UINT32_LE (data);
3760 if (blocksize == 0 || size < blocksize)
3763 g_assert ((newbuf == NULL) == (outdata == NULL));
3765 if (newbuf == NULL) {
3766 out_size = sizeof (Wavpack4Header) + blocksize;
3767 newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
3769 gst_buffer_copy_into (newbuf, *buf,
3770 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
3773 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3774 outdata = outmap.data;
3776 gst_buffer_unmap (newbuf, &outmap);
3777 out_size += sizeof (Wavpack4Header) + blocksize;
3778 gst_buffer_set_size (newbuf, out_size);
3779 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
3780 outdata = outmap.data;
3783 outdata[outpos] = 'w';
3784 outdata[outpos + 1] = 'v';
3785 outdata[outpos + 2] = 'p';
3786 outdata[outpos + 3] = 'k';
3789 GST_WRITE_UINT32_LE (outdata + outpos,
3790 blocksize + sizeof (Wavpack4Header) - 8);
3791 GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
3792 GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
3793 GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
3794 GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
3795 GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
3796 GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
3797 GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
3798 GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
3801 memmove (outdata + outpos, data, blocksize);
3802 outpos += blocksize;
3806 gst_buffer_unmap (*buf, &map);
3807 gst_buffer_unref (*buf);
3810 gst_buffer_unmap (newbuf, &outmap);
3813 audiocontext->wvpk_block_index += block_samples;
3819 static GstFlowReturn
3820 gst_matroska_demux_add_prores_header (GstElement * element,
3821 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3823 GstBuffer *newbuf = gst_buffer_new_allocate (NULL, 8, NULL);
3827 if (!gst_buffer_map (newbuf, &map, GST_MAP_WRITE)) {
3828 GST_ERROR ("Failed to map newly allocated buffer");
3829 return GST_FLOW_ERROR;
3832 frame_size = gst_buffer_get_size (*buf);
3834 GST_WRITE_UINT32_BE (map.data, frame_size);
3840 gst_buffer_unmap (newbuf, &map);
3841 *buf = gst_buffer_append (newbuf, *buf);
3846 /* @text must be null-terminated */
3848 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
3853 g_return_val_if_fail (text != NULL, FALSE);
3855 /* yes, this might all lead to false positives ... */
3856 tag = (gchar *) text;
3857 while ((tag = strchr (tag, '<'))) {
3859 if (*tag != '\0' && *(tag + 1) == '>') {
3860 /* some common convenience ones */
3861 /* maybe any character will do here ? */
3874 if (strstr (text, "<span"))
3880 static GstFlowReturn
3881 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
3882 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3884 GstMatroskaTrackSubtitleContext *sub_stream;
3885 const gchar *encoding;
3890 gboolean needs_unmap = TRUE;
3892 sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
3894 if (!gst_buffer_get_size (*buf) || !gst_buffer_map (*buf, &map, GST_MAP_READ))
3897 /* The subtitle buffer we push out should not include a NUL terminator as
3898 * part of the data. */
3899 if (map.data[map.size - 1] == '\0') {
3900 gst_buffer_set_size (*buf, map.size - 1);
3901 gst_buffer_unmap (*buf, &map);
3902 gst_buffer_map (*buf, &map, GST_MAP_READ);
3905 if (!sub_stream->invalid_utf8) {
3906 if (g_utf8_validate ((gchar *) map.data, map.size, NULL)) {
3909 GST_WARNING_OBJECT (element, "subtitle stream %" G_GUINT64_FORMAT
3910 " is not valid UTF-8, this is broken according to the matroska"
3911 " specification", stream->num);
3912 sub_stream->invalid_utf8 = TRUE;
3915 /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
3916 encoding = g_getenv ("GST_SUBTITLE_ENCODING");
3917 if (encoding == NULL || *encoding == '\0') {
3918 /* if local encoding is UTF-8 and no encoding specified
3919 * via the environment variable, assume ISO-8859-15 */
3920 if (g_get_charset (&encoding)) {
3921 encoding = "ISO-8859-15";
3926 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8", encoding,
3927 (char *) "*", NULL, NULL, &err);
3930 GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
3931 encoding, err->message);
3935 /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
3936 encoding = "ISO-8859-15";
3938 g_convert_with_fallback ((gchar *) map.data, map.size, "UTF-8",
3939 encoding, (char *) "*", NULL, NULL, NULL);
3942 GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
3943 encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
3946 utf8 = g_strdup ("invalid subtitle");
3948 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3949 gst_buffer_unmap (*buf, &map);
3950 gst_buffer_copy_into (newbuf, *buf,
3951 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
3953 gst_buffer_unref (*buf);
3956 gst_buffer_map (*buf, &map, GST_MAP_READ);
3960 if (sub_stream->check_markup) {
3961 /* caps claim markup text, so we need to escape text,
3962 * except if text is already markup and then needs no further escaping */
3963 sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
3964 gst_matroska_demux_subtitle_chunk_has_tag (element, (gchar *) map.data);
3966 if (!sub_stream->seen_markup_tag) {
3967 utf8 = g_markup_escape_text ((gchar *) map.data, map.size);
3969 newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
3970 gst_buffer_unmap (*buf, &map);
3971 gst_buffer_copy_into (newbuf, *buf,
3972 GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
3973 GST_BUFFER_COPY_META, 0, -1);
3974 gst_buffer_unref (*buf);
3977 needs_unmap = FALSE;
3982 gst_buffer_unmap (*buf, &map);
3987 static GstFlowReturn
3988 gst_matroska_demux_check_aac (GstElement * element,
3989 GstMatroskaTrackContext * stream, GstBuffer ** buf)
3994 gst_buffer_extract (*buf, 0, data, 2);
3995 size = gst_buffer_get_size (*buf);
3997 if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
4000 /* tss, ADTS data, remove codec_data
4001 * still assume it is at least parsed */
4002 stream->caps = gst_caps_make_writable (stream->caps);
4003 s = gst_caps_get_structure (stream->caps, 0);
4005 gst_structure_remove_field (s, "codec_data");
4006 gst_pad_set_caps (stream->pad, stream->caps);
4007 GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
4008 "new caps: %" GST_PTR_FORMAT, stream->caps);
4011 /* disable subsequent checking */
4012 stream->postprocess_frame = NULL;
4018 gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
4019 GstBuffer * buffer, gsize alignment)
4023 gst_buffer_map (buffer, &map, GST_MAP_READ);
4025 if (map.size < sizeof (guintptr)) {
4026 gst_buffer_unmap (buffer, &map);
4030 if (((guintptr) map.data) & (alignment - 1)) {
4031 GstBuffer *new_buffer;
4032 GstAllocationParams params = { 0, alignment - 1, 0, 0, };
4034 new_buffer = gst_buffer_new_allocate (NULL,
4035 gst_buffer_get_size (buffer), ¶ms);
4037 /* Copy data "by hand", so ensure alignment is kept: */
4038 gst_buffer_fill (new_buffer, 0, map.data, map.size);
4040 gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
4041 GST_DEBUG_OBJECT (demux,
4042 "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
4045 gst_buffer_unmap (buffer, &map);
4046 gst_buffer_unref (buffer);
4051 gst_buffer_unmap (buffer, &map);
4055 static GstFlowReturn
4056 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
4057 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
4058 gboolean is_simpleblock)
4060 GstMatroskaTrackContext *stream = NULL;
4061 GstFlowReturn ret = GST_FLOW_OK;
4062 gboolean readblock = FALSE;
4064 guint64 block_duration = -1;
4065 gint64 block_discardpadding = 0;
4066 GstBuffer *buf = NULL;
4068 gint stream_num = -1, n, laces = 0;
4070 gint *lace_size = NULL;
4073 gint64 referenceblock = 0;
4075 GstClockTime buffer_timestamp;
4077 offset = gst_ebml_read_get_offset (ebml);
4079 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4080 if (!is_simpleblock) {
4081 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
4085 id = GST_MATROSKA_ID_SIMPLEBLOCK;
4089 /* one block inside the group. Note, block parsing is one
4090 * of the harder things, so this code is a bit complicated.
4091 * See http://www.matroska.org/ for documentation. */
4092 case GST_MATROSKA_ID_SIMPLEBLOCK:
4093 case GST_MATROSKA_ID_BLOCK:
4099 gst_buffer_unmap (buf, &map);
4100 gst_buffer_unref (buf);
4103 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
4106 gst_buffer_map (buf, &map, GST_MAP_READ);
4110 /* first byte(s): blocknum */
4111 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
4116 /* fetch stream from num */
4117 stream_num = gst_matroska_read_common_stream_from_num (&demux->common,
4119 if (G_UNLIKELY (size < 3)) {
4120 GST_WARNING_OBJECT (demux, "Invalid size %u", size);
4121 /* non-fatal, try next block(group) */
4124 } else if (G_UNLIKELY (stream_num < 0 ||
4125 stream_num >= demux->common.num_streams)) {
4126 /* let's not give up on a stray invalid track number */
4127 GST_WARNING_OBJECT (demux,
4128 "Invalid stream %d for track number %" G_GUINT64_FORMAT
4129 "; ignoring block", stream_num, num);
4133 stream = g_ptr_array_index (demux->common.src, stream_num);
4135 /* time (relative to cluster time) */
4136 time = ((gint16) GST_READ_UINT16_BE (data));
4139 flags = GST_READ_UINT8 (data);
4143 GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
4146 switch ((flags & 0x06) >> 1) {
4147 case 0x0: /* no lacing */
4149 lace_size = g_new (gint, 1);
4150 lace_size[0] = size;
4153 case 0x1: /* xiph lacing */
4154 case 0x2: /* fixed-size lacing */
4155 case 0x3: /* EBML lacing */
4157 goto invalid_lacing;
4158 laces = GST_READ_UINT8 (data) + 1;
4161 lace_size = g_new0 (gint, laces);
4163 switch ((flags & 0x06) >> 1) {
4164 case 0x1: /* xiph lacing */ {
4165 guint temp, total = 0;
4167 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
4170 goto invalid_lacing;
4171 temp = GST_READ_UINT8 (data);
4172 lace_size[n] += temp;
4178 total += lace_size[n];
4180 lace_size[n] = size - total;
4184 case 0x2: /* fixed-size lacing */
4185 for (n = 0; n < laces; n++)
4186 lace_size[n] = size / laces;
4189 case 0x3: /* EBML lacing */ {
4192 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
4196 total = lace_size[0] = num;
4197 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
4201 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
4205 lace_size[n] = lace_size[n - 1] + snum;
4206 total += lace_size[n];
4209 lace_size[n] = size - total;
4216 if (ret != GST_FLOW_OK)
4223 case GST_MATROSKA_ID_BLOCKDURATION:{
4224 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
4225 GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
4230 case GST_MATROSKA_ID_DISCARDPADDING:{
4231 ret = gst_ebml_read_sint (ebml, &id, &block_discardpadding);
4232 GST_DEBUG_OBJECT (demux, "DiscardPadding: %" GST_STIME_FORMAT,
4233 GST_STIME_ARGS (block_discardpadding));
4237 case GST_MATROSKA_ID_REFERENCEBLOCK:{
4238 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
4239 GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
4244 case GST_MATROSKA_ID_CODECSTATE:{
4246 guint64 data_len = 0;
4249 gst_ebml_read_binary (ebml, &id, &data,
4250 &data_len)) != GST_FLOW_OK)
4253 if (G_UNLIKELY (stream == NULL)) {
4254 GST_WARNING_OBJECT (demux,
4255 "Unexpected CodecState subelement - ignoring");
4259 g_free (stream->codec_state);
4260 stream->codec_state = data;
4261 stream->codec_state_size = data_len;
4263 /* Decode if necessary */
4264 if (stream->encodings && stream->encodings->len > 0
4265 && stream->codec_state && stream->codec_state_size > 0) {
4266 if (!gst_matroska_decode_data (stream->encodings,
4267 &stream->codec_state, &stream->codec_state_size,
4268 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
4269 GST_WARNING_OBJECT (demux, "Decoding codec state failed");
4273 GST_DEBUG_OBJECT (demux, "CodecState of %" G_GSIZE_FORMAT " bytes",
4274 stream->codec_state_size);
4279 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
4283 case GST_MATROSKA_ID_BLOCKVIRTUAL:
4284 case GST_MATROSKA_ID_BLOCKADDITIONS:
4285 case GST_MATROSKA_ID_REFERENCEPRIORITY:
4286 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
4287 case GST_MATROSKA_ID_SLICES:
4288 GST_DEBUG_OBJECT (demux,
4289 "Skipping BlockGroup subelement 0x%x - ignoring", id);
4290 ret = gst_ebml_read_skip (ebml);
4298 /* reading a number or so could have failed */
4299 if (ret != GST_FLOW_OK)
4302 if (ret == GST_FLOW_OK && readblock) {
4303 gboolean invisible_frame = FALSE;
4304 gboolean delta_unit = FALSE;
4305 guint64 duration = 0;
4306 gint64 lace_time = 0;
4307 GstEvent *protect_event;
4309 stream = g_ptr_array_index (demux->common.src, stream_num);
4311 if (cluster_time != GST_CLOCK_TIME_NONE) {
4312 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
4313 * Drop unless the lace contains timestamp 0? */
4314 if (time < 0 && (-time) > cluster_time) {
4317 if (stream->timecodescale == 1.0)
4318 lace_time = (cluster_time + time) * demux->common.time_scale;
4321 gst_util_guint64_to_gdouble ((cluster_time + time) *
4322 demux->common.time_scale) * stream->timecodescale;
4325 lace_time = GST_CLOCK_TIME_NONE;
4327 /* Send the GST_PROTECTION event */
4328 while ((protect_event = g_queue_pop_head (&stream->protection_event_queue))) {
4329 GST_TRACE_OBJECT (demux, "pushing protection event for stream %d:%s",
4330 stream->index, GST_STR_NULL (stream->name));
4331 gst_pad_push_event (stream->pad, protect_event);
4334 /* need to refresh segment info ASAP */
4335 if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
4336 GstSegment *segment = &demux->common.segment;
4338 GstEvent *segment_event;
4340 if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
4341 demux->stream_start_time = lace_time;
4342 GST_DEBUG_OBJECT (demux,
4343 "Setting stream start time to %" GST_TIME_FORMAT,
4344 GST_TIME_ARGS (lace_time));
4346 clace_time = MAX (lace_time, demux->stream_start_time);
4347 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
4348 demux->common.segment.position != 0) {
4349 GST_DEBUG_OBJECT (demux,
4350 "using stored seek position %" GST_TIME_FORMAT,
4351 GST_TIME_ARGS (demux->common.segment.position));
4352 clace_time = demux->common.segment.position;
4353 segment->position = GST_CLOCK_TIME_NONE;
4355 segment->start = clace_time;
4356 segment->stop = GST_CLOCK_TIME_NONE;
4357 segment->time = segment->start - demux->stream_start_time;
4358 segment->position = segment->start - demux->stream_start_time;
4359 GST_DEBUG_OBJECT (demux,
4360 "generated segment starting at %" GST_TIME_FORMAT ": %"
4361 GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
4362 /* now convey our segment notion downstream */
4363 segment_event = gst_event_new_segment (segment);
4364 if (demux->segment_seqnum)
4365 gst_event_set_seqnum (segment_event, demux->segment_seqnum);
4366 gst_matroska_demux_send_event (demux, segment_event);
4367 demux->need_segment = FALSE;
4368 demux->segment_seqnum = 0;
4371 /* send pending codec data headers for all streams,
4372 * before we perform sync across all streams */
4373 gst_matroska_demux_push_codec_data_all (demux);
4375 if (block_duration != -1) {
4376 if (stream->timecodescale == 1.0)
4377 duration = gst_util_uint64_scale (block_duration,
4378 demux->common.time_scale, 1);
4381 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
4382 (gst_util_uint64_scale (block_duration, demux->common.time_scale,
4383 1)) * stream->timecodescale);
4384 } else if (stream->default_duration) {
4385 duration = stream->default_duration * laces;
4387 /* else duration is diff between timecode of this and next block */
4389 if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
4390 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
4391 a ReferenceBlock implies that this is not a keyframe. In either
4392 case, it only makes sense for video streams. */
4393 if ((is_simpleblock && !(flags & 0x80)) || referenceblock) {
4395 invisible_frame = ((flags & 0x08)) &&
4396 (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8) ||
4397 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9) ||
4398 !strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_AV1));
4401 /* If we're doing a keyframe-only trickmode, only push keyframes on video
4404 && demux->common.segment.
4405 flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) {
4406 GST_LOG_OBJECT (demux, "Skipping non-keyframe on stream %d",
4413 for (n = 0; n < laces; n++) {
4416 if (G_UNLIKELY (lace_size[n] > size)) {
4417 GST_WARNING_OBJECT (demux, "Invalid lace size");
4421 /* QoS for video track with an index. the assumption is that
4422 index entries point to keyframes, but if that is not true we
4423 will instad skip until the next keyframe. */
4424 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
4425 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
4426 stream->index_table && demux->common.segment.rate > 0.0) {
4427 GstMatroskaTrackVideoContext *videocontext =
4428 (GstMatroskaTrackVideoContext *) stream;
4429 GstClockTime earliest_time;
4430 GstClockTime earliest_stream_time;
4432 GST_OBJECT_LOCK (demux);
4433 earliest_time = videocontext->earliest_time;
4434 GST_OBJECT_UNLOCK (demux);
4435 earliest_stream_time =
4436 gst_segment_position_from_running_time (&demux->common.segment,
4437 GST_FORMAT_TIME, earliest_time);
4439 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
4440 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
4441 lace_time <= earliest_stream_time) {
4442 /* find index entry (keyframe) <= earliest_stream_time */
4443 GstMatroskaIndex *entry =
4444 gst_util_array_binary_search (stream->index_table->data,
4445 stream->index_table->len, sizeof (GstMatroskaIndex),
4446 (GCompareDataFunc) gst_matroska_index_seek_find,
4447 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
4449 /* if that entry (keyframe) is after the current the current
4450 buffer, we can skip pushing (and thus decoding) all
4451 buffers until that keyframe. */
4452 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
4453 entry->time > lace_time) {
4454 GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
4455 stream->set_discont = TRUE;
4461 sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
4462 gst_buffer_get_size (buf) - size, lace_size[n]);
4463 GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
4466 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4468 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
4470 if (invisible_frame)
4471 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DECODE_ONLY);
4473 if (stream->encodings != NULL && stream->encodings->len > 0)
4474 sub = gst_matroska_decode_buffer (stream, sub);
4477 GST_WARNING_OBJECT (demux, "Decoding buffer failed");
4481 if (!stream->dts_only) {
4482 GST_BUFFER_PTS (sub) = lace_time;
4484 GST_BUFFER_DTS (sub) = lace_time;
4485 if (stream->intra_only)
4486 GST_BUFFER_PTS (sub) = lace_time;
4489 buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
4491 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
4492 GstClockTime last_stop_end;
4494 /* Check if this stream is after segment stop */
4495 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop) &&
4496 lace_time >= demux->common.segment.stop) {
4497 GST_DEBUG_OBJECT (demux,
4498 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
4499 GST_TIME_ARGS (demux->common.segment.stop));
4500 gst_buffer_unref (sub);
4503 if (offset >= stream->to_offset
4504 || (GST_CLOCK_TIME_IS_VALID (demux->to_time)
4505 && lace_time > demux->to_time)) {
4506 GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
4508 gst_buffer_unref (sub);
4512 /* handle gaps, e.g. non-zero start-time, or an cue index entry
4513 * that landed us with timestamps not quite intended */
4514 GST_OBJECT_LOCK (demux);
4515 if (demux->max_gap_time &&
4516 GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
4517 demux->common.segment.rate > 0.0) {
4518 GstClockTimeDiff diff;
4520 /* only send segments with increasing start times,
4521 * otherwise if these go back and forth downstream (sinks) increase
4522 * accumulated time and running_time */
4523 diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
4524 if (diff > 0 && diff > demux->max_gap_time
4525 && lace_time > demux->common.segment.start
4526 && (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
4527 || lace_time < demux->common.segment.stop)) {
4529 GST_DEBUG_OBJECT (demux,
4530 "Gap of %" G_GINT64_FORMAT " ns detected in"
4531 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
4532 "Sending updated SEGMENT events", diff,
4533 stream->index, GST_TIME_ARGS (stream->pos),
4534 GST_TIME_ARGS (lace_time));
4536 event = gst_event_new_gap (demux->last_stop_end, diff);
4537 GST_OBJECT_UNLOCK (demux);
4538 gst_pad_push_event (stream->pad, event);
4539 GST_OBJECT_LOCK (demux);
4543 if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
4544 || demux->common.segment.position < lace_time) {
4545 demux->common.segment.position = lace_time;
4547 GST_OBJECT_UNLOCK (demux);
4549 last_stop_end = lace_time;
4551 GST_BUFFER_DURATION (sub) = duration / laces;
4552 last_stop_end += GST_BUFFER_DURATION (sub);
4555 if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
4556 demux->last_stop_end < last_stop_end)
4557 demux->last_stop_end = last_stop_end;
4559 GST_OBJECT_LOCK (demux);
4560 if (demux->common.segment.duration == -1 ||
4561 demux->stream_start_time + demux->common.segment.duration <
4563 demux->common.segment.duration =
4564 last_stop_end - demux->stream_start_time;
4565 GST_OBJECT_UNLOCK (demux);
4566 if (!demux->invalid_duration) {
4567 gst_element_post_message (GST_ELEMENT_CAST (demux),
4568 gst_message_new_duration_changed (GST_OBJECT_CAST (demux)));
4569 demux->invalid_duration = TRUE;
4572 GST_OBJECT_UNLOCK (demux);
4576 stream->pos = lace_time;
4578 gst_matroska_demux_sync_streams (demux);
4580 if (stream->set_discont) {
4581 GST_DEBUG_OBJECT (demux, "marking DISCONT");
4582 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
4583 stream->set_discont = FALSE;
4585 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DISCONT);
4588 /* reverse playback book-keeping */
4589 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
4590 stream->from_time = lace_time;
4591 if (stream->from_offset == -1)
4592 stream->from_offset = offset;
4594 GST_DEBUG_OBJECT (demux,
4595 "Pushing lace %d, data of size %" G_GSIZE_FORMAT
4596 " for stream %d, time=%" GST_TIME_FORMAT " and duration=%"
4597 GST_TIME_FORMAT, n, gst_buffer_get_size (sub), stream_num,
4598 GST_TIME_ARGS (buffer_timestamp),
4599 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
4602 if (demux->common.element_index) {
4603 if (stream->index_writer_id == -1)
4604 gst_index_get_writer_id (demux->common.element_index,
4605 GST_OBJECT (stream->pad), &stream->index_writer_id);
4607 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4608 G_GUINT64_FORMAT " for writer id %d",
4609 GST_TIME_ARGS (buffer_timestamp), cluster_offset,
4610 stream->index_writer_id);
4611 gst_index_add_association (demux->common.element_index,
4612 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
4613 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
4614 GST_FORMAT_TIME, buffer_timestamp, GST_FORMAT_BYTES, cluster_offset,
4619 /* Postprocess the buffers depending on the codec used */
4620 if (stream->postprocess_frame) {
4621 GST_LOG_OBJECT (demux, "running post process");
4622 ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
4625 /* At this point, we have a sub-buffer pointing at data within a larger
4626 buffer. This data might not be aligned with anything. If the data is
4627 raw samples though, we want it aligned to the raw type (eg, 4 bytes
4628 for 32 bit samples, etc), or bad things will happen downstream as
4629 elements typically assume minimal alignment.
4630 Therefore, create an aligned copy if necessary. */
4631 sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
4633 if (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
4634 guint64 start_clip = 0, end_clip = 0;
4636 /* Codec delay is part of the timestamps */
4637 if (GST_BUFFER_PTS_IS_VALID (sub) && stream->codec_delay) {
4638 if (GST_BUFFER_PTS (sub) > stream->codec_delay) {
4639 GST_BUFFER_PTS (sub) -= stream->codec_delay;
4641 GST_BUFFER_PTS (sub) = 0;
4643 /* Opus GstAudioClippingMeta units are scaled by 48000/sample_rate.
4644 That is, if a Opus track has audio encoded at 24000 Hz and 132
4645 samples need to be clipped, GstAudioClippingMeta.start will be
4646 set to 264. (This is also the case for buffer offsets.)
4647 Opus sample rates are always divisors of 48000 Hz, which is the
4648 maximum allowed sample rate. */
4650 gst_util_uint64_scale_round (stream->codec_delay, 48000,
4653 if (GST_BUFFER_DURATION_IS_VALID (sub)) {
4654 if (GST_BUFFER_DURATION (sub) > stream->codec_delay)
4655 GST_BUFFER_DURATION (sub) -= stream->codec_delay;
4657 GST_BUFFER_DURATION (sub) = 0;
4662 if (block_discardpadding) {
4664 gst_util_uint64_scale_round (block_discardpadding, 48000,
4668 if (start_clip || end_clip) {
4669 gst_buffer_add_audio_clipping_meta (sub, GST_FORMAT_DEFAULT,
4670 start_clip, end_clip);
4674 if (GST_BUFFER_PTS_IS_VALID (sub)) {
4675 stream->pos = GST_BUFFER_PTS (sub);
4676 if (GST_BUFFER_DURATION_IS_VALID (sub))
4677 stream->pos += GST_BUFFER_DURATION (sub);
4678 } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
4679 stream->pos = GST_BUFFER_DTS (sub);
4680 if (GST_BUFFER_DURATION_IS_VALID (sub))
4681 stream->pos += GST_BUFFER_DURATION (sub);
4684 ret = gst_pad_push (stream->pad, sub);
4686 if (demux->common.segment.rate < 0) {
4687 if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
4688 /* In reverse playback we can get a GST_FLOW_EOS when
4689 * we are at the end of the segment, so we just need to jump
4690 * back to the previous section. */
4691 GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
4696 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
4700 size -= lace_size[n];
4701 if (lace_time != GST_CLOCK_TIME_NONE && duration)
4702 lace_time += duration / laces;
4704 lace_time = GST_CLOCK_TIME_NONE;
4710 gst_buffer_unmap (buf, &map);
4711 gst_buffer_unref (buf);
4723 ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
4729 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
4730 /* non-fatal, try next block(group) */
4736 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
4737 /* non-fatal, try next block(group) */
4743 /* return FALSE if block(group) should be skipped (due to a seek) */
4744 static inline gboolean
4745 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
4747 if (G_UNLIKELY (demux->seek_block)) {
4748 if (!(--demux->seek_block)) {
4751 GST_LOG_OBJECT (demux, "should skip block due to seek");
4759 static GstFlowReturn
4760 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
4764 guint64 seek_pos = (guint64) - 1;
4765 guint32 seek_id = 0;
4768 DEBUG_ELEMENT_START (demux, ebml, "Seek");
4770 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4771 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4775 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4776 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4780 case GST_MATROSKA_ID_SEEKID:
4784 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4787 GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
4792 case GST_MATROSKA_ID_SEEKPOSITION:
4796 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4799 if (t > G_MAXINT64) {
4800 GST_WARNING_OBJECT (demux,
4801 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
4805 GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
4811 ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
4817 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
4820 if (!seek_id || seek_pos == (guint64) - 1) {
4821 GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
4822 G_GUINT64_FORMAT ")", seek_id, seek_pos);
4827 case GST_MATROSKA_ID_SEEKHEAD:
4830 case GST_MATROSKA_ID_CUES:
4831 case GST_MATROSKA_ID_TAGS:
4832 case GST_MATROSKA_ID_TRACKS:
4833 case GST_MATROSKA_ID_SEGMENTINFO:
4834 case GST_MATROSKA_ID_ATTACHMENTS:
4835 case GST_MATROSKA_ID_CHAPTERS:
4837 guint64 before_pos, length;
4841 length = gst_matroska_read_common_get_length (&demux->common);
4842 before_pos = demux->common.offset;
4844 if (length == (guint64) - 1) {
4845 GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
4849 /* check for validity */
4850 if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
4851 GST_WARNING_OBJECT (demux,
4852 "SeekHead reference lies outside file!" " (%"
4853 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
4854 G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
4859 /* only pick up index location when streaming */
4860 if (demux->streaming) {
4861 if (seek_id == GST_MATROSKA_ID_CUES) {
4862 demux->index_offset = seek_pos + demux->common.ebml_segment_start;
4863 GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
4864 demux->index_offset);
4870 demux->common.offset = seek_pos + demux->common.ebml_segment_start;
4873 if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4874 GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
4878 if (id != seek_id) {
4879 GST_WARNING_OBJECT (demux,
4880 "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
4881 seek_id, id, seek_pos + demux->common.ebml_segment_start);
4884 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4889 demux->common.offset = before_pos;
4893 case GST_MATROSKA_ID_CLUSTER:
4895 guint64 pos = seek_pos + demux->common.ebml_segment_start;
4897 GST_LOG_OBJECT (demux, "Cluster position");
4898 if (G_UNLIKELY (!demux->clusters))
4899 demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
4900 g_array_append_val (demux->clusters, pos);
4905 GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
4908 DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4913 static GstFlowReturn
4914 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4916 GstFlowReturn ret = GST_FLOW_OK;
4919 DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4921 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4922 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4926 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4927 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4931 case GST_MATROSKA_ID_SEEKENTRY:
4933 ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
4934 /* Ignore EOS and errors here */
4935 if (ret != GST_FLOW_OK) {
4936 GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4943 ret = gst_matroska_read_common_parse_skip (&demux->common,
4944 ebml, "SeekHead", id);
4949 DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4951 /* Sort clusters by position for easier searching */
4952 if (demux->clusters)
4953 g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4958 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
4960 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4962 static inline GstFlowReturn
4963 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4965 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4966 /* only a few blocks are expected/allowed to be large,
4967 * and will be recursed into, whereas others will be read and must fit */
4968 if (demux->streaming) {
4969 /* fatal in streaming case, as we can't step over easily */
4970 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4971 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4972 "file might be corrupt.", bytes));
4973 return GST_FLOW_ERROR;
4975 /* indicate higher level to quietly give up */
4976 GST_DEBUG_OBJECT (demux,
4977 "too large block of size %" G_GUINT64_FORMAT, bytes);
4978 return GST_FLOW_ERROR;
4985 /* returns TRUE if we truely are in error state, and should give up */
4986 static inline GstFlowReturn
4987 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4989 if (!demux->streaming && demux->next_cluster_offset > 0) {
4990 /* just repositioning to where next cluster should be and try from there */
4991 GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4992 G_GUINT64_FORMAT, demux->next_cluster_offset);
4993 demux->common.offset = demux->next_cluster_offset;
4994 demux->next_cluster_offset = 0;
5000 /* sigh, one last attempt above and beyond call of duty ...;
5001 * search for cluster mark following current pos */
5002 pos = demux->common.offset;
5003 GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
5004 if ((ret = gst_matroska_demux_search_cluster (demux, &pos, TRUE)) !=
5006 /* did not work, give up */
5009 GST_DEBUG_OBJECT (demux, "... found at %" G_GUINT64_FORMAT, pos);
5010 /* try that position */
5011 demux->common.offset = pos;
5017 static inline GstFlowReturn
5018 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
5020 GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
5021 demux->common.offset += flush;
5022 if (demux->streaming) {
5025 /* hard to skip large blocks when streaming */
5026 ret = gst_matroska_demux_check_read_size (demux, flush);
5027 if (ret != GST_FLOW_OK)
5029 if (flush <= gst_adapter_available (demux->common.adapter))
5030 gst_adapter_flush (demux->common.adapter, flush);
5032 return GST_FLOW_EOS;
5037 /* initializes @ebml with @bytes from input stream at current offset.
5038 * Returns EOS if insufficient available,
5039 * ERROR if too much was attempted to read. */
5040 static inline GstFlowReturn
5041 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
5044 GstBuffer *buffer = NULL;
5045 GstFlowReturn ret = GST_FLOW_OK;
5047 GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
5049 ret = gst_matroska_demux_check_read_size (demux, bytes);
5050 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
5051 if (!demux->streaming) {
5052 /* in pull mode, we can skip */
5053 if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
5054 ret = GST_FLOW_OVERFLOW;
5056 /* otherwise fatal */
5057 ret = GST_FLOW_ERROR;
5061 if (demux->streaming) {
5062 if (gst_adapter_available (demux->common.adapter) >= bytes)
5063 buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
5067 ret = gst_matroska_read_common_peek_bytes (&demux->common,
5068 demux->common.offset, bytes, &buffer, NULL);
5069 if (G_LIKELY (buffer)) {
5070 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
5071 demux->common.offset);
5072 demux->common.offset += bytes;
5079 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
5082 gboolean seekable = FALSE;
5083 gint64 start = -1, stop = -1;
5085 query = gst_query_new_seeking (GST_FORMAT_BYTES);
5086 if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
5087 GST_DEBUG_OBJECT (demux, "seeking query failed");
5091 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
5093 /* try harder to query upstream size if we didn't get it the first time */
5094 if (seekable && stop == -1) {
5095 GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
5096 gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
5100 /* if upstream doesn't know the size, it's likely that it's not seekable in
5101 * practice even if it technically may be seekable */
5102 if (seekable && (start != 0 || stop <= start)) {
5103 GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
5108 GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
5109 G_GUINT64_FORMAT ")", seekable, start, stop);
5110 demux->seekable = seekable;
5112 gst_query_unref (query);
5115 static GstFlowReturn
5116 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
5122 GstFlowReturn ret = GST_FLOW_OK;
5124 GST_WARNING_OBJECT (demux,
5125 "Found Cluster element before Tracks, searching Tracks");
5128 before_pos = demux->common.offset;
5130 /* Search Tracks element */
5132 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
5133 GST_ELEMENT_CAST (demux), &id, &length, &needed);
5134 if (ret != GST_FLOW_OK)
5137 if (id != GST_MATROSKA_ID_TRACKS) {
5138 /* we may be skipping large cluster here, so forego size check etc */
5139 /* ... but we can't skip undefined size; force error */
5140 if (length == G_MAXUINT64) {
5141 ret = gst_matroska_demux_check_read_size (demux, length);
5144 demux->common.offset += needed;
5145 demux->common.offset += length;
5150 /* will lead to track parsing ... */
5151 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5156 demux->common.offset = before_pos;
5161 #define GST_READ_CHECK(stmt) \
5163 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
5164 if (ret == GST_FLOW_OVERFLOW) { \
5165 ret = GST_FLOW_OK; \
5171 static GstFlowReturn
5172 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
5173 guint64 length, guint needed)
5175 GstEbmlRead ebml = { 0, };
5176 GstFlowReturn ret = GST_FLOW_OK;
5179 GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
5180 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
5182 /* if we plan to read and parse this element, we need prefix (id + length)
5183 * and the contents */
5184 /* mind about overflow wrap-around when dealing with undefined size */
5186 if (G_LIKELY (length != G_MAXUINT64))
5189 switch (demux->common.state) {
5190 case GST_MATROSKA_READ_STATE_START:
5192 case GST_EBML_ID_HEADER:
5193 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5194 ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
5195 if (ret != GST_FLOW_OK)
5197 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
5198 gst_matroska_demux_check_seekability (demux);
5201 goto invalid_header;
5205 case GST_MATROSKA_READ_STATE_SEGMENT:
5207 case GST_MATROSKA_ID_SEGMENT:
5208 /* eat segment prefix */
5209 GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
5210 GST_DEBUG_OBJECT (demux,
5211 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
5212 G_GUINT64_FORMAT, demux->common.offset, length);
5213 /* seeks are from the beginning of the segment,
5214 * after the segment ID/length */
5215 demux->common.ebml_segment_start = demux->common.offset;
5217 length = G_MAXUINT64;
5218 demux->common.ebml_segment_length = length;
5219 demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
5222 GST_WARNING_OBJECT (demux,
5223 "Expected a Segment ID (0x%x), but received 0x%x!",
5224 GST_MATROSKA_ID_SEGMENT, id);
5225 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5229 case GST_MATROSKA_READ_STATE_SCANNING:
5230 if (id != GST_MATROSKA_ID_CLUSTER &&
5231 id != GST_MATROSKA_ID_PREVSIZE &&
5232 id != GST_MATROSKA_ID_CLUSTERTIMECODE) {
5233 if (demux->common.start_resync_offset != -1) {
5234 /* we need to skip byte per byte if we are scanning for a new cluster
5235 * after invalid data is found
5241 if (demux->common.start_resync_offset != -1) {
5242 GST_LOG_OBJECT (demux, "Resync done, new cluster found!");
5243 demux->common.start_resync_offset = -1;
5244 demux->common.state = demux->common.state_to_restore;
5248 case GST_MATROSKA_READ_STATE_HEADER:
5249 case GST_MATROSKA_READ_STATE_DATA:
5250 case GST_MATROSKA_READ_STATE_SEEK:
5252 case GST_EBML_ID_HEADER:
5253 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5254 demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
5255 gst_matroska_demux_check_seekability (demux);
5257 case GST_MATROSKA_ID_SEGMENTINFO:
5258 if (!demux->common.segmentinfo_parsed) {
5259 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5260 ret = gst_matroska_read_common_parse_info (&demux->common,
5261 GST_ELEMENT_CAST (demux), &ebml);
5262 if (ret == GST_FLOW_OK)
5263 gst_matroska_demux_send_tags (demux);
5265 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5268 case GST_MATROSKA_ID_TRACKS:
5269 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5270 if (!demux->tracks_parsed) {
5271 ret = gst_matroska_demux_parse_tracks (demux, &ebml);
5273 ret = gst_matroska_demux_update_tracks (demux, &ebml);
5276 case GST_MATROSKA_ID_CLUSTER:
5277 if (G_UNLIKELY (!demux->tracks_parsed)) {
5278 if (demux->streaming) {
5279 GST_DEBUG_OBJECT (demux, "Cluster before Track");
5280 goto not_streamable;
5282 ret = gst_matroska_demux_find_tracks (demux);
5283 if (!demux->tracks_parsed)
5287 if (demux->common.state == GST_MATROSKA_READ_STATE_HEADER) {
5288 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
5289 demux->first_cluster_offset = demux->common.offset;
5291 if (!demux->streaming &&
5292 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.duration)) {
5293 GstMatroskaIndex *last = NULL;
5295 GST_DEBUG_OBJECT (demux,
5296 "estimating duration using last cluster");
5297 if ((last = gst_matroska_demux_search_pos (demux,
5298 GST_CLOCK_TIME_NONE)) != NULL) {
5299 demux->last_cluster_offset =
5300 last->pos + demux->common.ebml_segment_start;
5301 demux->stream_last_time = last->time;
5302 demux->common.segment.duration =
5303 demux->stream_last_time - demux->stream_start_time;
5304 /* above estimate should not be taken all too strongly */
5305 demux->invalid_duration = TRUE;
5306 GST_DEBUG_OBJECT (demux,
5307 "estimated duration as %" GST_TIME_FORMAT,
5308 GST_TIME_ARGS (demux->common.segment.duration));
5312 /* Peek at second cluster in order to figure out if we have cluster
5313 * prev_size or not (which is never set on the first cluster for
5314 * obvious reasons). This is useful in case someone initiates a
5315 * seek or direction change before we reach the second cluster. */
5316 if (!demux->streaming) {
5317 ClusterInfo cluster = { 0, };
5319 if (gst_matroska_demux_peek_cluster_info (demux, &cluster,
5320 demux->first_cluster_offset) && cluster.size > 0) {
5321 gst_matroska_demux_peek_cluster_info (demux, &cluster,
5322 demux->first_cluster_offset + cluster.size);
5324 demux->common.offset = demux->first_cluster_offset;
5327 /* send initial segment - we wait till we know the first
5328 incoming timestamp, so we can properly set the start of
5330 demux->need_segment = TRUE;
5332 demux->cluster_time = GST_CLOCK_TIME_NONE;
5333 demux->cluster_offset = demux->common.offset;
5334 demux->cluster_prevsize = 0;
5335 if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
5336 GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
5337 " not found in Cluster, trying next Cluster's first block instead",
5339 demux->seek_block = 0;
5341 demux->seek_first = FALSE;
5342 /* record next cluster for recovery */
5343 if (read != G_MAXUINT64)
5344 demux->next_cluster_offset = demux->cluster_offset + read;
5345 /* eat cluster prefix */
5346 gst_matroska_demux_flush (demux, needed);
5348 case GST_MATROSKA_ID_CLUSTERTIMECODE:
5352 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5353 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
5355 GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
5356 demux->cluster_time = num;
5357 /* track last cluster */
5358 if (demux->cluster_offset > demux->last_cluster_offset) {
5359 demux->last_cluster_offset = demux->cluster_offset;
5360 demux->stream_last_time =
5361 demux->cluster_time * demux->common.time_scale;
5364 if (demux->common.element_index) {
5365 if (demux->common.element_index_writer_id == -1)
5366 gst_index_get_writer_id (demux->common.element_index,
5367 GST_OBJECT (demux), &demux->common.element_index_writer_id);
5368 GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
5369 G_GUINT64_FORMAT " for writer id %d",
5370 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
5371 demux->common.element_index_writer_id);
5372 gst_index_add_association (demux->common.element_index,
5373 demux->common.element_index_writer_id,
5374 GST_ASSOCIATION_FLAG_KEY_UNIT,
5375 GST_FORMAT_TIME, demux->cluster_time,
5376 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
5381 case GST_MATROSKA_ID_BLOCKGROUP:
5382 if (!gst_matroska_demux_seek_block (demux))
5384 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5385 DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
5386 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
5387 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
5388 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
5390 DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
5392 case GST_MATROSKA_ID_SIMPLEBLOCK:
5393 if (!gst_matroska_demux_seek_block (demux))
5395 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5396 DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
5397 ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
5398 &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
5399 DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
5401 case GST_MATROSKA_ID_ATTACHMENTS:
5402 if (!demux->common.attachments_parsed) {
5403 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5404 ret = gst_matroska_read_common_parse_attachments (&demux->common,
5405 GST_ELEMENT_CAST (demux), &ebml);
5406 if (ret == GST_FLOW_OK)
5407 gst_matroska_demux_send_tags (demux);
5409 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5412 case GST_MATROSKA_ID_TAGS:
5413 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5414 ret = gst_matroska_read_common_parse_metadata (&demux->common,
5415 GST_ELEMENT_CAST (demux), &ebml);
5416 if (ret == GST_FLOW_OK)
5417 gst_matroska_demux_send_tags (demux);
5419 case GST_MATROSKA_ID_CHAPTERS:
5420 if (!demux->common.chapters_parsed) {
5421 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5423 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
5425 if (demux->common.toc) {
5426 gst_matroska_demux_send_event (demux,
5427 gst_event_new_toc (demux->common.toc, FALSE));
5430 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5432 case GST_MATROSKA_ID_SEEKHEAD:
5433 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5434 ret = gst_matroska_demux_parse_contents (demux, &ebml);
5436 case GST_MATROSKA_ID_CUES:
5437 if (demux->common.index_parsed) {
5438 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5441 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5442 ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
5443 /* only push based; delayed index building */
5444 if (ret == GST_FLOW_OK
5445 && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
5448 GST_OBJECT_LOCK (demux);
5449 event = demux->seek_event;
5450 demux->seek_event = NULL;
5451 GST_OBJECT_UNLOCK (demux);
5454 /* unlikely to fail, since we managed to seek to this point */
5455 if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
5456 gst_event_unref (event);
5459 gst_event_unref (event);
5460 /* resume data handling, main thread clear to seek again */
5461 GST_OBJECT_LOCK (demux);
5462 demux->common.state = GST_MATROSKA_READ_STATE_DATA;
5463 GST_OBJECT_UNLOCK (demux);
5466 case GST_MATROSKA_ID_PREVSIZE:{
5469 GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5470 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
5472 GST_LOG_OBJECT (demux, "ClusterPrevSize: %" G_GUINT64_FORMAT, num);
5473 demux->cluster_prevsize = num;
5474 demux->seen_cluster_prevsize = TRUE;
5477 case GST_MATROSKA_ID_POSITION:
5478 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
5479 /* The WebM doesn't support the EncryptedBlock element.
5480 * The Matroska spec doesn't give us more detail, how to parse this element,
5481 * for example the field TransformID isn't specified yet.*/
5482 case GST_MATROSKA_ID_SILENTTRACKS:
5483 GST_DEBUG_OBJECT (demux,
5484 "Skipping Cluster subelement 0x%x - ignoring", id);
5488 GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
5489 GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
5495 if (ret == GST_FLOW_PARSE)
5499 gst_ebml_read_clear (&ebml);
5505 /* simply exit, maybe not enough data yet */
5506 /* no ebml to clear if read error */
5511 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5512 ("Failed to parse Element 0x%x", id));
5513 ret = GST_FLOW_ERROR;
5518 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5519 ("File layout does not permit streaming"));
5520 ret = GST_FLOW_ERROR;
5525 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5526 ("No Tracks element found"));
5527 ret = GST_FLOW_ERROR;
5532 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
5533 ret = GST_FLOW_ERROR;
5538 GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
5539 ret = GST_FLOW_ERROR;
5545 gst_matroska_demux_loop (GstPad * pad)
5547 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
5553 /* If we have to close a segment, send a new segment to do this now */
5554 if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
5555 if (G_UNLIKELY (demux->new_segment)) {
5556 gst_matroska_demux_send_event (demux, demux->new_segment);
5557 demux->new_segment = NULL;
5561 ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
5562 GST_ELEMENT_CAST (demux), &id, &length, &needed);
5563 if (ret == GST_FLOW_EOS) {
5565 } else if (ret == GST_FLOW_FLUSHING) {
5567 } else if (ret != GST_FLOW_OK) {
5568 ret = gst_matroska_demux_check_parse_error (demux);
5570 /* Only handle EOS as no error if we're outside the segment already */
5571 if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
5572 && demux->common.offset >=
5573 demux->common.ebml_segment_start +
5574 demux->common.ebml_segment_length))
5576 else if (ret != GST_FLOW_OK)
5582 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
5583 "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
5586 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5587 if (ret == GST_FLOW_EOS)
5589 if (ret != GST_FLOW_OK)
5592 /* check if we're at the end of a configured segment */
5593 if (G_LIKELY (demux->common.src->len)) {
5596 g_assert (demux->common.num_streams == demux->common.src->len);
5597 for (i = 0; i < demux->common.src->len; i++) {
5598 GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
5600 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
5601 GST_TIME_ARGS (context->pos));
5602 if (context->eos == FALSE)
5606 GST_INFO_OBJECT (demux, "All streams are EOS");
5612 if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
5613 demux->common.offset >= demux->cached_length)) {
5614 demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
5615 if (demux->common.offset == demux->cached_length) {
5616 GST_LOG_OBJECT (demux, "Reached end of stream");
5627 if (demux->common.segment.rate < 0.0) {
5628 ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
5629 if (ret == GST_FLOW_OK)
5636 const gchar *reason = gst_flow_get_name (ret);
5637 gboolean push_eos = FALSE;
5639 GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
5640 gst_pad_pause_task (demux->common.sinkpad);
5642 if (ret == GST_FLOW_EOS) {
5643 /* perform EOS logic */
5645 /* If we were in the headers, make sure we send no-more-pads.
5646 This will ensure decodebin does not get stuck thinking
5647 the chain is not complete yet, and waiting indefinitely. */
5648 if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
5649 if (demux->common.src->len == 0) {
5650 GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
5651 ("No pads created"));
5653 GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
5654 ("Failed to finish reading headers"));
5656 gst_element_no_more_pads (GST_ELEMENT (demux));
5659 if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
5664 /* for segment playback we need to post when (in stream time)
5665 * we stopped, this is either stop (when set) or the duration. */
5666 if ((stop = demux->common.segment.stop) == -1)
5667 stop = demux->last_stop_end;
5669 GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
5670 msg = gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
5672 if (demux->segment_seqnum)
5673 gst_message_set_seqnum (msg, demux->segment_seqnum);
5674 gst_element_post_message (GST_ELEMENT (demux), msg);
5676 event = gst_event_new_segment_done (GST_FORMAT_TIME, stop);
5677 if (demux->segment_seqnum)
5678 gst_event_set_seqnum (event, demux->segment_seqnum);
5679 gst_matroska_demux_send_event (demux, event);
5683 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
5684 /* for fatal errors we post an error message */
5685 GST_ELEMENT_FLOW_ERROR (demux, ret);
5691 /* send EOS, and prevent hanging if no streams yet */
5692 GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
5693 event = gst_event_new_eos ();
5694 if (demux->segment_seqnum)
5695 gst_event_set_seqnum (event, demux->segment_seqnum);
5696 if (!gst_matroska_demux_send_event (demux, event) &&
5697 (ret == GST_FLOW_EOS)) {
5698 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5699 (NULL), ("got eos but no streams (yet)"));
5707 * Create and push a flushing seek event upstream
5710 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
5711 guint32 seqnum, GstSeekFlags flags)
5716 GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
5719 gst_event_new_seek (rate, GST_FORMAT_BYTES,
5720 flags | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
5721 GST_SEEK_TYPE_SET, offset, GST_SEEK_TYPE_NONE, -1);
5722 gst_event_set_seqnum (event, seqnum);
5724 res = gst_pad_push_event (demux->common.sinkpad, event);
5726 /* segment event will update offset */
5730 static GstFlowReturn
5731 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
5733 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5735 GstFlowReturn ret = GST_FLOW_OK;
5740 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
5741 GST_DEBUG_OBJECT (demux, "got DISCONT");
5742 gst_adapter_clear (demux->common.adapter);
5743 GST_OBJECT_LOCK (demux);
5744 gst_matroska_read_common_reset_streams (&demux->common,
5745 GST_CLOCK_TIME_NONE, FALSE);
5746 GST_OBJECT_UNLOCK (demux);
5749 gst_adapter_push (demux->common.adapter, buffer);
5753 available = gst_adapter_available (demux->common.adapter);
5755 ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
5756 GST_ELEMENT_CAST (demux), &id, &length, &needed);
5757 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
5758 if (demux->common.ebml_segment_length != G_MAXUINT64
5759 && demux->common.offset >=
5760 demux->common.ebml_segment_start + demux->common.ebml_segment_length) {
5763 gint64 bytes_scanned;
5764 if (demux->common.start_resync_offset == -1) {
5765 demux->common.start_resync_offset = demux->common.offset;
5766 demux->common.state_to_restore = demux->common.state;
5768 bytes_scanned = demux->common.offset - demux->common.start_resync_offset;
5769 if (bytes_scanned <= INVALID_DATA_THRESHOLD) {
5770 GST_WARNING_OBJECT (demux,
5771 "parse error, looking for next cluster, actual offset %"
5772 G_GUINT64_FORMAT ", start resync offset %" G_GUINT64_FORMAT,
5773 demux->common.offset, demux->common.start_resync_offset);
5774 demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
5777 GST_WARNING_OBJECT (demux,
5778 "unrecoverable parse error, next cluster not found and threshold "
5779 "exceeded, bytes scanned %" G_GINT64_FORMAT, bytes_scanned);
5785 GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
5786 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
5787 demux->common.offset, id, length, needed, available);
5789 if (needed > available)
5792 ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5793 if (ret == GST_FLOW_EOS) {
5794 /* need more data */
5796 } else if (ret != GST_FLOW_OK) {
5803 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
5806 gboolean res = TRUE;
5807 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5809 GST_DEBUG_OBJECT (demux,
5810 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
5812 switch (GST_EVENT_TYPE (event)) {
5813 case GST_EVENT_SEGMENT:
5815 const GstSegment *segment;
5817 /* some debug output */
5818 gst_event_parse_segment (event, &segment);
5819 /* FIXME: do we need to update segment base here (like accum in 0.10)? */
5820 GST_DEBUG_OBJECT (demux,
5821 "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
5824 if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
5825 GST_DEBUG_OBJECT (demux, "still starting");
5829 /* we only expect a BYTE segment, e.g. following a seek */
5830 if (segment->format != GST_FORMAT_BYTES) {
5831 GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
5835 GST_DEBUG_OBJECT (demux, "clearing segment state");
5836 GST_OBJECT_LOCK (demux);
5837 /* clear current segment leftover */
5838 gst_adapter_clear (demux->common.adapter);
5839 /* and some streaming setup */
5840 demux->common.offset = segment->start;
5841 /* accumulate base based on current position */
5842 if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
5843 demux->common.segment.base +=
5844 (MAX (demux->common.segment.position, demux->stream_start_time)
5845 - demux->stream_start_time) / fabs (demux->common.segment.rate);
5846 /* do not know where we are;
5847 * need to come across a cluster and generate segment */
5848 demux->common.segment.position = GST_CLOCK_TIME_NONE;
5849 demux->cluster_time = GST_CLOCK_TIME_NONE;
5850 demux->cluster_offset = 0;
5851 demux->cluster_prevsize = 0;
5852 demux->need_segment = TRUE;
5853 demux->segment_seqnum = gst_event_get_seqnum (event);
5854 /* but keep some of the upstream segment */
5855 demux->common.segment.rate = segment->rate;
5856 demux->common.segment.flags = segment->flags;
5857 /* also check if need to keep some of the requested seek position */
5858 if (demux->seek_offset == segment->start) {
5859 GST_DEBUG_OBJECT (demux, "position matches requested seek");
5860 demux->common.segment.position = demux->requested_seek_time;
5862 GST_DEBUG_OBJECT (demux, "unexpected segment position");
5864 demux->requested_seek_time = GST_CLOCK_TIME_NONE;
5865 demux->seek_offset = -1;
5866 GST_OBJECT_UNLOCK (demux);
5868 /* chain will send initial segment after pads have been added,
5869 * or otherwise come up with one */
5870 GST_DEBUG_OBJECT (demux, "eating event");
5871 gst_event_unref (event);
5877 if (demux->common.state != GST_MATROSKA_READ_STATE_DATA
5878 && demux->common.state != GST_MATROSKA_READ_STATE_SCANNING) {
5879 gst_event_unref (event);
5880 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5881 (NULL), ("got eos and didn't receive a complete header object"));
5882 } else if (demux->common.num_streams == 0) {
5883 GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5884 (NULL), ("got eos but no streams (yet)"));
5886 gst_matroska_demux_send_event (demux, event);
5890 case GST_EVENT_FLUSH_STOP:
5894 gst_adapter_clear (demux->common.adapter);
5895 GST_OBJECT_LOCK (demux);
5896 gst_matroska_read_common_reset_streams (&demux->common,
5897 GST_CLOCK_TIME_NONE, TRUE);
5898 gst_flow_combiner_reset (demux->flowcombiner);
5899 dur = demux->common.segment.duration;
5900 gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
5901 demux->common.segment.duration = dur;
5902 demux->cluster_time = GST_CLOCK_TIME_NONE;
5903 demux->cluster_offset = 0;
5904 demux->cluster_prevsize = 0;
5905 GST_OBJECT_UNLOCK (demux);
5909 res = gst_pad_event_default (pad, parent, event);
5917 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
5919 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5921 gboolean pull_mode = FALSE;
5923 query = gst_query_new_scheduling ();
5925 if (gst_pad_peer_query (sinkpad, query))
5926 pull_mode = gst_query_has_scheduling_mode_with_flags (query,
5927 GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
5929 gst_query_unref (query);
5932 GST_DEBUG ("going to pull mode");
5933 demux->streaming = FALSE;
5934 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
5936 GST_DEBUG ("going to push (streaming) mode");
5937 demux->streaming = TRUE;
5938 return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
5943 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
5944 GstPadMode mode, gboolean active)
5947 case GST_PAD_MODE_PULL:
5949 /* if we have a scheduler we can start the task */
5950 gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
5953 gst_pad_stop_task (sinkpad);
5956 case GST_PAD_MODE_PUSH:
5964 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
5965 videocontext, const gchar * codec_id, guint8 * data, guint size,
5966 gchar ** codec_name, guint32 * riff_fourcc)
5968 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
5969 GstCaps *caps = NULL;
5971 g_assert (videocontext != NULL);
5972 g_assert (codec_name != NULL);
5977 /* TODO: check if we have all codec types from matroska-ids.h
5978 * check if we have to do more special things with codec_private
5981 * GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
5982 * GST_MATROSKA_CODEC_ID_VIDEO_SNOW
5985 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
5986 gst_riff_strf_vids *vids = NULL;
5989 GstBuffer *buf = NULL;
5991 vids = (gst_riff_strf_vids *) data;
5993 /* assure size is big enough */
5995 GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
5998 if (size < sizeof (gst_riff_strf_vids)) {
5999 vids = g_new (gst_riff_strf_vids, 1);
6000 memcpy (vids, data, size);
6003 context->dts_only = TRUE; /* VFW files only store DTS */
6005 /* little-endian -> byte-order */
6006 vids->size = GUINT32_FROM_LE (vids->size);
6007 vids->width = GUINT32_FROM_LE (vids->width);
6008 vids->height = GUINT32_FROM_LE (vids->height);
6009 vids->planes = GUINT16_FROM_LE (vids->planes);
6010 vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
6011 vids->compression = GUINT32_FROM_LE (vids->compression);
6012 vids->image_size = GUINT32_FROM_LE (vids->image_size);
6013 vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
6014 vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
6015 vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
6016 vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
6018 if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
6019 gsize offset = sizeof (gst_riff_strf_vids);
6022 gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
6023 size - offset), size - offset);
6027 *riff_fourcc = vids->compression;
6029 caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
6030 buf, NULL, codec_name);
6033 GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
6034 GST_FOURCC_ARGS (vids->compression));
6036 static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
6037 "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
6038 "video/x-compressed-yuv");
6039 context->intra_only =
6040 gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
6044 gst_buffer_unref (buf);
6046 if (vids != (gst_riff_strf_vids *) data)
6049 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
6051 GstVideoFormat format;
6053 gst_video_info_init (&info);
6054 switch (videocontext->fourcc) {
6055 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
6056 format = GST_VIDEO_FORMAT_I420;
6058 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
6059 format = GST_VIDEO_FORMAT_YUY2;
6061 case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
6062 format = GST_VIDEO_FORMAT_YV12;
6064 case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
6065 format = GST_VIDEO_FORMAT_UYVY;
6067 case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
6068 format = GST_VIDEO_FORMAT_AYUV;
6070 case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
6071 case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
6072 format = GST_VIDEO_FORMAT_GRAY8;
6074 case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
6075 format = GST_VIDEO_FORMAT_RGB;
6077 case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
6078 format = GST_VIDEO_FORMAT_BGR;
6081 GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
6082 GST_FOURCC_ARGS (videocontext->fourcc));
6086 context->intra_only = TRUE;
6088 gst_video_info_set_format (&info, format, videocontext->pixel_width,
6089 videocontext->pixel_height);
6090 caps = gst_video_info_to_caps (&info);
6091 *codec_name = gst_pb_utils_get_codec_description (caps);
6092 context->alignment = 32;
6093 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
6094 caps = gst_caps_new_simple ("video/x-divx",
6095 "divxversion", G_TYPE_INT, 4, NULL);
6096 *codec_name = g_strdup ("MPEG-4 simple profile");
6097 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
6098 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
6099 caps = gst_caps_new_simple ("video/mpeg",
6100 "mpegversion", G_TYPE_INT, 4,
6101 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
6105 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
6106 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6107 gst_buffer_unref (priv);
6109 gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
6111 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
6112 *codec_name = g_strdup ("MPEG-4 advanced simple profile");
6114 *codec_name = g_strdup ("MPEG-4 advanced profile");
6115 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
6117 caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
6118 "divxversion", G_TYPE_INT, 3, NULL),
6119 gst_structure_new ("video/x-msmpeg",
6120 "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
6122 caps = gst_caps_new_simple ("video/x-msmpeg",
6123 "msmpegversion", G_TYPE_INT, 43, NULL);
6124 *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
6125 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
6126 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
6129 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
6134 caps = gst_caps_new_simple ("video/mpeg",
6135 "systemstream", G_TYPE_BOOLEAN, FALSE,
6136 "mpegversion", G_TYPE_INT, mpegversion, NULL);
6137 *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
6138 context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
6139 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
6140 caps = gst_caps_new_empty_simple ("image/jpeg");
6141 *codec_name = g_strdup ("Motion-JPEG");
6142 context->intra_only = TRUE;
6143 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
6144 caps = gst_caps_new_empty_simple ("video/x-h264");
6148 /* First byte is the version, second is the profile indication, and third
6149 * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
6150 * level indication. */
6151 gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
6154 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
6155 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6156 gst_buffer_unref (priv);
6158 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
6159 "alignment", G_TYPE_STRING, "au", NULL);
6161 GST_WARNING ("No codec data found, assuming output is byte-stream");
6162 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
6165 *codec_name = g_strdup ("H264");
6166 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
6167 caps = gst_caps_new_empty_simple ("video/x-h265");
6171 gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
6174 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
6175 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6176 gst_buffer_unref (priv);
6178 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
6179 "alignment", G_TYPE_STRING, "au", NULL);
6181 GST_WARNING ("No codec data found, assuming output is byte-stream");
6182 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
6185 *codec_name = g_strdup ("HEVC");
6186 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
6187 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
6188 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
6189 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
6190 gint rmversion = -1;
6192 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
6194 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
6196 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
6198 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
6201 caps = gst_caps_new_simple ("video/x-pn-realvideo",
6202 "rmversion", G_TYPE_INT, rmversion, NULL);
6203 GST_DEBUG ("data:%p, size:0x%x", data, size);
6204 /* We need to extract the extradata ! */
6205 if (data && (size >= 0x22)) {
6210 subformat = GST_READ_UINT32_BE (data + 0x1a);
6211 rformat = GST_READ_UINT32_BE (data + 0x1e);
6214 gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
6216 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
6217 G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
6218 gst_buffer_unref (priv);
6221 *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
6222 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
6223 caps = gst_caps_new_empty_simple ("video/x-theora");
6224 context->stream_headers =
6225 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6226 context->codec_priv_size);
6227 /* FIXME: mark stream as broken and skip if there are no stream headers */
6228 context->send_stream_headers = TRUE;
6229 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
6230 caps = gst_caps_new_empty_simple ("video/x-dirac");
6231 *codec_name = g_strdup_printf ("Dirac");
6232 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
6233 caps = gst_caps_new_empty_simple ("video/x-vp8");
6234 *codec_name = g_strdup_printf ("On2 VP8");
6235 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
6236 caps = gst_caps_new_empty_simple ("video/x-vp9");
6237 *codec_name = g_strdup_printf ("On2 VP9");
6238 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_AV1)) {
6239 caps = gst_caps_new_empty_simple ("video/x-av1");
6243 priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
6244 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6245 gst_buffer_unref (priv);
6247 GST_WARNING ("No codec data found, assuming output is byte-stream");
6248 gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
6251 *codec_name = g_strdup_printf ("AOM AV1");
6252 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
6254 const gchar *variant, *variant_descr = "";
6256 /* Expect a fourcc in the codec private data */
6257 if (!data || size < 4) {
6258 GST_WARNING ("No or too small PRORESS fourcc (%d bytes)", size);
6262 fourcc = GST_STR_FOURCC (data);
6264 case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
6265 variant_descr = " 4:2:2 LT";
6268 case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
6270 variant_descr = " 4:2:2 HQ";
6272 case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
6274 variant_descr = " 4:4:4:4";
6276 case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
6278 variant_descr = " 4:2:2 Proxy";
6280 case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
6282 variant = "standard";
6283 variant_descr = " 4:2:2 SD";
6287 GST_LOG ("Prores video, codec fourcc %" GST_FOURCC_FORMAT,
6288 GST_FOURCC_ARGS (fourcc));
6290 caps = gst_caps_new_simple ("video/x-prores",
6291 "format", G_TYPE_STRING, variant, NULL);
6292 *codec_name = g_strdup_printf ("Apple ProRes%s", variant_descr);
6293 context->postprocess_frame = gst_matroska_demux_add_prores_header;
6295 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6301 GstStructure *structure;
6303 for (i = 0; i < gst_caps_get_size (caps); i++) {
6304 structure = gst_caps_get_structure (caps, i);
6306 /* FIXME: use the real unit here! */
6307 GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
6308 videocontext->pixel_width,
6309 videocontext->pixel_height,
6310 videocontext->display_width, videocontext->display_height);
6312 /* pixel width and height are the w and h of the video in pixels */
6313 if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
6314 gint w = videocontext->pixel_width;
6315 gint h = videocontext->pixel_height;
6317 gst_structure_set (structure,
6318 "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
6321 if (videocontext->display_width > 0 || videocontext->display_height > 0) {
6324 if (videocontext->display_width <= 0)
6325 videocontext->display_width = videocontext->pixel_width;
6326 if (videocontext->display_height <= 0)
6327 videocontext->display_height = videocontext->pixel_height;
6329 /* calculate the pixel aspect ratio using the display and pixel w/h */
6330 n = videocontext->display_width * videocontext->pixel_height;
6331 d = videocontext->display_height * videocontext->pixel_width;
6332 GST_DEBUG ("setting PAR to %d/%d", n, d);
6333 gst_structure_set (structure, "pixel-aspect-ratio",
6335 videocontext->display_width * videocontext->pixel_height,
6336 videocontext->display_height * videocontext->pixel_width, NULL);
6339 if (videocontext->default_fps > 0.0) {
6342 gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
6344 GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
6346 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
6348 } else if (context->default_duration > 0) {
6351 gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
6353 GST_INFO ("using default duration %" G_GUINT64_FORMAT
6354 " framerate %d/%d", context->default_duration, fps_n, fps_d);
6356 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
6357 fps_n, fps_d, NULL);
6359 gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
6363 switch (videocontext->interlace_mode) {
6364 case GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE:
6365 gst_structure_set (structure,
6366 "interlace-mode", G_TYPE_STRING, "progressive", NULL);
6368 case GST_MATROSKA_INTERLACE_MODE_INTERLACED:
6369 gst_structure_set (structure,
6370 "interlace-mode", G_TYPE_STRING, "mixed", NULL);
6376 if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
6377 if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
6378 videocontext->pixel_width, videocontext->pixel_height,
6379 videocontext->display_width * videocontext->pixel_height,
6380 videocontext->display_height * videocontext->pixel_width)) {
6381 videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
6383 gst_caps_set_simple (caps,
6384 "multiview-mode", G_TYPE_STRING,
6385 gst_video_multiview_mode_to_caps_string
6386 (videocontext->multiview_mode), "multiview-flags",
6387 GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
6388 GST_FLAG_SET_MASK_EXACT, NULL);
6391 if (videocontext->colorimetry.range != GST_VIDEO_COLOR_RANGE_UNKNOWN ||
6392 videocontext->colorimetry.matrix != GST_VIDEO_COLOR_MATRIX_UNKNOWN ||
6393 videocontext->colorimetry.transfer != GST_VIDEO_TRANSFER_UNKNOWN ||
6394 videocontext->colorimetry.primaries !=
6395 GST_VIDEO_COLOR_PRIMARIES_UNKNOWN) {
6396 gchar *colorimetry =
6397 gst_video_colorimetry_to_string (&videocontext->colorimetry);
6398 gst_caps_set_simple (caps, "colorimetry", G_TYPE_STRING, colorimetry,
6400 GST_DEBUG ("setting colorimetry to %s", colorimetry);
6401 g_free (colorimetry);
6404 caps = gst_caps_simplify (caps);
6411 * Some AAC specific code... *sigh*
6412 * FIXME: maybe we should use '15' and code the sample rate explicitly
6413 * if the sample rate doesn't match the predefined rates exactly? (tpm)
6417 aac_rate_idx (gint rate)
6421 else if (75132 <= rate)
6423 else if (55426 <= rate)
6425 else if (46009 <= rate)
6427 else if (37566 <= rate)
6429 else if (27713 <= rate)
6431 else if (23004 <= rate)
6433 else if (18783 <= rate)
6435 else if (13856 <= rate)
6437 else if (11502 <= rate)
6439 else if (9391 <= rate)
6446 aac_profile_idx (const gchar * codec_id)
6450 if (strlen (codec_id) <= 12)
6452 else if (!strncmp (&codec_id[12], "MAIN", 4))
6454 else if (!strncmp (&codec_id[12], "LC", 2))
6456 else if (!strncmp (&codec_id[12], "SSR", 3))
6465 round_up_pow2 (guint n)
6476 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
6479 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
6480 audiocontext, const gchar * codec_id, guint8 * data, guint size,
6481 gchar ** codec_name, guint16 * riff_audio_fmt)
6483 GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
6484 GstCaps *caps = NULL;
6486 g_assert (audiocontext != NULL);
6487 g_assert (codec_name != NULL);
6490 *riff_audio_fmt = 0;
6492 /* TODO: check if we have all codec types from matroska-ids.h
6493 * check if we have to do more special things with codec_private
6494 * check if we need bitdepth in different places too
6495 * implement channel position magic
6497 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
6498 * GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
6499 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
6500 * GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
6503 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
6504 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
6505 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
6508 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
6510 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
6515 caps = gst_caps_new_simple ("audio/mpeg",
6516 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
6517 *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
6518 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
6519 !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
6522 GstAudioFormat format;
6524 sign = (audiocontext->bitdepth != 8);
6525 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
6526 endianness = G_BIG_ENDIAN;
6528 endianness = G_LITTLE_ENDIAN;
6530 format = gst_audio_format_build_integer (sign, endianness,
6531 audiocontext->bitdepth, audiocontext->bitdepth);
6533 /* FIXME: Channel mask and reordering */
6534 caps = gst_caps_new_simple ("audio/x-raw",
6535 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
6536 "layout", G_TYPE_STRING, "interleaved",
6537 "channel-mask", GST_TYPE_BITMASK,
6538 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
6540 *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
6541 audiocontext->bitdepth);
6542 context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
6543 context->alignment = round_up_pow2 (context->alignment);
6544 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
6545 const gchar *format;
6546 if (audiocontext->bitdepth == 32)
6550 /* FIXME: Channel mask and reordering */
6551 caps = gst_caps_new_simple ("audio/x-raw",
6552 "format", G_TYPE_STRING, format,
6553 "layout", G_TYPE_STRING, "interleaved",
6554 "channel-mask", GST_TYPE_BITMASK,
6555 gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
6556 *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
6557 audiocontext->bitdepth);
6558 context->alignment = audiocontext->bitdepth / 8;
6559 context->alignment = round_up_pow2 (context->alignment);
6560 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
6561 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
6562 caps = gst_caps_new_simple ("audio/x-ac3",
6563 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6564 *codec_name = g_strdup ("AC-3 audio");
6565 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
6566 strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
6567 caps = gst_caps_new_simple ("audio/x-eac3",
6568 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6569 *codec_name = g_strdup ("E-AC-3 audio");
6570 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
6571 strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
6572 caps = gst_caps_new_empty_simple ("audio/x-true-hd");
6573 *codec_name = g_strdup ("Dolby TrueHD");
6574 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
6575 caps = gst_caps_new_empty_simple ("audio/x-dts");
6576 *codec_name = g_strdup ("DTS audio");
6577 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
6578 caps = gst_caps_new_empty_simple ("audio/x-vorbis");
6579 context->stream_headers =
6580 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6581 context->codec_priv_size);
6582 /* FIXME: mark stream as broken and skip if there are no stream headers */
6583 context->send_stream_headers = TRUE;
6584 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
6585 caps = gst_caps_new_empty_simple ("audio/x-flac");
6586 context->stream_headers =
6587 gst_matroska_parse_flac_stream_headers (context->codec_priv,
6588 context->codec_priv_size);
6589 /* FIXME: mark stream as broken and skip if there are no stream headers */
6590 context->send_stream_headers = TRUE;
6591 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
6592 caps = gst_caps_new_empty_simple ("audio/x-speex");
6593 context->stream_headers =
6594 gst_matroska_parse_speex_stream_headers (context->codec_priv,
6595 context->codec_priv_size);
6596 /* FIXME: mark stream as broken and skip if there are no stream headers */
6597 context->send_stream_headers = TRUE;
6598 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
6601 if (context->codec_priv_size >= 19) {
6602 if (audiocontext->samplerate)
6603 GST_WRITE_UINT32_LE ((guint8 *) context->codec_priv + 12,
6604 audiocontext->samplerate);
6605 if (context->codec_delay) {
6607 gst_util_uint64_scale_round (context->codec_delay, 48000,
6609 GST_WRITE_UINT16_LE ((guint8 *) context->codec_priv + 10, delay);
6613 gst_buffer_new_wrapped (g_memdup (context->codec_priv,
6614 context->codec_priv_size), context->codec_priv_size);
6615 caps = gst_codec_utils_opus_create_caps_from_header (tmp, NULL);
6616 gst_buffer_unref (tmp);
6617 *codec_name = g_strdup ("Opus");
6618 } else if (context->codec_priv_size == 0) {
6619 GST_WARNING ("No Opus codec data found, trying to create one");
6620 if (audiocontext->channels <= 2) {
6621 guint8 streams, coupled, channels;
6625 audiocontext->samplerate == 0 ? 48000 : audiocontext->samplerate;
6626 channels = audiocontext->channels == 0 ? 2 : audiocontext->channels;
6627 if (channels == 1) {
6636 gst_codec_utils_opus_create_caps (samplerate, channels, 0, streams,
6639 *codec_name = g_strdup ("Opus");
6641 GST_WARNING ("Failed to create Opus caps from audio context");
6644 GST_WARNING ("No Opus codec data, and not enough info to create one");
6647 GST_WARNING ("Invalid Opus codec data size (got %" G_GSIZE_FORMAT
6648 ", expected 19)", context->codec_priv_size);
6650 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
6651 gst_riff_strf_auds auds;
6653 if (data && size >= 18) {
6654 GstBuffer *codec_data = NULL;
6656 /* little-endian -> byte-order */
6657 auds.format = GST_READ_UINT16_LE (data);
6658 auds.channels = GST_READ_UINT16_LE (data + 2);
6659 auds.rate = GST_READ_UINT32_LE (data + 4);
6660 auds.av_bps = GST_READ_UINT32_LE (data + 8);
6661 auds.blockalign = GST_READ_UINT16_LE (data + 12);
6662 auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
6664 /* 18 is the waveformatex size */
6666 codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
6667 data + 18, size - 18, 0, size - 18, NULL, NULL);
6671 *riff_audio_fmt = auds.format;
6673 /* FIXME: Handle reorder map */
6674 caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
6675 codec_data, codec_name, NULL);
6677 gst_buffer_unref (codec_data);
6680 GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
6683 GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
6685 } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
6686 GstBuffer *priv = NULL;
6688 gint rate_idx, profile;
6689 guint8 *data = NULL;
6691 /* unspecified AAC profile with opaque private codec data */
6692 if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
6693 if (context->codec_priv_size >= 2) {
6694 guint obj_type, freq_index, explicit_freq_bytes = 0;
6696 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6698 freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
6699 obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
6700 if (freq_index == 15)
6701 explicit_freq_bytes = 3;
6702 GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
6703 priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
6704 context->codec_priv_size), context->codec_priv_size);
6705 /* assume SBR if samplerate <= 24kHz */
6706 if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
6707 (context->codec_priv_size == (5 + explicit_freq_bytes))) {
6708 audiocontext->samplerate *= 2;
6711 GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
6712 /* this is pretty broken;
6713 * maybe we need to make up some default private,
6714 * or maybe ADTS data got dumped in.
6715 * Let's set up some private data now, and check actual data later */
6716 /* just try this and see what happens ... */
6717 codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6718 context->postprocess_frame = gst_matroska_demux_check_aac;
6722 /* make up decoder-specific data if it is not supplied */
6726 priv = gst_buffer_new_allocate (NULL, 5, NULL);
6727 gst_buffer_map (priv, &map, GST_MAP_WRITE);
6729 rate_idx = aac_rate_idx (audiocontext->samplerate);
6730 profile = aac_profile_idx (codec_id);
6732 data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
6733 data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
6735 if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
6736 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
6738 gst_buffer_unmap (priv, &map);
6739 gst_buffer_set_size (priv, 2);
6740 } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
6741 strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
6744 if (g_strrstr (codec_id, "SBR")) {
6745 /* HE-AAC (aka SBR AAC) */
6746 audiocontext->samplerate *= 2;
6747 rate_idx = aac_rate_idx (audiocontext->samplerate);
6748 data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
6749 data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
6750 data[4] = (1 << 7) | (rate_idx << 3);
6751 gst_buffer_unmap (priv, &map);
6753 gst_buffer_unmap (priv, &map);
6754 gst_buffer_set_size (priv, 2);
6757 gst_buffer_unmap (priv, &map);
6758 gst_buffer_unref (priv);
6760 GST_ERROR ("Unknown AAC profile and no codec private data");
6765 caps = gst_caps_new_simple ("audio/mpeg",
6766 "mpegversion", G_TYPE_INT, mpegversion,
6767 "framed", G_TYPE_BOOLEAN, TRUE,
6768 "stream-format", G_TYPE_STRING, "raw", NULL);
6769 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6770 if (context->codec_priv && context->codec_priv_size > 0)
6771 gst_codec_utils_aac_caps_set_level_and_profile (caps,
6772 context->codec_priv, context->codec_priv_size);
6773 *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
6774 gst_buffer_unref (priv);
6776 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
6777 caps = gst_caps_new_simple ("audio/x-tta",
6778 "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
6779 *codec_name = g_strdup ("TTA audio");
6780 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
6781 caps = gst_caps_new_simple ("audio/x-wavpack",
6782 "width", G_TYPE_INT, audiocontext->bitdepth,
6783 "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6784 *codec_name = g_strdup ("Wavpack audio");
6785 context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
6786 audiocontext->wvpk_block_index = 0;
6787 } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
6788 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
6789 (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
6790 gint raversion = -1;
6792 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
6794 else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
6799 caps = gst_caps_new_simple ("audio/x-pn-realaudio",
6800 "raversion", G_TYPE_INT, raversion, NULL);
6801 /* Extract extra information from caps, mapping varies based on codec */
6802 if (data && (size >= 0x50)) {
6809 guint extra_data_size;
6811 GST_DEBUG ("real audio raversion:%d", raversion);
6812 if (raversion == 8) {
6814 flavor = GST_READ_UINT16_BE (data + 22);
6815 packet_size = GST_READ_UINT32_BE (data + 24);
6816 height = GST_READ_UINT16_BE (data + 40);
6817 leaf_size = GST_READ_UINT16_BE (data + 44);
6818 sample_width = GST_READ_UINT16_BE (data + 58);
6819 extra_data_size = GST_READ_UINT32_BE (data + 74);
6822 ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
6823 flavor, packet_size, height, leaf_size, sample_width,
6825 gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
6826 G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
6827 G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
6829 if ((size - 78) >= extra_data_size) {
6830 priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
6832 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6833 gst_buffer_unref (priv);
6838 *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
6839 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
6840 caps = gst_caps_new_empty_simple ("audio/x-sipro");
6841 *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
6842 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
6843 caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
6844 *codec_name = g_strdup ("Real Audio Lossless");
6845 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
6846 caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
6847 *codec_name = g_strdup ("Sony ATRAC3");
6849 GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6854 if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
6857 for (i = 0; i < gst_caps_get_size (caps); i++) {
6858 gst_structure_set (gst_caps_get_structure (caps, i),
6859 "channels", G_TYPE_INT, audiocontext->channels,
6860 "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
6864 caps = gst_caps_simplify (caps);
6871 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
6872 subtitlecontext, const gchar * codec_id, gpointer data, guint size)
6874 GstCaps *caps = NULL;
6875 GstMatroskaTrackContext *context =
6876 (GstMatroskaTrackContext *) subtitlecontext;
6878 /* for backwards compatibility */
6879 if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
6880 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
6881 else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
6882 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
6883 else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
6884 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
6885 else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
6886 codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
6888 /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
6889 * Check if we have to do something with codec_private */
6890 if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
6891 /* well, plain text simply does not have a lot of markup ... */
6892 caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
6893 "pango-markup", NULL);
6894 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6895 subtitlecontext->check_markup = TRUE;
6896 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
6897 caps = gst_caps_new_empty_simple ("application/x-ssa");
6898 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6899 subtitlecontext->check_markup = FALSE;
6900 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
6901 caps = gst_caps_new_empty_simple ("application/x-ass");
6902 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6903 subtitlecontext->check_markup = FALSE;
6904 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
6905 caps = gst_caps_new_empty_simple ("application/x-usf");
6906 context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6907 subtitlecontext->check_markup = FALSE;
6908 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
6909 caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
6910 ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
6911 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
6912 caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
6913 } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
6914 caps = gst_caps_new_empty_simple ("subtitle/x-kate");
6915 context->stream_headers =
6916 gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6917 context->codec_priv_size);
6918 /* FIXME: mark stream as broken and skip if there are no stream headers */
6919 context->send_stream_headers = TRUE;
6921 GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
6922 caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
6925 if (data != NULL && size > 0) {
6928 buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
6929 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
6930 gst_buffer_unref (buf);
6938 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
6940 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6942 GST_OBJECT_LOCK (demux);
6943 if (demux->common.element_index)
6944 gst_object_unref (demux->common.element_index);
6945 demux->common.element_index = index ? gst_object_ref (index) : NULL;
6946 GST_OBJECT_UNLOCK (demux);
6947 GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
6948 demux->common.element_index);
6952 gst_matroska_demux_get_index (GstElement * element)
6954 GstIndex *result = NULL;
6955 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6957 GST_OBJECT_LOCK (demux);
6958 if (demux->common.element_index)
6959 result = gst_object_ref (demux->common.element_index);
6960 GST_OBJECT_UNLOCK (demux);
6962 GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
6968 static GstStateChangeReturn
6969 gst_matroska_demux_change_state (GstElement * element,
6970 GstStateChange transition)
6972 GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6973 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
6975 /* handle upwards state changes here */
6976 switch (transition) {
6981 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
6983 /* handle downwards state changes */
6984 switch (transition) {
6985 case GST_STATE_CHANGE_PAUSED_TO_READY:
6986 gst_matroska_demux_reset (GST_ELEMENT (demux));
6996 gst_matroska_demux_set_property (GObject * object,
6997 guint prop_id, const GValue * value, GParamSpec * pspec)
6999 GstMatroskaDemux *demux;
7001 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
7002 demux = GST_MATROSKA_DEMUX (object);
7005 case PROP_MAX_GAP_TIME:
7006 GST_OBJECT_LOCK (demux);
7007 demux->max_gap_time = g_value_get_uint64 (value);
7008 GST_OBJECT_UNLOCK (demux);
7010 case PROP_MAX_BACKTRACK_DISTANCE:
7011 GST_OBJECT_LOCK (demux);
7012 demux->max_backtrack_distance = g_value_get_uint (value);
7013 GST_OBJECT_UNLOCK (demux);
7016 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
7022 gst_matroska_demux_get_property (GObject * object,
7023 guint prop_id, GValue * value, GParamSpec * pspec)
7025 GstMatroskaDemux *demux;
7027 g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
7028 demux = GST_MATROSKA_DEMUX (object);
7031 case PROP_MAX_GAP_TIME:
7032 GST_OBJECT_LOCK (demux);
7033 g_value_set_uint64 (value, demux->max_gap_time);
7034 GST_OBJECT_UNLOCK (demux);
7036 case PROP_MAX_BACKTRACK_DISTANCE:
7037 GST_OBJECT_LOCK (demux);
7038 g_value_set_uint (value, demux->max_backtrack_distance);
7039 GST_OBJECT_UNLOCK (demux);
7042 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
7047 static const gchar *
7048 gst_matroska_track_encryption_algorithm_name (gint val)
7051 GEnumClass *enum_class =
7052 g_type_class_ref (MATROSKA_TRACK_ENCRYPTION_ALGORITHM_TYPE);
7053 en = g_enum_get_value (G_ENUM_CLASS (enum_class), val);
7054 return en ? en->value_nick : NULL;
7057 static const gchar *
7058 gst_matroska_track_encryption_cipher_mode_name (gint val)
7061 GEnumClass *enum_class =
7062 g_type_class_ref (MATROSKA_TRACK_ENCRYPTION_CIPHER_MODE_TYPE);
7063 en = g_enum_get_value (G_ENUM_CLASS (enum_class), val);
7064 return en ? en->value_nick : NULL;
7067 static const gchar *
7068 gst_matroska_track_encoding_scope_name (gint val)
7071 GEnumClass *enum_class =
7072 g_type_class_ref (MATROSKA_TRACK_ENCODING_SCOPE_TYPE);
7074 en = g_enum_get_value (G_ENUM_CLASS (enum_class), val);
7075 return en ? en->value_nick : NULL;
7079 gst_matroska_demux_plugin_init (GstPlugin * plugin)
7083 /* parser helper separate debug */
7084 GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
7085 0, "EBML stream helper class");
7087 /* create an elementfactory for the matroska_demux element */
7088 if (!gst_element_register (plugin, "matroskademux",
7089 GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))