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-parse.c: matroska file/stream parser
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 parseing is done correct for all codecs according to spec
31 * TODO: seeking with incomplete or without CUE
35 * SECTION:element-matroskaparse
37 * matroskaparse parsees 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 ! matroskaparse ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
43 * ]| This pipeline parsees a Matroska file and outputs the contained Vorbis audio.
54 #include <glib/gprintf.h>
56 /* For AVI compatibility mode
57 and for fourcc stuff */
58 #include <gst/riff/riff-read.h>
59 #include <gst/riff/riff-ids.h>
60 #include <gst/riff/riff-media.h>
62 #include <gst/tag/tag.h>
64 #include <gst/pbutils/pbutils.h>
66 #include "matroska-parse.h"
67 #include "matroska-ids.h"
69 GST_DEBUG_CATEGORY_STATIC (matroskaparse_debug);
70 #define GST_CAT_DEFAULT matroskaparse_debug
72 #define DEBUG_ELEMENT_START(parse, ebml, element) \
73 GST_DEBUG_OBJECT (parse, "Parsing " element " element at offset %" \
74 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
76 #define DEBUG_ELEMENT_STOP(parse, ebml, element, ret) \
77 GST_DEBUG_OBJECT (parse, "Parsing " element " element " \
78 " finished with '%s'", gst_flow_get_name (ret))
80 #define INVALID_DATA_THRESHOLD (2 * 1024 * 1024)
87 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
90 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
91 "video/x-matroska-3d; audio/webm; video/webm")
94 static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
97 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
98 "video/x-matroska-3d; audio/webm; video/webm")
101 static GstFlowReturn gst_matroska_parse_parse_id (GstMatroskaParse * parse,
102 guint32 id, guint64 length, guint needed);
104 /* element functions */
105 //static void gst_matroska_parse_loop (GstPad * pad);
107 static gboolean gst_matroska_parse_element_send_event (GstElement * element,
109 static gboolean gst_matroska_parse_element_query (GstElement * element,
113 static gboolean gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
114 GstPad * pad, GstEvent * event);
115 static gboolean gst_matroska_parse_handle_src_event (GstPad * pad,
116 GstObject * parent, GstEvent * event);
117 static gboolean gst_matroska_parse_handle_src_query (GstPad * pad,
118 GstObject * parent, GstQuery * query);
120 static gboolean gst_matroska_parse_handle_sink_event (GstPad * pad,
121 GstObject * parent, GstEvent * event);
122 static GstFlowReturn gst_matroska_parse_chain (GstPad * pad,
123 GstObject * parent, GstBuffer * buffer);
125 static GstStateChangeReturn
126 gst_matroska_parse_change_state (GstElement * element,
127 GstStateChange transition);
130 gst_matroska_parse_set_index (GstElement * element, GstIndex * index);
131 static GstIndex *gst_matroska_parse_get_index (GstElement * element);
135 static void gst_matroska_parse_reset (GstElement * element);
136 static gboolean perform_seek_to_offset (GstMatroskaParse * parse,
138 static GstCaps *gst_matroska_parse_forge_caps (gboolean is_webm,
141 GType gst_matroska_parse_get_type (void);
142 #define parent_class gst_matroska_parse_parent_class
143 G_DEFINE_TYPE (GstMatroskaParse, gst_matroska_parse, GST_TYPE_ELEMENT);
146 gst_matroska_parse_finalize (GObject * object)
148 GstMatroskaParse *parse = GST_MATROSKA_PARSE (object);
150 gst_matroska_read_common_finalize (&parse->common);
151 G_OBJECT_CLASS (parent_class)->finalize (object);
155 gst_matroska_parse_class_init (GstMatroskaParseClass * klass)
157 GObjectClass *gobject_class = (GObjectClass *) klass;
158 GstElementClass *gstelement_class = (GstElementClass *) klass;
160 GST_DEBUG_CATEGORY_INIT (matroskaparse_debug, "matroskaparse", 0,
163 gobject_class->finalize = gst_matroska_parse_finalize;
165 gstelement_class->change_state =
166 GST_DEBUG_FUNCPTR (gst_matroska_parse_change_state);
167 gstelement_class->send_event =
168 GST_DEBUG_FUNCPTR (gst_matroska_parse_element_send_event);
169 gstelement_class->query =
170 GST_DEBUG_FUNCPTR (gst_matroska_parse_element_query);
173 gstelement_class->set_index =
174 GST_DEBUG_FUNCPTR (gst_matroska_parse_set_index);
175 gstelement_class->get_index =
176 GST_DEBUG_FUNCPTR (gst_matroska_parse_get_index);
179 gst_element_class_add_static_pad_template (gstelement_class, &src_templ);
180 gst_element_class_add_static_pad_template (gstelement_class, &sink_templ);
182 gst_element_class_set_static_metadata (gstelement_class,
183 "Matroska parser", "Codec/Parser",
184 "Parses Matroska/WebM streams into video/audio/subtitles",
185 "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
189 gst_matroska_parse_init (GstMatroskaParse * parse)
191 parse->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
193 gst_pad_set_chain_function (parse->common.sinkpad,
194 GST_DEBUG_FUNCPTR (gst_matroska_parse_chain));
195 gst_pad_set_event_function (parse->common.sinkpad,
196 GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_sink_event));
197 gst_element_add_pad (GST_ELEMENT (parse), parse->common.sinkpad);
199 parse->srcpad = gst_pad_new_from_static_template (&src_templ, "src");
200 gst_pad_set_event_function (parse->srcpad,
201 GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_event));
202 gst_pad_set_query_function (parse->srcpad,
203 GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_query));
204 gst_pad_use_fixed_caps (parse->srcpad);
206 gst_element_add_pad (GST_ELEMENT (parse), parse->srcpad);
208 /* init defaults for common read context */
209 gst_matroska_read_common_init (&parse->common);
211 GST_OBJECT_FLAG_SET (parse, GST_ELEMENT_FLAG_INDEXABLE);
214 gst_matroska_parse_reset (GST_ELEMENT (parse));
218 gst_matroska_parse_reset (GstElement * element)
220 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
222 GST_DEBUG_OBJECT (parse, "Resetting state");
224 gst_matroska_read_common_reset (GST_ELEMENT (parse), &parse->common);
226 parse->num_a_streams = 0;
227 parse->num_t_streams = 0;
228 parse->num_v_streams = 0;
231 parse->tracks_parsed = FALSE;
233 g_list_foreach (parse->seek_parsed,
234 (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
235 g_list_free (parse->seek_parsed);
236 parse->seek_parsed = NULL;
238 parse->last_stop_end = GST_CLOCK_TIME_NONE;
239 parse->seek_block = 0;
240 parse->cluster_time = GST_CLOCK_TIME_NONE;
241 parse->cluster_offset = 0;
242 parse->next_cluster_offset = 0;
243 parse->index_offset = 0;
244 parse->seekable = FALSE;
245 parse->need_newsegment = TRUE;
246 parse->building_index = FALSE;
247 if (parse->seek_event) {
248 gst_event_unref (parse->seek_event);
249 parse->seek_event = NULL;
252 parse->seek_index = NULL;
253 parse->seek_entry = 0;
255 if (parse->close_segment) {
256 gst_event_unref (parse->close_segment);
257 parse->close_segment = NULL;
260 if (parse->new_segment) {
261 gst_event_unref (parse->new_segment);
262 parse->new_segment = NULL;
265 if (parse->streamheader != NULL) {
266 gst_buffer_unref (parse->streamheader);
267 parse->streamheader = NULL;
272 gst_matroska_parse_add_stream (GstMatroskaParse * parse, GstEbmlRead * ebml)
274 GstMatroskaTrackContext *context;
278 DEBUG_ELEMENT_START (parse, ebml, "TrackEntry");
280 /* start with the master */
281 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
282 DEBUG_ELEMENT_STOP (parse, ebml, "TrackEntry", ret);
286 /* allocate generic... if we know the type, we'll g_renew()
287 * with the precise type */
288 context = g_new0 (GstMatroskaTrackContext, 1);
289 g_ptr_array_add (parse->common.src, context);
290 context->index = parse->common.num_streams;
291 context->index_writer_id = -1;
292 context->type = 0; /* no type yet */
293 context->default_duration = 0;
295 context->set_discont = TRUE;
296 context->timecodescale = 1.0;
298 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
299 GST_MATROSKA_TRACK_LACING;
300 context->to_offset = G_MAXINT64;
301 context->alignment = 1;
302 parse->common.num_streams++;
303 g_assert (parse->common.src->len == parse->common.num_streams);
305 GST_DEBUG_OBJECT (parse, "Stream number %d", context->index);
307 /* try reading the trackentry headers */
308 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
309 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
313 /* track number (unique stream ID) */
314 case GST_MATROSKA_ID_TRACKNUMBER:{
317 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
321 GST_ERROR_OBJECT (parse, "Invalid TrackNumber 0");
322 ret = GST_FLOW_ERROR;
324 } else if (!gst_matroska_read_common_tracknumber_unique (&parse->common,
326 GST_ERROR_OBJECT (parse, "TrackNumber %" G_GUINT64_FORMAT
327 " is not unique", num);
328 ret = GST_FLOW_ERROR;
332 GST_DEBUG_OBJECT (parse, "TrackNumber: %" G_GUINT64_FORMAT, num);
336 /* track UID (unique identifier) */
337 case GST_MATROSKA_ID_TRACKUID:{
340 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
344 GST_ERROR_OBJECT (parse, "Invalid TrackUID 0");
345 ret = GST_FLOW_ERROR;
349 GST_DEBUG_OBJECT (parse, "TrackUID: %" G_GUINT64_FORMAT, num);
354 /* track type (video, audio, combined, subtitle, etc.) */
355 case GST_MATROSKA_ID_TRACKTYPE:{
358 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
362 if (context->type != 0 && context->type != track_type) {
363 GST_WARNING_OBJECT (parse,
364 "More than one tracktype defined in a TrackEntry - skipping");
366 } else if (track_type < 1 || track_type > 254) {
367 GST_WARNING_OBJECT (parse, "Invalid TrackType %" G_GUINT64_FORMAT,
372 GST_DEBUG_OBJECT (parse, "TrackType: %" G_GUINT64_FORMAT, track_type);
374 /* ok, so we're actually going to reallocate this thing */
375 switch (track_type) {
376 case GST_MATROSKA_TRACK_TYPE_VIDEO:
377 gst_matroska_track_init_video_context (&context);
378 parse->common.has_video = TRUE;
380 case GST_MATROSKA_TRACK_TYPE_AUDIO:
381 gst_matroska_track_init_audio_context (&context);
383 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
384 gst_matroska_track_init_subtitle_context (&context);
386 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
387 case GST_MATROSKA_TRACK_TYPE_LOGO:
388 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
389 case GST_MATROSKA_TRACK_TYPE_CONTROL:
391 GST_WARNING_OBJECT (parse,
392 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
397 g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
402 /* tracktype specific stuff for video */
403 case GST_MATROSKA_ID_TRACKVIDEO:{
404 GstMatroskaTrackVideoContext *videocontext;
406 DEBUG_ELEMENT_START (parse, ebml, "TrackVideo");
408 if (!gst_matroska_track_init_video_context (&context)) {
409 GST_WARNING_OBJECT (parse,
410 "TrackVideo element in non-video track - ignoring track");
411 ret = GST_FLOW_ERROR;
413 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
416 videocontext = (GstMatroskaTrackVideoContext *) context;
417 g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
420 while (ret == GST_FLOW_OK &&
421 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
422 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
426 /* Should be one level up but some broken muxers write it here. */
427 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
430 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
434 GST_WARNING_OBJECT (parse, "Invalid TrackDefaultDuration 0");
438 GST_DEBUG_OBJECT (parse,
439 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
440 context->default_duration = num;
444 /* video framerate */
445 /* NOTE: This one is here only for backward compatibility.
446 * Use _TRACKDEFAULDURATION one level up. */
447 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
450 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
454 GST_WARNING_OBJECT (parse, "Invalid TrackVideoFPS %lf", num);
458 GST_DEBUG_OBJECT (parse, "TrackVideoFrameRate: %lf", num);
459 if (context->default_duration == 0)
460 context->default_duration =
461 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
462 videocontext->default_fps = num;
466 /* width of the size to display the video at */
467 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
470 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
474 GST_WARNING_OBJECT (parse, "Invalid TrackVideoDisplayWidth 0");
478 GST_DEBUG_OBJECT (parse,
479 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
480 videocontext->display_width = num;
484 /* height of the size to display the video at */
485 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
488 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
492 GST_WARNING_OBJECT (parse, "Invalid TrackVideoDisplayHeight 0");
496 GST_DEBUG_OBJECT (parse,
497 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
498 videocontext->display_height = num;
502 /* width of the video in the file */
503 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
506 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
510 GST_WARNING_OBJECT (parse, "Invalid TrackVideoPixelWidth 0");
514 GST_DEBUG_OBJECT (parse,
515 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
516 videocontext->pixel_width = num;
520 /* height of the video in the file */
521 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
524 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
528 GST_WARNING_OBJECT (parse, "Invalid TrackVideoPixelHeight 0");
532 GST_DEBUG_OBJECT (parse,
533 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
534 videocontext->pixel_height = num;
538 /* whether the video is interlaced */
539 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
542 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
546 videocontext->interlace_mode =
547 GST_MATROSKA_INTERLACE_MODE_INTERLACED;
549 videocontext->interlace_mode =
550 GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
552 videocontext->interlace_mode =
553 GST_MATROSKA_INTERLACE_MODE_UNKNOWN;
555 GST_DEBUG_OBJECT (parse, "video track interlacing mode: %d",
556 videocontext->interlace_mode);
560 /* aspect ratio behaviour */
561 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
564 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
567 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
568 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
569 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
570 GST_WARNING_OBJECT (parse,
571 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
574 GST_DEBUG_OBJECT (parse,
575 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
576 videocontext->asr_mode = num;
580 /* colourspace (only matters for raw video) fourcc */
581 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
586 gst_ebml_read_binary (ebml, &id, &data,
587 &datalen)) != GST_FLOW_OK)
592 GST_WARNING_OBJECT (parse,
593 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
598 memcpy (&videocontext->fourcc, data, 4);
599 GST_DEBUG_OBJECT (parse,
600 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
601 GST_FOURCC_ARGS (videocontext->fourcc));
607 GST_WARNING_OBJECT (parse,
608 "Unknown TrackVideo subelement 0x%x - ignoring", id);
610 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
611 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
612 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
613 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
614 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
615 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
616 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
617 ret = gst_ebml_read_skip (ebml);
622 DEBUG_ELEMENT_STOP (parse, ebml, "TrackVideo", ret);
626 /* tracktype specific stuff for audio */
627 case GST_MATROSKA_ID_TRACKAUDIO:{
628 GstMatroskaTrackAudioContext *audiocontext;
630 DEBUG_ELEMENT_START (parse, ebml, "TrackAudio");
632 if (!gst_matroska_track_init_audio_context (&context)) {
633 GST_WARNING_OBJECT (parse,
634 "TrackAudio element in non-audio track - ignoring track");
635 ret = GST_FLOW_ERROR;
639 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
642 audiocontext = (GstMatroskaTrackAudioContext *) context;
643 g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
646 while (ret == GST_FLOW_OK &&
647 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
648 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
653 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
656 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
661 GST_WARNING_OBJECT (parse,
662 "Invalid TrackAudioSamplingFrequency %lf", num);
666 GST_DEBUG_OBJECT (parse, "TrackAudioSamplingFrequency: %lf", num);
667 audiocontext->samplerate = num;
672 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
675 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
679 GST_WARNING_OBJECT (parse, "Invalid TrackAudioBitDepth 0");
683 GST_DEBUG_OBJECT (parse, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
685 audiocontext->bitdepth = num;
690 case GST_MATROSKA_ID_AUDIOCHANNELS:{
693 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
697 GST_WARNING_OBJECT (parse, "Invalid TrackAudioChannels 0");
701 GST_DEBUG_OBJECT (parse, "TrackAudioChannels: %" G_GUINT64_FORMAT,
703 audiocontext->channels = num;
708 GST_WARNING_OBJECT (parse,
709 "Unknown TrackAudio subelement 0x%x - ignoring", id);
711 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
712 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
713 ret = gst_ebml_read_skip (ebml);
718 DEBUG_ELEMENT_STOP (parse, ebml, "TrackAudio", ret);
723 /* codec identifier */
724 case GST_MATROSKA_ID_CODECID:{
727 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
730 GST_DEBUG_OBJECT (parse, "CodecID: %s", GST_STR_NULL (text));
731 context->codec_id = text;
735 /* codec private data */
736 case GST_MATROSKA_ID_CODECPRIVATE:{
741 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
744 context->codec_priv = data;
745 context->codec_priv_size = size;
747 GST_DEBUG_OBJECT (parse, "CodecPrivate of size %" G_GUINT64_FORMAT,
752 /* name of the codec */
753 case GST_MATROSKA_ID_CODECNAME:{
756 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
759 GST_DEBUG_OBJECT (parse, "CodecName: %s", GST_STR_NULL (text));
760 context->codec_name = text;
764 /* name of this track */
765 case GST_MATROSKA_ID_TRACKNAME:{
768 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
771 context->name = text;
772 GST_DEBUG_OBJECT (parse, "TrackName: %s", GST_STR_NULL (text));
776 /* language (matters for audio/subtitles, mostly) */
777 case GST_MATROSKA_ID_TRACKLANGUAGE:{
780 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
784 context->language = text;
787 if (strlen (context->language) >= 4 && context->language[3] == '-')
788 context->language[3] = '\0';
790 GST_DEBUG_OBJECT (parse, "TrackLanguage: %s",
791 GST_STR_NULL (context->language));
795 /* whether this is actually used */
796 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
799 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
803 context->flags |= GST_MATROSKA_TRACK_ENABLED;
805 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
807 GST_DEBUG_OBJECT (parse, "TrackEnabled: %d",
808 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
812 /* whether it's the default for this track type */
813 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
816 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
820 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
822 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
824 GST_DEBUG_OBJECT (parse, "TrackDefault: %d",
825 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
829 /* whether the track must be used during playback */
830 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
833 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
837 context->flags |= GST_MATROSKA_TRACK_FORCED;
839 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
841 GST_DEBUG_OBJECT (parse, "TrackForced: %d",
842 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
846 /* lacing (like MPEG, where blocks don't end/start on frame
848 case GST_MATROSKA_ID_TRACKFLAGLACING:{
851 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
855 context->flags |= GST_MATROSKA_TRACK_LACING;
857 context->flags &= ~GST_MATROSKA_TRACK_LACING;
859 GST_DEBUG_OBJECT (parse, "TrackLacing: %d",
860 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
864 /* default length (in time) of one data block in this track */
865 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
868 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
873 GST_WARNING_OBJECT (parse, "Invalid TrackDefaultDuration 0");
877 GST_DEBUG_OBJECT (parse, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
879 context->default_duration = num;
883 case GST_MATROSKA_ID_CONTENTENCODINGS:{
884 ret = gst_matroska_read_common_read_track_encodings (&parse->common,
889 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
892 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
896 GST_WARNING_OBJECT (parse, "Invalid TrackTimeCodeScale %lf", num);
900 GST_DEBUG_OBJECT (parse, "TrackTimeCodeScale: %lf", num);
901 context->timecodescale = num;
906 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
909 /* we ignore these because they're nothing useful (i.e. crap)
910 * or simply not implemented yet. */
911 case GST_MATROSKA_ID_TRACKMINCACHE:
912 case GST_MATROSKA_ID_TRACKMAXCACHE:
913 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
914 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
915 case GST_MATROSKA_ID_TRACKOVERLAY:
916 case GST_MATROSKA_ID_TRACKTRANSLATE:
917 case GST_MATROSKA_ID_TRACKOFFSET:
918 case GST_MATROSKA_ID_CODECSETTINGS:
919 case GST_MATROSKA_ID_CODECINFOURL:
920 case GST_MATROSKA_ID_CODECDOWNLOADURL:
921 case GST_MATROSKA_ID_CODECDECODEALL:
922 ret = gst_ebml_read_skip (ebml);
927 DEBUG_ELEMENT_STOP (parse, ebml, "TrackEntry", ret);
929 /* Decode codec private data if necessary */
930 if (context->encodings && context->encodings->len > 0 && context->codec_priv
931 && context->codec_priv_size > 0) {
932 if (!gst_matroska_decode_data (context->encodings,
933 &context->codec_priv, &context->codec_priv_size,
934 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
935 GST_WARNING_OBJECT (parse, "Decoding codec private data failed");
936 ret = GST_FLOW_ERROR;
940 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
941 && ret != GST_FLOW_EOS)) {
942 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
943 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
945 parse->common.num_streams--;
946 g_ptr_array_remove_index (parse->common.src, parse->common.num_streams);
947 g_assert (parse->common.src->len == parse->common.num_streams);
948 gst_matroska_track_free (context);
953 if ((context->language == NULL || *context->language == '\0') &&
954 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
955 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
956 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
957 context->language = g_strdup ("eng");
966 gst_matroska_parse_query (GstMatroskaParse * parse, GstPad * pad,
969 gboolean res = FALSE;
970 GstMatroskaTrackContext *context = NULL;
973 context = gst_pad_get_element_private (pad);
976 switch (GST_QUERY_TYPE (query)) {
977 case GST_QUERY_POSITION:
981 gst_query_parse_position (query, &format, NULL);
983 if (format == GST_FORMAT_TIME) {
984 GST_OBJECT_LOCK (parse);
986 gst_query_set_position (query, GST_FORMAT_TIME, context->pos);
988 gst_query_set_position (query, GST_FORMAT_TIME,
989 parse->common.segment.position);
990 GST_OBJECT_UNLOCK (parse);
991 } else if (format == GST_FORMAT_DEFAULT && context
992 && context->default_duration) {
993 GST_OBJECT_LOCK (parse);
994 gst_query_set_position (query, GST_FORMAT_DEFAULT,
995 context->pos / context->default_duration);
996 GST_OBJECT_UNLOCK (parse);
998 GST_DEBUG_OBJECT (parse,
999 "only position query in TIME and DEFAULT format is supported");
1005 case GST_QUERY_DURATION:
1009 gst_query_parse_duration (query, &format, NULL);
1011 if (format == GST_FORMAT_TIME) {
1012 GST_OBJECT_LOCK (parse);
1013 gst_query_set_duration (query, GST_FORMAT_TIME,
1014 parse->common.segment.duration);
1015 GST_OBJECT_UNLOCK (parse);
1016 } else if (format == GST_FORMAT_DEFAULT && context
1017 && context->default_duration) {
1018 GST_OBJECT_LOCK (parse);
1019 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1020 parse->common.segment.duration / context->default_duration);
1021 GST_OBJECT_UNLOCK (parse);
1023 GST_DEBUG_OBJECT (parse,
1024 "only duration query in TIME and DEFAULT format is supported");
1031 case GST_QUERY_SEEKING:
1035 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1036 if (fmt == GST_FORMAT_TIME) {
1039 /* assuming we'll be able to get an index ... */
1040 seekable = parse->seekable;
1042 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1043 0, parse->common.segment.duration);
1050 res = gst_pad_query_default (pad, (GstObject *) parse, query);
1058 gst_matroska_parse_element_query (GstElement * element, GstQuery * query)
1060 return gst_matroska_parse_query (GST_MATROSKA_PARSE (element), NULL, query);
1064 gst_matroska_parse_handle_src_query (GstPad * pad, GstObject * parent,
1068 GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
1070 ret = gst_matroska_parse_query (parse, pad, query);
1076 gst_matroska_parse_send_tags (GstMatroskaParse * parse)
1078 if (G_UNLIKELY (parse->common.global_tags_changed)) {
1079 GstEvent *tag_event;
1080 gst_tag_list_add (parse->common.global_tags, GST_TAG_MERGE_REPLACE,
1081 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1082 GST_DEBUG_OBJECT (parse, "Sending global_tags %p : %" GST_PTR_FORMAT,
1083 parse->common.global_tags, parse->common.global_tags);
1085 /* Send a copy as we want to keep our local ref writable to add more tags
1086 * if any are found */
1088 gst_event_new_tag (gst_tag_list_copy (parse->common.global_tags));
1090 gst_pad_push_event (parse->srcpad, tag_event);
1092 parse->common.global_tags_changed = FALSE;
1096 /* returns FALSE if there are no pads to deliver event to,
1097 * otherwise TRUE (whatever the outcome of event sending),
1098 * takes ownership of the passed event! */
1100 gst_matroska_parse_send_event (GstMatroskaParse * parse, GstEvent * event)
1102 gboolean ret = FALSE;
1104 g_return_val_if_fail (event != NULL, FALSE);
1106 GST_DEBUG_OBJECT (parse, "Sending event of type %s to all source pads",
1107 GST_EVENT_TYPE_NAME (event));
1109 gst_pad_push_event (parse->srcpad, event);
1115 gst_matroska_parse_element_send_event (GstElement * element, GstEvent * event)
1117 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
1120 g_return_val_if_fail (event != NULL, FALSE);
1122 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1123 res = gst_matroska_parse_handle_seek_event (parse, NULL, event);
1125 GST_WARNING_OBJECT (parse, "Unhandled event of type %s",
1126 GST_EVENT_TYPE_NAME (event));
1129 gst_event_unref (event);
1134 /* searches for a cluster start from @pos,
1135 * return GST_FLOW_OK and cluster position in @pos if found */
1136 static GstFlowReturn
1137 gst_matroska_parse_search_cluster (GstMatroskaParse * parse, gint64 * pos)
1139 gint64 newpos = *pos;
1141 GstFlowReturn ret = GST_FLOW_OK;
1142 const guint chunk = 64 * 1024;
1151 orig_offset = parse->common.offset;
1153 /* read in at newpos and scan for ebml cluster id */
1155 GstByteReader reader;
1159 ret = gst_pad_pull_range (parse->common.sinkpad, newpos, chunk, &buf);
1160 if (ret != GST_FLOW_OK)
1162 GST_DEBUG_OBJECT (parse,
1163 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1164 gst_buffer_get_size (buf), newpos);
1165 gst_buffer_map (buf, &map, GST_MAP_READ);
1168 gst_byte_reader_init (&reader, data, size);
1171 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1172 GST_MATROSKA_ID_CLUSTER, cluster_pos, size - cluster_pos);
1173 if (cluster_pos >= 0) {
1174 newpos += cluster_pos;
1175 GST_DEBUG_OBJECT (parse,
1176 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1177 /* extra checks whether we really sync'ed to a cluster:
1178 * - either it is the first and only cluster
1179 * - either there is a cluster after this one
1180 * - either cluster length is undefined
1182 /* ok if first cluster (there may not a subsequent one) */
1183 if (newpos == parse->first_cluster_offset) {
1184 GST_DEBUG_OBJECT (parse, "cluster is first cluster -> OK");
1187 parse->common.offset = newpos;
1188 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1189 GST_ELEMENT_CAST (parse), &id, &length, &needed);
1190 if (ret != GST_FLOW_OK)
1192 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1193 GST_DEBUG_OBJECT (parse, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1195 /* ok if undefined length or first cluster */
1196 if (length == G_MAXUINT64) {
1197 GST_DEBUG_OBJECT (parse, "cluster has undefined length -> OK");
1201 parse->common.offset += length + needed;
1202 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1203 GST_ELEMENT_CAST (parse), &id, &length, &needed);
1204 if (ret != GST_FLOW_OK)
1206 GST_DEBUG_OBJECT (parse, "next element is %scluster",
1207 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1208 if (id == GST_MATROSKA_ID_CLUSTER)
1210 /* not ok, resume */
1213 /* partial cluster id may have been in tail of buffer */
1214 newpos += MAX (size, 4) - 3;
1215 gst_buffer_unmap (buf, &map);
1216 gst_buffer_unref (buf);
1222 gst_buffer_unmap (buf, &map);
1223 gst_buffer_unref (buf);
1227 parse->common.offset = orig_offset;
1234 gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
1235 GstPad * pad, GstEvent * event)
1237 GstMatroskaIndex *entry = NULL;
1239 GstSeekType cur_type, stop_type;
1243 GstMatroskaTrackContext *track = NULL;
1244 GstSegment seeksegment = { 0, };
1246 GstSearchMode snap_dir;
1249 track = gst_pad_get_element_private (pad);
1251 track = gst_matroska_read_common_get_seek_track (&parse->common, track);
1253 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1256 /* we can only seek on time */
1257 if (format != GST_FORMAT_TIME) {
1258 GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1262 /* copy segment, we need this because we still need the old
1263 * segment when we close the current segment. */
1264 memcpy (&seeksegment, &parse->common.segment, sizeof (GstSegment));
1267 GST_DEBUG_OBJECT (parse, "configuring seek");
1268 gst_segment_do_seek (&seeksegment, rate, format, flags,
1269 cur_type, cur, stop_type, stop, &update);
1272 GST_DEBUG_OBJECT (parse, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1274 if (seeksegment.rate < 0)
1275 snap_dir = GST_SEARCH_MODE_AFTER;
1277 snap_dir = GST_SEARCH_MODE_BEFORE;
1279 /* check sanity before we start flushing and all that */
1280 GST_OBJECT_LOCK (parse);
1281 if ((entry = gst_matroska_read_common_do_index_seek (&parse->common, track,
1282 seeksegment.position, &parse->seek_index, &parse->seek_entry,
1283 snap_dir)) == NULL) {
1284 /* pull mode without index can scan later on */
1285 GST_DEBUG_OBJECT (parse, "No matching seek entry in index");
1286 GST_OBJECT_UNLOCK (parse);
1289 GST_DEBUG_OBJECT (parse, "Seek position looks sane");
1290 GST_OBJECT_UNLOCK (parse);
1292 /* need to seek to cluster start to pick up cluster time */
1293 /* upstream takes care of flushing and all that
1294 * ... and newsegment event handling takes care of the rest */
1295 return perform_seek_to_offset (parse, entry->pos
1296 + parse->common.ebml_segment_start);
1300 * Handle whether we can perform the seek event or if we have to let the chain
1301 * function handle seeks to build the seek indexes first.
1304 gst_matroska_parse_handle_seek_push (GstMatroskaParse * parse, GstPad * pad,
1308 GstSeekType cur_type, stop_type;
1313 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1318 /* we can only seek on time */
1319 if (format != GST_FORMAT_TIME) {
1320 GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1324 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
1325 GST_DEBUG_OBJECT (parse, "Seek end-time not supported in streaming mode");
1329 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
1330 GST_DEBUG_OBJECT (parse,
1331 "Non-flushing seek not supported in streaming mode");
1335 if (flags & GST_SEEK_FLAG_SEGMENT) {
1336 GST_DEBUG_OBJECT (parse, "Segment seek not supported in streaming mode");
1340 /* check for having parsed index already */
1341 if (!parse->common.index_parsed) {
1342 gboolean building_index;
1345 if (!parse->index_offset) {
1346 GST_DEBUG_OBJECT (parse, "no index (location); no seek in push mode");
1350 GST_OBJECT_LOCK (parse);
1351 /* handle the seek event in the chain function */
1352 parse->common.state = GST_MATROSKA_READ_STATE_SEEK;
1353 /* no more seek can be issued until state reset to _DATA */
1355 /* copy the event */
1356 if (parse->seek_event)
1357 gst_event_unref (parse->seek_event);
1358 parse->seek_event = gst_event_ref (event);
1360 /* set the building_index flag so that only one thread can setup the
1361 * structures for index seeking. */
1362 building_index = parse->building_index;
1363 if (!building_index) {
1364 parse->building_index = TRUE;
1365 offset = parse->index_offset;
1367 GST_OBJECT_UNLOCK (parse);
1369 if (!building_index) {
1370 /* seek to the first subindex or legacy index */
1371 GST_INFO_OBJECT (parse, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
1372 return perform_seek_to_offset (parse, offset);
1375 /* well, we are handling it already */
1379 /* delegate to tweaked regular seek */
1380 return gst_matroska_parse_handle_seek_event (parse, pad, event);
1384 gst_matroska_parse_handle_src_event (GstPad * pad, GstObject * parent,
1387 GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
1388 gboolean res = TRUE;
1390 switch (GST_EVENT_TYPE (event)) {
1391 case GST_EVENT_SEEK:
1392 /* no seeking until we are (safely) ready */
1393 if (parse->common.state != GST_MATROSKA_READ_STATE_DATA) {
1394 GST_DEBUG_OBJECT (parse, "not ready for seeking yet");
1397 res = gst_matroska_parse_handle_seek_push (parse, pad, event);
1398 gst_event_unref (event);
1403 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
1404 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
1405 GstMatroskaTrackVideoContext *videocontext =
1406 (GstMatroskaTrackVideoContext *) context;
1408 GstClockTimeDiff diff;
1409 GstClockTime timestamp;
1411 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
1413 GST_OBJECT_LOCK (parse);
1414 videocontext->earliest_time = timestamp + diff;
1415 GST_OBJECT_UNLOCK (parse);
1418 gst_event_unref (event);
1422 /* events we don't need to handle */
1423 case GST_EVENT_NAVIGATION:
1424 gst_event_unref (event);
1428 case GST_EVENT_LATENCY:
1430 res = gst_pad_push_event (parse->common.sinkpad, event);
1437 static GstFlowReturn
1438 gst_matroska_parse_parse_tracks (GstMatroskaParse * parse, GstEbmlRead * ebml)
1440 GstFlowReturn ret = GST_FLOW_OK;
1443 DEBUG_ELEMENT_START (parse, ebml, "Tracks");
1445 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1446 DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1450 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1451 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1455 /* one track within the "all-tracks" header */
1456 case GST_MATROSKA_ID_TRACKENTRY:
1457 ret = gst_matroska_parse_add_stream (parse, ebml);
1461 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1466 DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1468 parse->tracks_parsed = TRUE;
1474 * Read signed/unsigned "EBML" numbers.
1475 * Return: number of bytes processed.
1479 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
1481 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
1489 while (read <= 8 && !(total & len_mask)) {
1496 if ((total &= (len_mask - 1)) == len_mask - 1)
1501 if (data[n] == 0xff)
1503 total = (total << 8) | data[n];
1507 if (read == num_ffs && total != 0)
1516 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
1521 /* read as unsigned number first */
1522 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
1526 if (unum == G_MAXUINT64)
1529 *num = unum - ((1 << ((7 * res) - 1)) - 1);
1534 static GstFlowReturn
1535 gst_matroska_parse_parse_blockgroup_or_simpleblock (GstMatroskaParse * parse,
1536 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
1537 gboolean is_simpleblock)
1539 GstMatroskaTrackContext *stream = NULL;
1540 GstFlowReturn ret = GST_FLOW_OK;
1541 gboolean readblock = FALSE;
1543 guint64 block_duration = 0;
1544 GstBuffer *buf = NULL;
1546 gint stream_num = -1, n, laces = 0;
1548 gint *lace_size = NULL;
1551 gint64 referenceblock = 0;
1553 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1554 if (!is_simpleblock) {
1555 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
1559 id = GST_MATROSKA_ID_SIMPLEBLOCK;
1563 /* one block inside the group. Note, block parsing is one
1564 * of the harder things, so this code is a bit complicated.
1565 * See http://www.matroska.org/ for documentation. */
1566 case GST_MATROSKA_ID_SIMPLEBLOCK:
1567 case GST_MATROSKA_ID_BLOCK:
1573 gst_buffer_unref (buf);
1576 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
1579 gst_buffer_map (buf, &map, GST_MAP_READ);
1583 /* first byte(s): blocknum */
1584 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1589 /* fetch stream from num */
1590 stream_num = gst_matroska_read_common_stream_from_num (&parse->common,
1592 if (G_UNLIKELY (size < 3)) {
1593 GST_WARNING_OBJECT (parse, "Invalid size %u", size);
1594 /* non-fatal, try next block(group) */
1597 } else if (G_UNLIKELY (stream_num < 0 ||
1598 stream_num >= parse->common.num_streams)) {
1599 /* let's not give up on a stray invalid track number */
1600 GST_WARNING_OBJECT (parse,
1601 "Invalid stream %d for track number %" G_GUINT64_FORMAT
1602 "; ignoring block", stream_num, num);
1606 stream = g_ptr_array_index (parse->common.src, stream_num);
1608 /* time (relative to cluster time) */
1609 time = ((gint16) GST_READ_UINT16_BE (data));
1612 flags = GST_READ_UINT8 (data);
1616 GST_LOG_OBJECT (parse, "time %" G_GUINT64_FORMAT ", flags %d", time,
1619 switch ((flags & 0x06) >> 1) {
1620 case 0x0: /* no lacing */
1622 lace_size = g_new (gint, 1);
1623 lace_size[0] = size;
1626 case 0x1: /* xiph lacing */
1627 case 0x2: /* fixed-size lacing */
1628 case 0x3: /* EBML lacing */
1630 goto invalid_lacing;
1631 laces = GST_READ_UINT8 (data) + 1;
1634 lace_size = g_new0 (gint, laces);
1636 switch ((flags & 0x06) >> 1) {
1637 case 0x1: /* xiph lacing */ {
1638 guint temp, total = 0;
1640 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
1643 goto invalid_lacing;
1644 temp = GST_READ_UINT8 (data);
1645 lace_size[n] += temp;
1651 total += lace_size[n];
1653 lace_size[n] = size - total;
1657 case 0x2: /* fixed-size lacing */
1658 for (n = 0; n < laces; n++)
1659 lace_size[n] = size / laces;
1662 case 0x3: /* EBML lacing */ {
1665 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1669 total = lace_size[0] = num;
1670 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
1674 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
1678 lace_size[n] = lace_size[n - 1] + snum;
1679 total += lace_size[n];
1682 lace_size[n] = size - total;
1689 if (ret != GST_FLOW_OK)
1696 case GST_MATROSKA_ID_BLOCKDURATION:{
1697 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
1698 GST_DEBUG_OBJECT (parse, "BlockDuration: %" G_GUINT64_FORMAT,
1703 case GST_MATROSKA_ID_REFERENCEBLOCK:{
1704 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
1705 GST_DEBUG_OBJECT (parse, "ReferenceBlock: %" G_GINT64_FORMAT,
1710 case GST_MATROSKA_ID_CODECSTATE:{
1712 guint64 data_len = 0;
1715 gst_ebml_read_binary (ebml, &id, &data,
1716 &data_len)) != GST_FLOW_OK)
1719 if (G_UNLIKELY (stream == NULL)) {
1720 GST_WARNING_OBJECT (parse,
1721 "Unexpected CodecState subelement - ignoring");
1725 g_free (stream->codec_state);
1726 stream->codec_state = data;
1727 stream->codec_state_size = data_len;
1733 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1737 case GST_MATROSKA_ID_BLOCKVIRTUAL:
1738 case GST_MATROSKA_ID_BLOCKADDITIONS:
1739 case GST_MATROSKA_ID_REFERENCEPRIORITY:
1740 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
1741 case GST_MATROSKA_ID_SLICES:
1742 GST_DEBUG_OBJECT (parse,
1743 "Skipping BlockGroup subelement 0x%x - ignoring", id);
1744 ret = gst_ebml_read_skip (ebml);
1752 /* reading a number or so could have failed */
1753 if (ret != GST_FLOW_OK)
1756 if (ret == GST_FLOW_OK && readblock) {
1757 guint64 duration = 0;
1758 gint64 lace_time = 0;
1759 gboolean delta_unit;
1761 stream = g_ptr_array_index (parse->common.src, stream_num);
1763 if (cluster_time != GST_CLOCK_TIME_NONE) {
1764 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
1765 * Drop unless the lace contains timestamp 0? */
1766 if (time < 0 && (-time) > cluster_time) {
1769 if (stream->timecodescale == 1.0)
1770 lace_time = (cluster_time + time) * parse->common.time_scale;
1773 gst_util_guint64_to_gdouble ((cluster_time + time) *
1774 parse->common.time_scale) * stream->timecodescale;
1777 lace_time = GST_CLOCK_TIME_NONE;
1780 if (lace_time != GST_CLOCK_TIME_NONE) {
1781 parse->last_timestamp = lace_time;
1783 /* need to refresh segment info ASAP */
1784 if (GST_CLOCK_TIME_IS_VALID (lace_time) && parse->need_newsegment) {
1786 GST_DEBUG_OBJECT (parse,
1787 "generating segment starting at %" GST_TIME_FORMAT,
1788 GST_TIME_ARGS (lace_time));
1789 /* pretend we seeked here */
1790 gst_segment_do_seek (&parse->common.segment, parse->common.segment.rate,
1791 GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, lace_time,
1792 GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE, NULL);
1793 /* now convey our segment notion downstream */
1794 segment = parse->common.segment;
1795 segment.position = segment.start;
1796 gst_matroska_parse_send_event (parse, gst_event_new_segment (&segment));
1797 parse->need_newsegment = FALSE;
1800 if (block_duration) {
1801 if (stream->timecodescale == 1.0)
1802 duration = gst_util_uint64_scale (block_duration,
1803 parse->common.time_scale, 1);
1806 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
1807 (gst_util_uint64_scale (block_duration, parse->common.time_scale,
1808 1)) * stream->timecodescale);
1809 } else if (stream->default_duration) {
1810 duration = stream->default_duration * laces;
1812 /* else duration is diff between timecode of this and next block */
1814 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
1815 a ReferenceBlock implies that this is not a keyframe. In either
1816 case, it only makes sense for video streams. */
1817 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1818 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
1820 if (delta_unit && stream->set_discont) {
1821 /* When doing seeks or such, we need to restart on key frames or
1822 * decoders might choke. */
1823 GST_DEBUG_OBJECT (parse, "skipping delta unit");
1827 for (n = 0; n < laces; n++) {
1828 if (G_UNLIKELY (lace_size[n] > size)) {
1829 GST_WARNING_OBJECT (parse, "Invalid lace size");
1833 /* QoS for video track with an index. the assumption is that
1834 index entries point to keyframes, but if that is not true we
1835 will instad skip until the next keyframe. */
1836 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1837 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1838 stream->index_table && parse->common.segment.rate > 0.0) {
1839 GstMatroskaTrackVideoContext *videocontext =
1840 (GstMatroskaTrackVideoContext *) stream;
1841 GstClockTime earliest_time;
1842 GstClockTime earliest_stream_time;
1844 GST_OBJECT_LOCK (parse);
1845 earliest_time = videocontext->earliest_time;
1846 GST_OBJECT_UNLOCK (parse);
1847 earliest_stream_time =
1848 gst_segment_position_from_running_time (&parse->common.segment,
1849 GST_FORMAT_TIME, earliest_time);
1851 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1852 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
1853 lace_time <= earliest_stream_time) {
1854 /* find index entry (keyframe) <= earliest_stream_time */
1855 GstMatroskaIndex *entry =
1856 gst_util_array_binary_search (stream->index_table->data,
1857 stream->index_table->len, sizeof (GstMatroskaIndex),
1858 (GCompareDataFunc) gst_matroska_index_seek_find,
1859 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
1861 /* if that entry (keyframe) is after the current the current
1862 buffer, we can skip pushing (and thus decoding) all
1863 buffers until that keyframe. */
1864 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
1865 entry->time > lace_time) {
1866 GST_LOG_OBJECT (parse, "Skipping lace before late keyframe");
1867 stream->set_discont = TRUE;
1873 sub = gst_buffer_create_sub (buf,
1874 GST_BUFFER_SIZE (buf) - size, lace_size[n]);
1875 GST_DEBUG_OBJECT (parse, "created subbuffer %p", sub);
1878 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1880 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1882 if (stream->encodings != NULL && stream->encodings->len > 0)
1883 sub = gst_matroska_decode_buffer (stream, sub);
1886 GST_WARNING_OBJECT (parse, "Decoding buffer failed");
1890 GST_BUFFER_TIMESTAMP (sub) = lace_time;
1892 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
1893 GstClockTime last_stop_end;
1895 /* Check if this stream is after segment stop */
1896 if (GST_CLOCK_TIME_IS_VALID (parse->common.segment.stop) &&
1897 lace_time >= parse->common.segment.stop) {
1898 GST_DEBUG_OBJECT (parse,
1899 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
1900 GST_TIME_ARGS (parse->common.segment.stop));
1901 gst_buffer_unref (sub);
1904 if (offset >= stream->to_offset) {
1905 GST_DEBUG_OBJECT (parse, "Stream %d after playback section",
1907 gst_buffer_unref (sub);
1911 /* handle gaps, e.g. non-zero start-time, or an cue index entry
1912 * that landed us with timestamps not quite intended */
1913 if (GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop) &&
1914 parse->segment.rate > 0.0) {
1915 GstClockTimeDiff diff;
1917 /* only send newsegments with increasing start times,
1918 * otherwise if these go back and forth downstream (sinks) increase
1919 * accumulated time and running_time */
1920 diff = GST_CLOCK_DIFF (parse->segment.last_stop, lace_time);
1921 if (diff > 2 * GST_SECOND && lace_time > parse->segment.start &&
1922 (!GST_CLOCK_TIME_IS_VALID (parse->segment.stop) ||
1923 lace_time < parse->segment.stop)) {
1924 GST_DEBUG_OBJECT (parse,
1925 "Gap of %" G_GINT64_FORMAT " ns detected in"
1926 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
1927 "Sending updated NEWSEGMENT events", diff,
1928 stream->index, GST_TIME_ARGS (stream->pos),
1929 GST_TIME_ARGS (lace_time));
1930 /* send newsegment events such that the gap is not accounted in
1931 * accum time, hence running_time */
1932 /* close ahead of gap */
1933 gst_matroska_parse_send_event (parse,
1934 gst_event_new_new_segment (TRUE, parse->segment.rate,
1935 parse->segment.format, parse->segment.last_stop,
1936 parse->segment.last_stop, parse->segment.last_stop));
1938 gst_matroska_parse_send_event (parse,
1939 gst_event_new_new_segment (FALSE, parse->segment.rate,
1940 parse->segment.format, lace_time, parse->segment.stop,
1942 /* align segment view with downstream,
1943 * prevents double-counting accum when closing segment */
1944 gst_segment_set_newsegment (&parse->segment, FALSE,
1945 parse->segment.rate, parse->segment.format, lace_time,
1946 parse->segment.stop, lace_time);
1947 parse->segment.last_stop = lace_time;
1951 if (!GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop)
1952 || parse->segment.last_stop < lace_time) {
1953 parse->segment.last_stop = lace_time;
1956 last_stop_end = lace_time;
1958 GST_BUFFER_DURATION (sub) = duration / laces;
1959 last_stop_end += GST_BUFFER_DURATION (sub);
1962 if (!GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) ||
1963 parse->last_stop_end < last_stop_end)
1964 parse->last_stop_end = last_stop_end;
1966 if (parse->segment.duration == -1 ||
1967 parse->segment.duration < lace_time) {
1968 gst_segment_set_duration (&parse->segment, GST_FORMAT_TIME,
1970 gst_element_post_message (GST_ELEMENT_CAST (parse),
1971 gst_message_new_duration (GST_OBJECT_CAST (parse),
1972 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
1976 stream->pos = lace_time;
1978 gst_matroska_parse_sync_streams (parse);
1980 if (stream->set_discont) {
1981 GST_DEBUG_OBJECT (parse, "marking DISCONT");
1982 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
1983 stream->set_discont = FALSE;
1986 /* reverse playback book-keeping */
1987 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
1988 stream->from_time = lace_time;
1989 if (stream->from_offset == -1)
1990 stream->from_offset = offset;
1992 GST_DEBUG_OBJECT (parse,
1993 "Pushing lace %d, data of size %d for stream %d, time=%"
1994 GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
1995 GST_BUFFER_SIZE (sub), stream_num,
1996 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
1997 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
1999 if (parse->element_index) {
2000 if (stream->index_writer_id == -1)
2001 gst_index_get_writer_id (parse->element_index,
2002 GST_OBJECT (stream->pad), &stream->index_writer_id);
2004 GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
2005 G_GUINT64_FORMAT " for writer id %d",
2006 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
2007 stream->index_writer_id);
2008 gst_index_add_association (parse->element_index,
2009 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
2010 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
2011 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
2012 cluster_offset, NULL);
2015 gst_buffer_set_caps (sub, GST_PAD_CAPS (parse->srcpad));
2017 /* Postprocess the buffers depending on the codec used */
2018 if (stream->postprocess_frame) {
2019 GST_LOG_OBJECT (parse, "running post process");
2020 ret = stream->postprocess_frame (GST_ELEMENT (parse), stream, &sub);
2023 ret = gst_pad_push (stream->pad, sub);
2024 if (parse->segment.rate < 0) {
2025 if (lace_time > parse->segment.stop && ret == GST_FLOW_EOS) {
2026 /* In reverse playback we can get a GST_FLOW_EOS when
2027 * we are at the end of the segment, so we just need to jump
2028 * back to the previous section. */
2029 GST_DEBUG_OBJECT (parse, "downstream has reached end of segment");
2034 ret = gst_matroska_parse_combine_flows (parse, stream, ret);
2038 size -= lace_size[n];
2039 if (lace_time != GST_CLOCK_TIME_NONE && duration)
2040 lace_time += duration / laces;
2042 lace_time = GST_CLOCK_TIME_NONE;
2048 gst_buffer_unmap (buf, &map);
2049 gst_buffer_unref (buf);
2058 GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
2059 /* non-fatal, try next block(group) */
2065 GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Data error"));
2066 /* non-fatal, try next block(group) */
2072 /* return FALSE if block(group) should be skipped (due to a seek) */
2073 static inline gboolean
2074 gst_matroska_parse_seek_block (GstMatroskaParse * parse)
2076 if (G_UNLIKELY (parse->seek_block)) {
2077 if (!(--parse->seek_block)) {
2080 GST_LOG_OBJECT (parse, "should skip block due to seek");
2088 static GstFlowReturn
2089 gst_matroska_parse_parse_contents_seekentry (GstMatroskaParse * parse,
2093 guint64 seek_pos = (guint64) - 1;
2094 guint32 seek_id = 0;
2097 DEBUG_ELEMENT_START (parse, ebml, "Seek");
2099 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2100 DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2104 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2105 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2109 case GST_MATROSKA_ID_SEEKID:
2113 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2116 GST_DEBUG_OBJECT (parse, "SeekID: %" G_GUINT64_FORMAT, t);
2121 case GST_MATROSKA_ID_SEEKPOSITION:
2125 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2128 if (t > G_MAXINT64) {
2129 GST_WARNING_OBJECT (parse,
2130 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
2134 GST_DEBUG_OBJECT (parse, "SeekPosition: %" G_GUINT64_FORMAT, t);
2140 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2146 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
2149 if (!seek_id || seek_pos == (guint64) - 1) {
2150 GST_WARNING_OBJECT (parse, "Incomplete seekhead entry (0x%x/%"
2151 G_GUINT64_FORMAT ")", seek_id, seek_pos);
2156 case GST_MATROSKA_ID_SEEKHEAD:
2159 case GST_MATROSKA_ID_CUES:
2160 case GST_MATROSKA_ID_TAGS:
2161 case GST_MATROSKA_ID_TRACKS:
2162 case GST_MATROSKA_ID_SEGMENTINFO:
2163 case GST_MATROSKA_ID_ATTACHMENTS:
2164 case GST_MATROSKA_ID_CHAPTERS:
2169 length = gst_matroska_read_common_get_length (&parse->common);
2171 if (length == (guint64) - 1) {
2172 GST_DEBUG_OBJECT (parse, "no upstream length, skipping SeakHead entry");
2176 /* check for validity */
2177 if (seek_pos + parse->common.ebml_segment_start + 12 >= length) {
2178 GST_WARNING_OBJECT (parse,
2179 "SeekHead reference lies outside file!" " (%"
2180 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
2181 G_GUINT64_FORMAT ")", seek_pos, parse->common.ebml_segment_start,
2186 /* only pick up index location when streaming */
2187 if (seek_id == GST_MATROSKA_ID_CUES) {
2188 parse->index_offset = seek_pos + parse->common.ebml_segment_start;
2189 GST_DEBUG_OBJECT (parse, "Cues located at offset %" G_GUINT64_FORMAT,
2190 parse->index_offset);
2196 GST_DEBUG_OBJECT (parse, "Ignoring Seek entry for ID=0x%x", seek_id);
2199 DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2204 static GstFlowReturn
2205 gst_matroska_parse_parse_contents (GstMatroskaParse * parse, GstEbmlRead * ebml)
2207 GstFlowReturn ret = GST_FLOW_OK;
2210 DEBUG_ELEMENT_START (parse, ebml, "SeekHead");
2212 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2213 DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2217 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2218 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2222 case GST_MATROSKA_ID_SEEKENTRY:
2224 ret = gst_matroska_parse_parse_contents_seekentry (parse, ebml);
2225 /* Ignore EOS and errors here */
2226 if (ret != GST_FLOW_OK) {
2227 GST_DEBUG_OBJECT (parse, "Ignoring %s", gst_flow_get_name (ret));
2234 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2240 DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2245 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
2247 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
2249 static inline GstFlowReturn
2250 gst_matroska_parse_check_read_size (GstMatroskaParse * parse, guint64 bytes)
2252 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
2253 /* only a few blocks are expected/allowed to be large,
2254 * and will be recursed into, whereas others will be read and must fit */
2255 /* fatal in streaming case, as we can't step over easily */
2256 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2257 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
2258 "file might be corrupt.", bytes));
2259 return GST_FLOW_ERROR;
2266 /* returns TRUE if we truely are in error state, and should give up */
2267 static inline gboolean
2268 gst_matroska_parse_check_parse_error (GstMatroskaParse * parse)
2272 /* sigh, one last attempt above and beyond call of duty ...;
2273 * search for cluster mark following current pos */
2274 pos = parse->common.offset;
2275 GST_WARNING_OBJECT (parse, "parse error, looking for next cluster");
2276 if (gst_matroska_parse_search_cluster (parse, &pos) != GST_FLOW_OK) {
2277 /* did not work, give up */
2280 GST_DEBUG_OBJECT (parse, "... found at %" G_GUINT64_FORMAT, pos);
2281 /* try that position */
2282 parse->common.offset = pos;
2288 /* initializes @ebml with @bytes from input stream at current offset.
2289 * Returns EOS if insufficient available,
2290 * ERROR if too much was attempted to read. */
2291 static inline GstFlowReturn
2292 gst_matroska_parse_take (GstMatroskaParse * parse, guint64 bytes,
2295 GstBuffer *buffer = NULL;
2296 GstFlowReturn ret = GST_FLOW_OK;
2298 GST_LOG_OBJECT (parse, "taking %" G_GUINT64_FORMAT " bytes for parsing",
2300 ret = gst_matroska_parse_check_read_size (parse, bytes);
2301 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
2302 /* otherwise fatal */
2303 ret = GST_FLOW_ERROR;
2306 if (gst_adapter_available (parse->common.adapter) < bytes)
2307 return GST_FLOW_EOS;
2309 buffer = gst_adapter_take_buffer (parse->common.adapter, bytes);
2310 if (G_LIKELY (buffer)) {
2311 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (parse), buffer,
2312 parse->common.offset);
2313 parse->common.offset += bytes;
2315 ret = GST_FLOW_ERROR;
2323 gst_matroska_parse_check_seekability (GstMatroskaParse * parse)
2326 gboolean seekable = FALSE;
2327 gint64 start = -1, stop = -1;
2329 query = gst_query_new_seeking (GST_FORMAT_BYTES);
2330 if (!gst_pad_peer_query (parse->common.sinkpad, query)) {
2331 GST_DEBUG_OBJECT (parse, "seeking query failed");
2335 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
2337 /* try harder to query upstream size if we didn't get it the first time */
2338 if (seekable && stop == -1) {
2339 GST_DEBUG_OBJECT (parse, "doing duration query to fix up unset stop");
2340 gst_pad_peer_query_duration (parse->common.sinkpad, GST_FORMAT_BYTES,
2344 /* if upstream doesn't know the size, it's likely that it's not seekable in
2345 * practice even if it technically may be seekable */
2346 if (seekable && (start != 0 || stop <= start)) {
2347 GST_DEBUG_OBJECT (parse, "seekable but unknown start/stop -> disable");
2352 GST_INFO_OBJECT (parse, "seekable: %d (%" G_GUINT64_FORMAT " - %"
2353 G_GUINT64_FORMAT ")", seekable, start, stop);
2354 parse->seekable = seekable;
2356 gst_query_unref (query);
2360 static GstFlowReturn
2361 gst_matroska_parse_find_tracks (GstMatroskaParse * parse)
2367 GstFlowReturn ret = GST_FLOW_OK;
2369 GST_WARNING_OBJECT (parse,
2370 "Found Cluster element before Tracks, searching Tracks");
2373 before_pos = parse->common.offset;
2375 /* Search Tracks element */
2377 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2378 GST_ELEMENT_CAST (parse), &id, &length, &needed);
2379 if (ret != GST_FLOW_OK)
2382 if (id != GST_MATROSKA_ID_TRACKS) {
2383 /* we may be skipping large cluster here, so forego size check etc */
2384 /* ... but we can't skip undefined size; force error */
2385 if (length == G_MAXUINT64) {
2386 ret = gst_matroska_parse_check_read_size (parse, length);
2389 parse->common.offset += needed;
2390 parse->offset += length;
2395 /* will lead to track parsing ... */
2396 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2401 parse->offset = before_pos;
2407 #define GST_READ_CHECK(stmt) \
2409 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
2410 if (ret == GST_FLOW_OVERFLOW) { \
2411 ret = GST_FLOW_OK; \
2418 gst_matroska_parse_accumulate_streamheader (GstMatroskaParse * parse,
2421 if (parse->pushed_headers) {
2422 GST_WARNING_OBJECT (parse,
2423 "Accumulating headers, but headers are already pushed");
2426 if (parse->streamheader) {
2427 parse->streamheader = gst_buffer_append (parse->streamheader,
2428 gst_buffer_ref (buffer));
2430 parse->streamheader = gst_buffer_ref (buffer);
2433 GST_DEBUG ("%" G_GSIZE_FORMAT, gst_buffer_get_size (parse->streamheader));
2436 static GstFlowReturn
2437 gst_matroska_parse_output (GstMatroskaParse * parse, GstBuffer * buffer,
2442 if (!parse->pushed_headers) {
2445 GValue streamheader = { 0 };
2446 GValue bufval = { 0 };
2449 caps = gst_pad_get_current_caps (parse->common.sinkpad);
2451 caps = gst_matroska_parse_forge_caps (parse->common.is_webm,
2452 parse->common.has_video);
2454 caps = gst_caps_make_writable (caps);
2456 s = gst_caps_get_structure (caps, 0);
2457 g_value_init (&streamheader, GST_TYPE_ARRAY);
2458 g_value_init (&bufval, GST_TYPE_BUFFER);
2459 buf = gst_buffer_copy (parse->streamheader);
2460 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2461 gst_value_set_buffer (&bufval, buf);
2462 gst_buffer_unref (buf);
2463 gst_value_array_append_value (&streamheader, &bufval);
2464 g_value_unset (&bufval);
2465 gst_structure_set_value (s, "streamheader", &streamheader);
2466 g_value_unset (&streamheader);
2467 //gst_caps_replace (parse->caps, caps);
2468 gst_pad_set_caps (parse->srcpad, caps);
2470 if (parse->need_newsegment) {
2471 gst_pad_push_event (parse->srcpad,
2472 gst_event_new_segment (&parse->common.segment));
2473 parse->need_newsegment = FALSE;
2476 buf = gst_buffer_copy (parse->streamheader);
2477 gst_caps_unref (caps);
2479 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2480 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2481 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
2483 ret = gst_pad_push (parse->srcpad, buf);
2484 if (ret != GST_FLOW_OK) {
2485 GST_WARNING_OBJECT (parse, "Failed to push buffer");
2489 parse->pushed_headers = TRUE;
2493 GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2495 GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2497 if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE) {
2498 parse->last_timestamp = GST_BUFFER_TIMESTAMP (buffer);
2500 GST_BUFFER_TIMESTAMP (buffer) = parse->last_timestamp;
2503 return gst_pad_push (parse->srcpad, gst_buffer_ref (buffer));
2506 static GstFlowReturn
2507 gst_matroska_parse_parse_id (GstMatroskaParse * parse, guint32 id,
2508 guint64 length, guint needed)
2510 GstEbmlRead ebml = { 0, };
2511 GstFlowReturn ret = GST_FLOW_OK;
2513 //GstBuffer *buffer;
2515 GST_DEBUG_OBJECT (parse, "Parsing Element id 0x%x, "
2516 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
2519 if (gst_adapter_available (parse->adapter) >= length + needed) {
2520 buffer = gst_adapter_take_buffer (parse->adapter, length + needed);
2521 gst_pad_push (parse->srcpad, buffer);
2525 //GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2532 /* if we plan to read and parse this element, we need prefix (id + length)
2533 * and the contents */
2534 /* mind about overflow wrap-around when dealing with undefined size */
2536 if (G_LIKELY (length != G_MAXUINT64))
2539 switch (parse->common.state) {
2540 case GST_MATROSKA_READ_STATE_START:
2542 case GST_EBML_ID_HEADER:
2543 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2544 ret = gst_matroska_read_common_parse_header (&parse->common, &ebml);
2545 if (ret != GST_FLOW_OK)
2547 parse->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
2548 gst_matroska_parse_check_seekability (parse);
2549 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2552 goto invalid_header;
2556 case GST_MATROSKA_READ_STATE_SEGMENT:
2558 case GST_MATROSKA_ID_SEGMENT:
2559 /* eat segment prefix */
2560 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2561 GST_DEBUG_OBJECT (parse,
2562 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
2563 G_GUINT64_FORMAT, parse->common.offset, length);
2564 /* seeks are from the beginning of the segment,
2565 * after the segment ID/length */
2566 parse->common.ebml_segment_start = parse->common.offset;
2568 length = G_MAXUINT64;
2569 parse->common.ebml_segment_length = length;
2570 parse->common.state = GST_MATROSKA_READ_STATE_HEADER;
2571 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2574 GST_WARNING_OBJECT (parse,
2575 "Expected a Segment ID (0x%x), but received 0x%x!",
2576 GST_MATROSKA_ID_SEGMENT, id);
2577 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2578 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2582 case GST_MATROSKA_READ_STATE_SCANNING:
2583 if (id != GST_MATROSKA_ID_CLUSTER &&
2584 id != GST_MATROSKA_ID_CLUSTERTIMECODE) {
2585 /* we need to skip byte per byte if we are scanning for a new cluster */
2589 GST_LOG_OBJECT (parse, "Resync done, new cluster found!");
2590 parse->common.start_resync_offset = -1;
2591 parse->common.state = parse->common.state_to_restore;
2594 case GST_MATROSKA_READ_STATE_HEADER:
2595 case GST_MATROSKA_READ_STATE_DATA:
2596 case GST_MATROSKA_READ_STATE_SEEK:
2598 case GST_MATROSKA_ID_SEGMENTINFO:
2599 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2600 if (!parse->common.segmentinfo_parsed) {
2601 ret = gst_matroska_read_common_parse_info (&parse->common,
2602 GST_ELEMENT_CAST (parse), &ebml);
2603 if (ret == GST_FLOW_OK)
2604 gst_matroska_parse_send_tags (parse);
2606 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2608 case GST_MATROSKA_ID_TRACKS:
2609 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2610 if (!parse->tracks_parsed) {
2611 ret = gst_matroska_parse_parse_tracks (parse, &ebml);
2613 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2615 case GST_MATROSKA_ID_CLUSTER:
2616 if (G_UNLIKELY (!parse->tracks_parsed)) {
2617 GST_DEBUG_OBJECT (parse, "Cluster before Track");
2618 goto not_streamable;
2620 if (G_UNLIKELY (parse->common.state
2621 == GST_MATROSKA_READ_STATE_HEADER)) {
2622 parse->common.state = GST_MATROSKA_READ_STATE_DATA;
2623 parse->first_cluster_offset = parse->common.offset;
2624 GST_DEBUG_OBJECT (parse, "signaling no more pads");
2626 parse->cluster_time = GST_CLOCK_TIME_NONE;
2627 parse->cluster_offset = parse->common.offset;
2628 if (G_UNLIKELY (!parse->seek_first && parse->seek_block)) {
2629 GST_DEBUG_OBJECT (parse, "seek target block %" G_GUINT64_FORMAT
2630 " not found in Cluster, trying next Cluster's first block instead",
2632 parse->seek_block = 0;
2634 parse->seek_first = FALSE;
2635 /* record next cluster for recovery */
2636 if (read != G_MAXUINT64)
2637 parse->next_cluster_offset = parse->cluster_offset + read;
2638 /* eat cluster prefix */
2639 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2640 ret = gst_matroska_parse_output (parse, ebml.buf, TRUE);
2641 //gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2643 case GST_MATROSKA_ID_CLUSTERTIMECODE:
2647 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2648 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
2650 GST_DEBUG_OBJECT (parse, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
2651 parse->cluster_time = num;
2653 if (parse->common.element_index) {
2654 if (parse->common.element_index_writer_id == -1)
2655 gst_index_get_writer_id (parse->common.element_index,
2656 GST_OBJECT (parse), &parse->common.element_index_writer_id);
2657 GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
2658 G_GUINT64_FORMAT " for writer id %d",
2659 GST_TIME_ARGS (parse->cluster_time), parse->cluster_offset,
2660 parse->common.element_index_writer_id);
2661 gst_index_add_association (parse->common.element_index,
2662 parse->common.element_index_writer_id,
2663 GST_ASSOCIATION_FLAG_KEY_UNIT,
2664 GST_FORMAT_TIME, parse->cluster_time,
2665 GST_FORMAT_BYTES, parse->cluster_offset, NULL);
2668 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2671 case GST_MATROSKA_ID_BLOCKGROUP:
2672 if (!gst_matroska_parse_seek_block (parse))
2674 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2675 DEBUG_ELEMENT_START (parse, &ebml, "BlockGroup");
2676 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
2677 ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
2678 &ebml, parse->cluster_time, parse->cluster_offset, FALSE);
2680 DEBUG_ELEMENT_STOP (parse, &ebml, "BlockGroup", ret);
2681 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2683 case GST_MATROSKA_ID_SIMPLEBLOCK:
2684 if (!gst_matroska_parse_seek_block (parse))
2686 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2687 DEBUG_ELEMENT_START (parse, &ebml, "SimpleBlock");
2688 ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
2689 &ebml, parse->cluster_time, parse->cluster_offset, TRUE);
2690 DEBUG_ELEMENT_STOP (parse, &ebml, "SimpleBlock", ret);
2691 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2693 case GST_MATROSKA_ID_ATTACHMENTS:
2694 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2695 if (!parse->common.attachments_parsed) {
2696 ret = gst_matroska_read_common_parse_attachments (&parse->common,
2697 GST_ELEMENT_CAST (parse), &ebml);
2698 if (ret == GST_FLOW_OK)
2699 gst_matroska_parse_send_tags (parse);
2701 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2703 case GST_MATROSKA_ID_TAGS:
2704 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2705 ret = gst_matroska_read_common_parse_metadata (&parse->common,
2706 GST_ELEMENT_CAST (parse), &ebml);
2707 if (ret == GST_FLOW_OK)
2708 gst_matroska_parse_send_tags (parse);
2709 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2711 case GST_MATROSKA_ID_CHAPTERS:
2712 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2713 ret = gst_matroska_read_common_parse_chapters (&parse->common, &ebml);
2714 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2716 case GST_MATROSKA_ID_SEEKHEAD:
2717 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2718 ret = gst_matroska_parse_parse_contents (parse, &ebml);
2719 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2721 case GST_MATROSKA_ID_CUES:
2722 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2723 if (!parse->common.index_parsed) {
2724 ret = gst_matroska_read_common_parse_index (&parse->common, &ebml);
2725 /* only push based; delayed index building */
2726 if (ret == GST_FLOW_OK
2727 && parse->common.state == GST_MATROSKA_READ_STATE_SEEK) {
2730 GST_OBJECT_LOCK (parse);
2731 event = parse->seek_event;
2732 parse->seek_event = NULL;
2733 GST_OBJECT_UNLOCK (parse);
2736 /* unlikely to fail, since we managed to seek to this point */
2737 if (!gst_matroska_parse_handle_seek_event (parse, NULL, event))
2739 /* resume data handling, main thread clear to seek again */
2740 GST_OBJECT_LOCK (parse);
2741 parse->common.state = GST_MATROSKA_READ_STATE_DATA;
2742 GST_OBJECT_UNLOCK (parse);
2745 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2747 case GST_MATROSKA_ID_POSITION:
2748 case GST_MATROSKA_ID_PREVSIZE:
2749 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
2750 case GST_MATROSKA_ID_SILENTTRACKS:
2751 GST_DEBUG_OBJECT (parse,
2752 "Skipping Cluster subelement 0x%x - ignoring", id);
2756 GST_DEBUG_OBJECT (parse, "skipping Element 0x%x", id);
2757 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2758 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2764 if (ret == GST_FLOW_PARSE)
2768 gst_ebml_read_clear (&ebml);
2774 /* simply exit, maybe not enough data yet */
2775 /* no ebml to clear if read error */
2780 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2781 ("Failed to parse Element 0x%x", id));
2782 ret = GST_FLOW_ERROR;
2787 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2788 ("File layout does not permit streaming"));
2789 ret = GST_FLOW_ERROR;
2795 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2796 ("No Tracks element found"));
2797 ret = GST_FLOW_ERROR;
2803 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Invalid header"));
2804 ret = GST_FLOW_ERROR;
2809 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Failed to seek"));
2810 ret = GST_FLOW_ERROR;
2817 gst_matroska_parse_loop (GstPad * pad)
2819 GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
2825 /* If we have to close a segment, send a new segment to do this now */
2826 if (G_LIKELY (parse->common.state == GST_MATROSKA_READ_STATE_DATA)) {
2827 if (G_UNLIKELY (parse->close_segment)) {
2828 gst_matroska_parse_send_event (parse, parse->close_segment);
2829 parse->close_segment = NULL;
2831 if (G_UNLIKELY (parse->new_segment)) {
2832 gst_matroska_parse_send_event (parse, parse->new_segment);
2833 parse->new_segment = NULL;
2837 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2838 GST_ELEMENT_CAST (parse), &id, &length, &needed);
2839 if (ret == GST_FLOW_EOS)
2841 if (ret != GST_FLOW_OK) {
2842 if (gst_matroska_parse_check_parse_error (parse))
2848 GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2849 "size %" G_GUINT64_FORMAT ", needed %d", parse->offset, id,
2852 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2853 if (ret == GST_FLOW_EOS)
2855 if (ret != GST_FLOW_OK)
2858 /* check if we're at the end of a configured segment */
2859 if (G_LIKELY (parse->src->len)) {
2862 g_assert (parse->num_streams == parse->src->len);
2863 for (i = 0; i < parse->src->len; i++) {
2864 GstMatroskaTrackContext *context = g_ptr_array_index (parse->src, i);
2865 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
2866 GST_TIME_ARGS (context->pos));
2867 if (context->eos == FALSE)
2871 GST_INFO_OBJECT (parse, "All streams are EOS");
2877 if (G_UNLIKELY (parse->offset ==
2878 gst_matroska_read_common_get_length (&parse->common))) {
2879 GST_LOG_OBJECT (parse, "Reached end of stream");
2889 if (parse->segment.rate < 0.0) {
2890 ret = gst_matroska_parse_seek_to_previous_keyframe (parse);
2891 if (ret == GST_FLOW_OK)
2898 const gchar *reason = gst_flow_get_name (ret);
2899 gboolean push_eos = FALSE;
2901 GST_LOG_OBJECT (parse, "pausing task, reason %s", reason);
2902 parse->segment_running = FALSE;
2903 gst_pad_pause_task (parse->common.sinkpad);
2905 if (ret == GST_FLOW_EOS) {
2906 /* perform EOS logic */
2908 /* Close the segment, i.e. update segment stop with the duration
2909 * if no stop was set */
2910 if (GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) &&
2911 !GST_CLOCK_TIME_IS_VALID (parse->segment.stop)) {
2913 gst_event_new_new_segment_full (TRUE, parse->segment.rate,
2914 parse->segment.applied_rate, parse->segment.format,
2915 parse->segment.start,
2916 MAX (parse->last_stop_end, parse->segment.start),
2917 parse->segment.time);
2918 gst_matroska_parse_send_event (parse, event);
2921 if (parse->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2924 /* for segment playback we need to post when (in stream time)
2925 * we stopped, this is either stop (when set) or the duration. */
2926 if ((stop = parse->segment.stop) == -1)
2927 stop = parse->last_stop_end;
2929 GST_LOG_OBJECT (parse, "Sending segment done, at end of segment");
2930 gst_element_post_message (GST_ELEMENT (parse),
2931 gst_message_new_segment_done (GST_OBJECT (parse), GST_FORMAT_TIME,
2933 gst_matroska_parse_send_event (parse,
2934 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
2938 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
2939 /* for fatal errors we post an error message */
2940 GST_ELEMENT_FLOW_ERROR (parse, ret);
2944 /* send EOS, and prevent hanging if no streams yet */
2945 GST_LOG_OBJECT (parse, "Sending EOS, at end of stream");
2946 if (!gst_matroska_parse_send_event (parse, gst_event_new_eos ()) &&
2947 (ret == GST_FLOW_EOS)) {
2948 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
2949 (NULL), ("got eos but no streams (yet)"));
2958 * Create and push a flushing seek event upstream
2961 perform_seek_to_offset (GstMatroskaParse * parse, guint64 offset)
2966 GST_DEBUG_OBJECT (parse, "Seeking to %" G_GUINT64_FORMAT, offset);
2969 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
2970 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
2971 GST_SEEK_TYPE_NONE, -1);
2973 res = gst_pad_push_event (parse->common.sinkpad, event);
2975 /* newsegment event will update offset */
2980 * Forge empty default caps when all we know is the stream's EBML
2981 * type and whether it has video or not.
2983 * FIXME: Do something with video/x-matroska-3d if possible
2986 gst_matroska_parse_forge_caps (gboolean is_webm, gboolean has_video)
2992 caps = gst_caps_new_empty_simple ("video/webm");
2994 caps = gst_caps_new_empty_simple ("audio/webm");
2997 caps = gst_caps_new_empty_simple ("video/x-matroska");
2999 caps = gst_caps_new_empty_simple ("audio/x-matroska");
3004 static GstFlowReturn
3005 gst_matroska_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
3007 GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
3009 GstFlowReturn ret = GST_FLOW_OK;
3014 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
3015 GST_DEBUG_OBJECT (parse, "got DISCONT");
3016 gst_adapter_clear (parse->common.adapter);
3017 GST_OBJECT_LOCK (parse);
3018 gst_matroska_read_common_reset_streams (&parse->common,
3019 GST_CLOCK_TIME_NONE, FALSE);
3020 GST_OBJECT_UNLOCK (parse);
3023 gst_adapter_push (parse->common.adapter, buffer);
3027 available = gst_adapter_available (parse->common.adapter);
3029 ret = gst_matroska_read_common_peek_id_length_push (&parse->common,
3030 GST_ELEMENT_CAST (parse), &id, &length, &needed);
3031 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
3032 if (parse->common.ebml_segment_length != G_MAXUINT64
3033 && parse->common.offset >=
3034 parse->common.ebml_segment_start + parse->common.ebml_segment_length) {
3035 return GST_FLOW_EOS;
3038 * parsing error: we need to flush a byte from the adapter if the id is
3039 * not a cluster and so on until we found a new cluser or the
3040 * INVALID_DATA_THRESHOLD is exceeded, we reuse gst_matroska_parse_parse_id
3041 * setting the state to GST_MATROSKA_READ_STATE_SCANNING so the bytes
3042 * are skipped until a new cluster is found
3044 gint64 bytes_scanned;
3045 if (parse->common.start_resync_offset == -1) {
3046 parse->common.start_resync_offset = parse->common.offset;
3047 parse->common.state_to_restore = parse->common.state;
3049 bytes_scanned = parse->common.offset - parse->common.start_resync_offset;
3050 if (bytes_scanned <= INVALID_DATA_THRESHOLD) {
3051 GST_WARNING_OBJECT (parse,
3052 "parse error, looking for next cluster, actual offset %"
3053 G_GUINT64_FORMAT ", start resync offset %" G_GUINT64_FORMAT,
3054 parse->common.offset, parse->common.start_resync_offset);
3055 parse->common.state = GST_MATROSKA_READ_STATE_SCANNING;
3058 GST_WARNING_OBJECT (parse,
3059 "unrecoverable parse error, next cluster not found and threshold "
3060 "exceeded, bytes scanned %" G_GINT64_FORMAT, bytes_scanned);
3066 GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
3067 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
3068 parse->common.offset, id, length, needed, available);
3070 if (needed > available)
3073 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
3074 if (ret == GST_FLOW_EOS) {
3075 /* need more data */
3077 } else if (ret != GST_FLOW_OK) {
3084 gst_matroska_parse_handle_sink_event (GstPad * pad, GstObject * parent,
3087 gboolean res = TRUE;
3088 GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
3090 GST_DEBUG_OBJECT (parse,
3091 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
3093 switch (GST_EVENT_TYPE (event)) {
3094 case GST_EVENT_SEGMENT:
3096 const GstSegment *segment;
3098 /* some debug output */
3099 gst_event_parse_segment (event, &segment);
3100 GST_DEBUG_OBJECT (parse,
3101 "received format %d newsegment %" GST_SEGMENT_FORMAT,
3102 segment->format, segment);
3104 if (parse->common.state < GST_MATROSKA_READ_STATE_DATA) {
3105 GST_DEBUG_OBJECT (parse, "still starting");
3109 /* we only expect a BYTE segment, e.g. following a seek */
3110 if (segment->format != GST_FORMAT_BYTES) {
3111 GST_DEBUG_OBJECT (parse, "unsupported segment format, ignoring");
3115 GST_DEBUG_OBJECT (parse, "clearing segment state");
3116 /* clear current segment leftover */
3117 gst_adapter_clear (parse->common.adapter);
3118 /* and some streaming setup */
3119 parse->common.offset = segment->start;
3120 /* do not know where we are;
3121 * need to come across a cluster and generate newsegment */
3122 parse->common.segment.position = GST_CLOCK_TIME_NONE;
3123 parse->cluster_time = GST_CLOCK_TIME_NONE;
3124 parse->cluster_offset = 0;
3125 parse->need_newsegment = TRUE;
3126 /* but keep some of the upstream segment */
3127 parse->common.segment.rate = segment->rate;
3129 /* chain will send initial newsegment after pads have been added,
3130 * or otherwise come up with one */
3131 GST_DEBUG_OBJECT (parse, "eating event");
3132 gst_event_unref (event);
3138 if (parse->common.state != GST_MATROSKA_READ_STATE_DATA
3139 && parse->common.state != GST_MATROSKA_READ_STATE_SCANNING) {
3140 gst_event_unref (event);
3141 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3142 (NULL), ("got eos and didn't receive a complete header object"));
3143 } else if (parse->common.num_streams == 0) {
3144 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3145 (NULL), ("got eos but no streams (yet)"));
3147 gst_matroska_parse_send_event (parse, event);
3151 case GST_EVENT_FLUSH_STOP:
3153 gst_adapter_clear (parse->common.adapter);
3154 GST_OBJECT_LOCK (parse);
3155 gst_matroska_read_common_reset_streams (&parse->common,
3156 GST_CLOCK_TIME_NONE, TRUE);
3157 GST_OBJECT_UNLOCK (parse);
3158 parse->common.segment.position = GST_CLOCK_TIME_NONE;
3159 parse->cluster_time = GST_CLOCK_TIME_NONE;
3160 parse->cluster_offset = 0;
3164 res = gst_pad_event_default (pad, parent, event);
3173 gst_matroska_parse_set_index (GstElement * element, GstIndex * index)
3175 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3177 GST_OBJECT_LOCK (parse);
3178 if (parse->common.element_index)
3179 gst_object_unref (parse->common.element_index);
3180 parse->common.element_index = index ? gst_object_ref (index) : NULL;
3181 GST_OBJECT_UNLOCK (parse);
3182 GST_DEBUG_OBJECT (parse, "Set index %" GST_PTR_FORMAT,
3183 parse->common.element_index);
3187 gst_matroska_parse_get_index (GstElement * element)
3189 GstIndex *result = NULL;
3190 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3192 GST_OBJECT_LOCK (parse);
3193 if (parse->common.element_index)
3194 result = gst_object_ref (parse->common.element_index);
3195 GST_OBJECT_UNLOCK (parse);
3197 GST_DEBUG_OBJECT (parse, "Returning index %" GST_PTR_FORMAT, result);
3203 static GstStateChangeReturn
3204 gst_matroska_parse_change_state (GstElement * element,
3205 GstStateChange transition)
3207 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3208 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
3210 /* handle upwards state changes here */
3211 switch (transition) {
3216 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
3218 /* handle downwards state changes */
3219 switch (transition) {
3220 case GST_STATE_CHANGE_PAUSED_TO_READY:
3221 gst_matroska_parse_reset (GST_ELEMENT (parse));
3231 gst_matroska_parse_plugin_init (GstPlugin * plugin)
3235 /* create an elementfactory for the matroska_parse element */
3236 if (!gst_element_register (plugin, "matroskaparse",
3237 GST_RANK_NONE, GST_TYPE_MATROSKA_PARSE))