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 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
548 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
549 GST_DEBUG_OBJECT (parse, "TrackVideoInterlaced: %d",
550 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
555 /* aspect ratio behaviour */
556 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
559 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
562 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
563 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
564 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
565 GST_WARNING_OBJECT (parse,
566 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
569 GST_DEBUG_OBJECT (parse,
570 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
571 videocontext->asr_mode = num;
575 /* colourspace (only matters for raw video) fourcc */
576 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
581 gst_ebml_read_binary (ebml, &id, &data,
582 &datalen)) != GST_FLOW_OK)
587 GST_WARNING_OBJECT (parse,
588 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
593 memcpy (&videocontext->fourcc, data, 4);
594 GST_DEBUG_OBJECT (parse,
595 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
596 GST_FOURCC_ARGS (videocontext->fourcc));
602 GST_WARNING_OBJECT (parse,
603 "Unknown TrackVideo subelement 0x%x - ignoring", id);
605 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
606 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
607 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
608 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
609 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
610 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
611 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
612 ret = gst_ebml_read_skip (ebml);
617 DEBUG_ELEMENT_STOP (parse, ebml, "TrackVideo", ret);
621 /* tracktype specific stuff for audio */
622 case GST_MATROSKA_ID_TRACKAUDIO:{
623 GstMatroskaTrackAudioContext *audiocontext;
625 DEBUG_ELEMENT_START (parse, ebml, "TrackAudio");
627 if (!gst_matroska_track_init_audio_context (&context)) {
628 GST_WARNING_OBJECT (parse,
629 "TrackAudio element in non-audio track - ignoring track");
630 ret = GST_FLOW_ERROR;
634 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
637 audiocontext = (GstMatroskaTrackAudioContext *) context;
638 g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
641 while (ret == GST_FLOW_OK &&
642 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
643 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
648 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
651 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
656 GST_WARNING_OBJECT (parse,
657 "Invalid TrackAudioSamplingFrequency %lf", num);
661 GST_DEBUG_OBJECT (parse, "TrackAudioSamplingFrequency: %lf", num);
662 audiocontext->samplerate = num;
667 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
670 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
674 GST_WARNING_OBJECT (parse, "Invalid TrackAudioBitDepth 0");
678 GST_DEBUG_OBJECT (parse, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
680 audiocontext->bitdepth = num;
685 case GST_MATROSKA_ID_AUDIOCHANNELS:{
688 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
692 GST_WARNING_OBJECT (parse, "Invalid TrackAudioChannels 0");
696 GST_DEBUG_OBJECT (parse, "TrackAudioChannels: %" G_GUINT64_FORMAT,
698 audiocontext->channels = num;
703 GST_WARNING_OBJECT (parse,
704 "Unknown TrackAudio subelement 0x%x - ignoring", id);
706 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
707 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
708 ret = gst_ebml_read_skip (ebml);
713 DEBUG_ELEMENT_STOP (parse, ebml, "TrackAudio", ret);
718 /* codec identifier */
719 case GST_MATROSKA_ID_CODECID:{
722 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
725 GST_DEBUG_OBJECT (parse, "CodecID: %s", GST_STR_NULL (text));
726 context->codec_id = text;
730 /* codec private data */
731 case GST_MATROSKA_ID_CODECPRIVATE:{
736 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
739 context->codec_priv = data;
740 context->codec_priv_size = size;
742 GST_DEBUG_OBJECT (parse, "CodecPrivate of size %" G_GUINT64_FORMAT,
747 /* name of the codec */
748 case GST_MATROSKA_ID_CODECNAME:{
751 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
754 GST_DEBUG_OBJECT (parse, "CodecName: %s", GST_STR_NULL (text));
755 context->codec_name = text;
759 /* name of this track */
760 case GST_MATROSKA_ID_TRACKNAME:{
763 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
766 context->name = text;
767 GST_DEBUG_OBJECT (parse, "TrackName: %s", GST_STR_NULL (text));
771 /* language (matters for audio/subtitles, mostly) */
772 case GST_MATROSKA_ID_TRACKLANGUAGE:{
775 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
779 context->language = text;
782 if (strlen (context->language) >= 4 && context->language[3] == '-')
783 context->language[3] = '\0';
785 GST_DEBUG_OBJECT (parse, "TrackLanguage: %s",
786 GST_STR_NULL (context->language));
790 /* whether this is actually used */
791 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
794 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
798 context->flags |= GST_MATROSKA_TRACK_ENABLED;
800 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
802 GST_DEBUG_OBJECT (parse, "TrackEnabled: %d",
803 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
807 /* whether it's the default for this track type */
808 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
811 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
815 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
817 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
819 GST_DEBUG_OBJECT (parse, "TrackDefault: %d",
820 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
824 /* whether the track must be used during playback */
825 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
828 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
832 context->flags |= GST_MATROSKA_TRACK_FORCED;
834 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
836 GST_DEBUG_OBJECT (parse, "TrackForced: %d",
837 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
841 /* lacing (like MPEG, where blocks don't end/start on frame
843 case GST_MATROSKA_ID_TRACKFLAGLACING:{
846 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
850 context->flags |= GST_MATROSKA_TRACK_LACING;
852 context->flags &= ~GST_MATROSKA_TRACK_LACING;
854 GST_DEBUG_OBJECT (parse, "TrackLacing: %d",
855 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
859 /* default length (in time) of one data block in this track */
860 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
863 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
868 GST_WARNING_OBJECT (parse, "Invalid TrackDefaultDuration 0");
872 GST_DEBUG_OBJECT (parse, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
874 context->default_duration = num;
878 case GST_MATROSKA_ID_CONTENTENCODINGS:{
879 ret = gst_matroska_read_common_read_track_encodings (&parse->common,
884 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
887 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
891 GST_WARNING_OBJECT (parse, "Invalid TrackTimeCodeScale %lf", num);
895 GST_DEBUG_OBJECT (parse, "TrackTimeCodeScale: %lf", num);
896 context->timecodescale = num;
901 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
904 /* we ignore these because they're nothing useful (i.e. crap)
905 * or simply not implemented yet. */
906 case GST_MATROSKA_ID_TRACKMINCACHE:
907 case GST_MATROSKA_ID_TRACKMAXCACHE:
908 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
909 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
910 case GST_MATROSKA_ID_TRACKOVERLAY:
911 case GST_MATROSKA_ID_TRACKTRANSLATE:
912 case GST_MATROSKA_ID_TRACKOFFSET:
913 case GST_MATROSKA_ID_CODECSETTINGS:
914 case GST_MATROSKA_ID_CODECINFOURL:
915 case GST_MATROSKA_ID_CODECDOWNLOADURL:
916 case GST_MATROSKA_ID_CODECDECODEALL:
917 ret = gst_ebml_read_skip (ebml);
922 DEBUG_ELEMENT_STOP (parse, ebml, "TrackEntry", ret);
924 /* Decode codec private data if necessary */
925 if (context->encodings && context->encodings->len > 0 && context->codec_priv
926 && context->codec_priv_size > 0) {
927 if (!gst_matroska_decode_data (context->encodings,
928 &context->codec_priv, &context->codec_priv_size,
929 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
930 GST_WARNING_OBJECT (parse, "Decoding codec private data failed");
931 ret = GST_FLOW_ERROR;
935 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
936 && ret != GST_FLOW_EOS)) {
937 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
938 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
940 parse->common.num_streams--;
941 g_ptr_array_remove_index (parse->common.src, parse->common.num_streams);
942 g_assert (parse->common.src->len == parse->common.num_streams);
943 gst_matroska_track_free (context);
948 if ((context->language == NULL || *context->language == '\0') &&
949 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
950 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
951 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
952 context->language = g_strdup ("eng");
961 gst_matroska_parse_query (GstMatroskaParse * parse, GstPad * pad,
964 gboolean res = FALSE;
965 GstMatroskaTrackContext *context = NULL;
968 context = gst_pad_get_element_private (pad);
971 switch (GST_QUERY_TYPE (query)) {
972 case GST_QUERY_POSITION:
976 gst_query_parse_position (query, &format, NULL);
978 if (format == GST_FORMAT_TIME) {
979 GST_OBJECT_LOCK (parse);
981 gst_query_set_position (query, GST_FORMAT_TIME, context->pos);
983 gst_query_set_position (query, GST_FORMAT_TIME,
984 parse->common.segment.position);
985 GST_OBJECT_UNLOCK (parse);
986 } else if (format == GST_FORMAT_DEFAULT && context
987 && context->default_duration) {
988 GST_OBJECT_LOCK (parse);
989 gst_query_set_position (query, GST_FORMAT_DEFAULT,
990 context->pos / context->default_duration);
991 GST_OBJECT_UNLOCK (parse);
993 GST_DEBUG_OBJECT (parse,
994 "only position query in TIME and DEFAULT format is supported");
1000 case GST_QUERY_DURATION:
1004 gst_query_parse_duration (query, &format, NULL);
1006 if (format == GST_FORMAT_TIME) {
1007 GST_OBJECT_LOCK (parse);
1008 gst_query_set_duration (query, GST_FORMAT_TIME,
1009 parse->common.segment.duration);
1010 GST_OBJECT_UNLOCK (parse);
1011 } else if (format == GST_FORMAT_DEFAULT && context
1012 && context->default_duration) {
1013 GST_OBJECT_LOCK (parse);
1014 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1015 parse->common.segment.duration / context->default_duration);
1016 GST_OBJECT_UNLOCK (parse);
1018 GST_DEBUG_OBJECT (parse,
1019 "only duration query in TIME and DEFAULT format is supported");
1026 case GST_QUERY_SEEKING:
1030 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1031 if (fmt == GST_FORMAT_TIME) {
1034 /* assuming we'll be able to get an index ... */
1035 seekable = parse->seekable;
1037 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1038 0, parse->common.segment.duration);
1045 res = gst_pad_query_default (pad, (GstObject *) parse, query);
1053 gst_matroska_parse_element_query (GstElement * element, GstQuery * query)
1055 return gst_matroska_parse_query (GST_MATROSKA_PARSE (element), NULL, query);
1059 gst_matroska_parse_handle_src_query (GstPad * pad, GstObject * parent,
1063 GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
1065 ret = gst_matroska_parse_query (parse, pad, query);
1071 gst_matroska_parse_send_tags (GstMatroskaParse * parse)
1073 if (G_UNLIKELY (parse->common.global_tags_changed)) {
1074 GstEvent *tag_event;
1075 gst_tag_list_add (parse->common.global_tags, GST_TAG_MERGE_REPLACE,
1076 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1077 GST_DEBUG_OBJECT (parse, "Sending global_tags %p : %" GST_PTR_FORMAT,
1078 parse->common.global_tags, parse->common.global_tags);
1080 /* Send a copy as we want to keep our local ref writable to add more tags
1081 * if any are found */
1083 gst_event_new_tag (gst_tag_list_copy (parse->common.global_tags));
1085 gst_pad_push_event (parse->srcpad, tag_event);
1087 parse->common.global_tags_changed = FALSE;
1091 /* returns FALSE if there are no pads to deliver event to,
1092 * otherwise TRUE (whatever the outcome of event sending),
1093 * takes ownership of the passed event! */
1095 gst_matroska_parse_send_event (GstMatroskaParse * parse, GstEvent * event)
1097 gboolean ret = FALSE;
1099 g_return_val_if_fail (event != NULL, FALSE);
1101 GST_DEBUG_OBJECT (parse, "Sending event of type %s to all source pads",
1102 GST_EVENT_TYPE_NAME (event));
1104 gst_pad_push_event (parse->srcpad, event);
1110 gst_matroska_parse_element_send_event (GstElement * element, GstEvent * event)
1112 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
1115 g_return_val_if_fail (event != NULL, FALSE);
1117 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1118 res = gst_matroska_parse_handle_seek_event (parse, NULL, event);
1120 GST_WARNING_OBJECT (parse, "Unhandled event of type %s",
1121 GST_EVENT_TYPE_NAME (event));
1124 gst_event_unref (event);
1129 /* searches for a cluster start from @pos,
1130 * return GST_FLOW_OK and cluster position in @pos if found */
1131 static GstFlowReturn
1132 gst_matroska_parse_search_cluster (GstMatroskaParse * parse, gint64 * pos)
1134 gint64 newpos = *pos;
1136 GstFlowReturn ret = GST_FLOW_OK;
1137 const guint chunk = 64 * 1024;
1146 orig_offset = parse->common.offset;
1148 /* read in at newpos and scan for ebml cluster id */
1150 GstByteReader reader;
1154 ret = gst_pad_pull_range (parse->common.sinkpad, newpos, chunk, &buf);
1155 if (ret != GST_FLOW_OK)
1157 GST_DEBUG_OBJECT (parse,
1158 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1159 gst_buffer_get_size (buf), newpos);
1160 gst_buffer_map (buf, &map, GST_MAP_READ);
1163 gst_byte_reader_init (&reader, data, size);
1166 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1167 GST_MATROSKA_ID_CLUSTER, cluster_pos, size - cluster_pos);
1168 if (cluster_pos >= 0) {
1169 newpos += cluster_pos;
1170 GST_DEBUG_OBJECT (parse,
1171 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1172 /* extra checks whether we really sync'ed to a cluster:
1173 * - either it is the first and only cluster
1174 * - either there is a cluster after this one
1175 * - either cluster length is undefined
1177 /* ok if first cluster (there may not a subsequent one) */
1178 if (newpos == parse->first_cluster_offset) {
1179 GST_DEBUG_OBJECT (parse, "cluster is first cluster -> OK");
1182 parse->common.offset = newpos;
1183 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1184 GST_ELEMENT_CAST (parse), &id, &length, &needed);
1185 if (ret != GST_FLOW_OK)
1187 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1188 GST_DEBUG_OBJECT (parse, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1190 /* ok if undefined length or first cluster */
1191 if (length == G_MAXUINT64) {
1192 GST_DEBUG_OBJECT (parse, "cluster has undefined length -> OK");
1196 parse->common.offset += length + needed;
1197 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1198 GST_ELEMENT_CAST (parse), &id, &length, &needed);
1199 if (ret != GST_FLOW_OK)
1201 GST_DEBUG_OBJECT (parse, "next element is %scluster",
1202 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1203 if (id == GST_MATROSKA_ID_CLUSTER)
1205 /* not ok, resume */
1208 /* partial cluster id may have been in tail of buffer */
1209 newpos += MAX (size, 4) - 3;
1210 gst_buffer_unmap (buf, &map);
1211 gst_buffer_unref (buf);
1217 gst_buffer_unmap (buf, &map);
1218 gst_buffer_unref (buf);
1222 parse->common.offset = orig_offset;
1229 gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
1230 GstPad * pad, GstEvent * event)
1232 GstMatroskaIndex *entry = NULL;
1234 GstSeekType cur_type, stop_type;
1238 GstMatroskaTrackContext *track = NULL;
1239 GstSegment seeksegment = { 0, };
1241 GstSearchMode snap_dir;
1244 track = gst_pad_get_element_private (pad);
1246 track = gst_matroska_read_common_get_seek_track (&parse->common, track);
1248 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1251 /* we can only seek on time */
1252 if (format != GST_FORMAT_TIME) {
1253 GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1257 /* copy segment, we need this because we still need the old
1258 * segment when we close the current segment. */
1259 memcpy (&seeksegment, &parse->common.segment, sizeof (GstSegment));
1262 GST_DEBUG_OBJECT (parse, "configuring seek");
1263 gst_segment_do_seek (&seeksegment, rate, format, flags,
1264 cur_type, cur, stop_type, stop, &update);
1267 GST_DEBUG_OBJECT (parse, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1269 if (seeksegment.rate < 0)
1270 snap_dir = GST_SEARCH_MODE_AFTER;
1272 snap_dir = GST_SEARCH_MODE_BEFORE;
1274 /* check sanity before we start flushing and all that */
1275 GST_OBJECT_LOCK (parse);
1276 if ((entry = gst_matroska_read_common_do_index_seek (&parse->common, track,
1277 seeksegment.position, &parse->seek_index, &parse->seek_entry,
1278 snap_dir)) == NULL) {
1279 /* pull mode without index can scan later on */
1280 GST_DEBUG_OBJECT (parse, "No matching seek entry in index");
1281 GST_OBJECT_UNLOCK (parse);
1284 GST_DEBUG_OBJECT (parse, "Seek position looks sane");
1285 GST_OBJECT_UNLOCK (parse);
1287 /* need to seek to cluster start to pick up cluster time */
1288 /* upstream takes care of flushing and all that
1289 * ... and newsegment event handling takes care of the rest */
1290 return perform_seek_to_offset (parse, entry->pos
1291 + parse->common.ebml_segment_start);
1295 * Handle whether we can perform the seek event or if we have to let the chain
1296 * function handle seeks to build the seek indexes first.
1299 gst_matroska_parse_handle_seek_push (GstMatroskaParse * parse, GstPad * pad,
1303 GstSeekType cur_type, stop_type;
1308 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1313 /* we can only seek on time */
1314 if (format != GST_FORMAT_TIME) {
1315 GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1319 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
1320 GST_DEBUG_OBJECT (parse, "Seek end-time not supported in streaming mode");
1324 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
1325 GST_DEBUG_OBJECT (parse,
1326 "Non-flushing seek not supported in streaming mode");
1330 if (flags & GST_SEEK_FLAG_SEGMENT) {
1331 GST_DEBUG_OBJECT (parse, "Segment seek not supported in streaming mode");
1335 /* check for having parsed index already */
1336 if (!parse->common.index_parsed) {
1337 gboolean building_index;
1340 if (!parse->index_offset) {
1341 GST_DEBUG_OBJECT (parse, "no index (location); no seek in push mode");
1345 GST_OBJECT_LOCK (parse);
1346 /* handle the seek event in the chain function */
1347 parse->common.state = GST_MATROSKA_READ_STATE_SEEK;
1348 /* no more seek can be issued until state reset to _DATA */
1350 /* copy the event */
1351 if (parse->seek_event)
1352 gst_event_unref (parse->seek_event);
1353 parse->seek_event = gst_event_ref (event);
1355 /* set the building_index flag so that only one thread can setup the
1356 * structures for index seeking. */
1357 building_index = parse->building_index;
1358 if (!building_index) {
1359 parse->building_index = TRUE;
1360 offset = parse->index_offset;
1362 GST_OBJECT_UNLOCK (parse);
1364 if (!building_index) {
1365 /* seek to the first subindex or legacy index */
1366 GST_INFO_OBJECT (parse, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
1367 return perform_seek_to_offset (parse, offset);
1370 /* well, we are handling it already */
1374 /* delegate to tweaked regular seek */
1375 return gst_matroska_parse_handle_seek_event (parse, pad, event);
1379 gst_matroska_parse_handle_src_event (GstPad * pad, GstObject * parent,
1382 GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
1383 gboolean res = TRUE;
1385 switch (GST_EVENT_TYPE (event)) {
1386 case GST_EVENT_SEEK:
1387 /* no seeking until we are (safely) ready */
1388 if (parse->common.state != GST_MATROSKA_READ_STATE_DATA) {
1389 GST_DEBUG_OBJECT (parse, "not ready for seeking yet");
1392 res = gst_matroska_parse_handle_seek_push (parse, pad, event);
1393 gst_event_unref (event);
1398 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
1399 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
1400 GstMatroskaTrackVideoContext *videocontext =
1401 (GstMatroskaTrackVideoContext *) context;
1403 GstClockTimeDiff diff;
1404 GstClockTime timestamp;
1406 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
1408 GST_OBJECT_LOCK (parse);
1409 videocontext->earliest_time = timestamp + diff;
1410 GST_OBJECT_UNLOCK (parse);
1413 gst_event_unref (event);
1417 /* events we don't need to handle */
1418 case GST_EVENT_NAVIGATION:
1419 gst_event_unref (event);
1423 case GST_EVENT_LATENCY:
1425 res = gst_pad_push_event (parse->common.sinkpad, event);
1432 static GstFlowReturn
1433 gst_matroska_parse_parse_tracks (GstMatroskaParse * parse, GstEbmlRead * ebml)
1435 GstFlowReturn ret = GST_FLOW_OK;
1438 DEBUG_ELEMENT_START (parse, ebml, "Tracks");
1440 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1441 DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1445 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1446 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1450 /* one track within the "all-tracks" header */
1451 case GST_MATROSKA_ID_TRACKENTRY:
1452 ret = gst_matroska_parse_add_stream (parse, ebml);
1456 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1461 DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1463 parse->tracks_parsed = TRUE;
1469 * Read signed/unsigned "EBML" numbers.
1470 * Return: number of bytes processed.
1474 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
1476 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
1484 while (read <= 8 && !(total & len_mask)) {
1491 if ((total &= (len_mask - 1)) == len_mask - 1)
1496 if (data[n] == 0xff)
1498 total = (total << 8) | data[n];
1502 if (read == num_ffs && total != 0)
1511 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
1516 /* read as unsigned number first */
1517 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
1521 if (unum == G_MAXUINT64)
1524 *num = unum - ((1 << ((7 * res) - 1)) - 1);
1529 static GstFlowReturn
1530 gst_matroska_parse_parse_blockgroup_or_simpleblock (GstMatroskaParse * parse,
1531 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
1532 gboolean is_simpleblock)
1534 GstMatroskaTrackContext *stream = NULL;
1535 GstFlowReturn ret = GST_FLOW_OK;
1536 gboolean readblock = FALSE;
1538 guint64 block_duration = 0;
1539 GstBuffer *buf = NULL;
1541 gint stream_num = -1, n, laces = 0;
1543 gint *lace_size = NULL;
1546 gint64 referenceblock = 0;
1548 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1549 if (!is_simpleblock) {
1550 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
1554 id = GST_MATROSKA_ID_SIMPLEBLOCK;
1558 /* one block inside the group. Note, block parsing is one
1559 * of the harder things, so this code is a bit complicated.
1560 * See http://www.matroska.org/ for documentation. */
1561 case GST_MATROSKA_ID_SIMPLEBLOCK:
1562 case GST_MATROSKA_ID_BLOCK:
1568 gst_buffer_unref (buf);
1571 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
1574 gst_buffer_map (buf, &map, GST_MAP_READ);
1578 /* first byte(s): blocknum */
1579 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1584 /* fetch stream from num */
1585 stream_num = gst_matroska_read_common_stream_from_num (&parse->common,
1587 if (G_UNLIKELY (size < 3)) {
1588 GST_WARNING_OBJECT (parse, "Invalid size %u", size);
1589 /* non-fatal, try next block(group) */
1592 } else if (G_UNLIKELY (stream_num < 0 ||
1593 stream_num >= parse->common.num_streams)) {
1594 /* let's not give up on a stray invalid track number */
1595 GST_WARNING_OBJECT (parse,
1596 "Invalid stream %d for track number %" G_GUINT64_FORMAT
1597 "; ignoring block", stream_num, num);
1601 stream = g_ptr_array_index (parse->common.src, stream_num);
1603 /* time (relative to cluster time) */
1604 time = ((gint16) GST_READ_UINT16_BE (data));
1607 flags = GST_READ_UINT8 (data);
1611 GST_LOG_OBJECT (parse, "time %" G_GUINT64_FORMAT ", flags %d", time,
1614 switch ((flags & 0x06) >> 1) {
1615 case 0x0: /* no lacing */
1617 lace_size = g_new (gint, 1);
1618 lace_size[0] = size;
1621 case 0x1: /* xiph lacing */
1622 case 0x2: /* fixed-size lacing */
1623 case 0x3: /* EBML lacing */
1625 goto invalid_lacing;
1626 laces = GST_READ_UINT8 (data) + 1;
1629 lace_size = g_new0 (gint, laces);
1631 switch ((flags & 0x06) >> 1) {
1632 case 0x1: /* xiph lacing */ {
1633 guint temp, total = 0;
1635 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
1638 goto invalid_lacing;
1639 temp = GST_READ_UINT8 (data);
1640 lace_size[n] += temp;
1646 total += lace_size[n];
1648 lace_size[n] = size - total;
1652 case 0x2: /* fixed-size lacing */
1653 for (n = 0; n < laces; n++)
1654 lace_size[n] = size / laces;
1657 case 0x3: /* EBML lacing */ {
1660 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1664 total = lace_size[0] = num;
1665 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
1669 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
1673 lace_size[n] = lace_size[n - 1] + snum;
1674 total += lace_size[n];
1677 lace_size[n] = size - total;
1684 if (ret != GST_FLOW_OK)
1691 case GST_MATROSKA_ID_BLOCKDURATION:{
1692 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
1693 GST_DEBUG_OBJECT (parse, "BlockDuration: %" G_GUINT64_FORMAT,
1698 case GST_MATROSKA_ID_REFERENCEBLOCK:{
1699 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
1700 GST_DEBUG_OBJECT (parse, "ReferenceBlock: %" G_GINT64_FORMAT,
1705 case GST_MATROSKA_ID_CODECSTATE:{
1707 guint64 data_len = 0;
1710 gst_ebml_read_binary (ebml, &id, &data,
1711 &data_len)) != GST_FLOW_OK)
1714 if (G_UNLIKELY (stream == NULL)) {
1715 GST_WARNING_OBJECT (parse,
1716 "Unexpected CodecState subelement - ignoring");
1720 g_free (stream->codec_state);
1721 stream->codec_state = data;
1722 stream->codec_state_size = data_len;
1728 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1732 case GST_MATROSKA_ID_BLOCKVIRTUAL:
1733 case GST_MATROSKA_ID_BLOCKADDITIONS:
1734 case GST_MATROSKA_ID_REFERENCEPRIORITY:
1735 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
1736 case GST_MATROSKA_ID_SLICES:
1737 GST_DEBUG_OBJECT (parse,
1738 "Skipping BlockGroup subelement 0x%x - ignoring", id);
1739 ret = gst_ebml_read_skip (ebml);
1747 /* reading a number or so could have failed */
1748 if (ret != GST_FLOW_OK)
1751 if (ret == GST_FLOW_OK && readblock) {
1752 guint64 duration = 0;
1753 gint64 lace_time = 0;
1754 gboolean delta_unit;
1756 stream = g_ptr_array_index (parse->common.src, stream_num);
1758 if (cluster_time != GST_CLOCK_TIME_NONE) {
1759 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
1760 * Drop unless the lace contains timestamp 0? */
1761 if (time < 0 && (-time) > cluster_time) {
1764 if (stream->timecodescale == 1.0)
1765 lace_time = (cluster_time + time) * parse->common.time_scale;
1768 gst_util_guint64_to_gdouble ((cluster_time + time) *
1769 parse->common.time_scale) * stream->timecodescale;
1772 lace_time = GST_CLOCK_TIME_NONE;
1775 if (lace_time != GST_CLOCK_TIME_NONE) {
1776 parse->last_timestamp = lace_time;
1778 /* need to refresh segment info ASAP */
1779 if (GST_CLOCK_TIME_IS_VALID (lace_time) && parse->need_newsegment) {
1781 GST_DEBUG_OBJECT (parse,
1782 "generating segment starting at %" GST_TIME_FORMAT,
1783 GST_TIME_ARGS (lace_time));
1784 /* pretend we seeked here */
1785 gst_segment_do_seek (&parse->common.segment, parse->common.segment.rate,
1786 GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, lace_time,
1787 GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE, NULL);
1788 /* now convey our segment notion downstream */
1789 segment = parse->common.segment;
1790 segment.position = segment.start;
1791 gst_matroska_parse_send_event (parse, gst_event_new_segment (&segment));
1792 parse->need_newsegment = FALSE;
1795 if (block_duration) {
1796 if (stream->timecodescale == 1.0)
1797 duration = gst_util_uint64_scale (block_duration,
1798 parse->common.time_scale, 1);
1801 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
1802 (gst_util_uint64_scale (block_duration, parse->common.time_scale,
1803 1)) * stream->timecodescale);
1804 } else if (stream->default_duration) {
1805 duration = stream->default_duration * laces;
1807 /* else duration is diff between timecode of this and next block */
1809 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
1810 a ReferenceBlock implies that this is not a keyframe. In either
1811 case, it only makes sense for video streams. */
1812 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1813 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
1815 if (delta_unit && stream->set_discont) {
1816 /* When doing seeks or such, we need to restart on key frames or
1817 * decoders might choke. */
1818 GST_DEBUG_OBJECT (parse, "skipping delta unit");
1822 for (n = 0; n < laces; n++) {
1823 if (G_UNLIKELY (lace_size[n] > size)) {
1824 GST_WARNING_OBJECT (parse, "Invalid lace size");
1828 /* QoS for video track with an index. the assumption is that
1829 index entries point to keyframes, but if that is not true we
1830 will instad skip until the next keyframe. */
1831 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1832 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1833 stream->index_table && parse->common.segment.rate > 0.0) {
1834 GstMatroskaTrackVideoContext *videocontext =
1835 (GstMatroskaTrackVideoContext *) stream;
1836 GstClockTime earliest_time;
1837 GstClockTime earliest_stream_time;
1839 GST_OBJECT_LOCK (parse);
1840 earliest_time = videocontext->earliest_time;
1841 GST_OBJECT_UNLOCK (parse);
1842 earliest_stream_time =
1843 gst_segment_position_from_running_time (&parse->common.segment,
1844 GST_FORMAT_TIME, earliest_time);
1846 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1847 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
1848 lace_time <= earliest_stream_time) {
1849 /* find index entry (keyframe) <= earliest_stream_time */
1850 GstMatroskaIndex *entry =
1851 gst_util_array_binary_search (stream->index_table->data,
1852 stream->index_table->len, sizeof (GstMatroskaIndex),
1853 (GCompareDataFunc) gst_matroska_index_seek_find,
1854 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
1856 /* if that entry (keyframe) is after the current the current
1857 buffer, we can skip pushing (and thus decoding) all
1858 buffers until that keyframe. */
1859 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
1860 entry->time > lace_time) {
1861 GST_LOG_OBJECT (parse, "Skipping lace before late keyframe");
1862 stream->set_discont = TRUE;
1868 sub = gst_buffer_create_sub (buf,
1869 GST_BUFFER_SIZE (buf) - size, lace_size[n]);
1870 GST_DEBUG_OBJECT (parse, "created subbuffer %p", sub);
1873 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1875 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1877 if (stream->encodings != NULL && stream->encodings->len > 0)
1878 sub = gst_matroska_decode_buffer (stream, sub);
1881 GST_WARNING_OBJECT (parse, "Decoding buffer failed");
1885 GST_BUFFER_TIMESTAMP (sub) = lace_time;
1887 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
1888 GstClockTime last_stop_end;
1890 /* Check if this stream is after segment stop */
1891 if (GST_CLOCK_TIME_IS_VALID (parse->common.segment.stop) &&
1892 lace_time >= parse->common.segment.stop) {
1893 GST_DEBUG_OBJECT (parse,
1894 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
1895 GST_TIME_ARGS (parse->common.segment.stop));
1896 gst_buffer_unref (sub);
1899 if (offset >= stream->to_offset) {
1900 GST_DEBUG_OBJECT (parse, "Stream %d after playback section",
1902 gst_buffer_unref (sub);
1906 /* handle gaps, e.g. non-zero start-time, or an cue index entry
1907 * that landed us with timestamps not quite intended */
1908 if (GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop) &&
1909 parse->segment.rate > 0.0) {
1910 GstClockTimeDiff diff;
1912 /* only send newsegments with increasing start times,
1913 * otherwise if these go back and forth downstream (sinks) increase
1914 * accumulated time and running_time */
1915 diff = GST_CLOCK_DIFF (parse->segment.last_stop, lace_time);
1916 if (diff > 2 * GST_SECOND && lace_time > parse->segment.start &&
1917 (!GST_CLOCK_TIME_IS_VALID (parse->segment.stop) ||
1918 lace_time < parse->segment.stop)) {
1919 GST_DEBUG_OBJECT (parse,
1920 "Gap of %" G_GINT64_FORMAT " ns detected in"
1921 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
1922 "Sending updated NEWSEGMENT events", diff,
1923 stream->index, GST_TIME_ARGS (stream->pos),
1924 GST_TIME_ARGS (lace_time));
1925 /* send newsegment events such that the gap is not accounted in
1926 * accum time, hence running_time */
1927 /* close ahead of gap */
1928 gst_matroska_parse_send_event (parse,
1929 gst_event_new_new_segment (TRUE, parse->segment.rate,
1930 parse->segment.format, parse->segment.last_stop,
1931 parse->segment.last_stop, parse->segment.last_stop));
1933 gst_matroska_parse_send_event (parse,
1934 gst_event_new_new_segment (FALSE, parse->segment.rate,
1935 parse->segment.format, lace_time, parse->segment.stop,
1937 /* align segment view with downstream,
1938 * prevents double-counting accum when closing segment */
1939 gst_segment_set_newsegment (&parse->segment, FALSE,
1940 parse->segment.rate, parse->segment.format, lace_time,
1941 parse->segment.stop, lace_time);
1942 parse->segment.last_stop = lace_time;
1946 if (!GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop)
1947 || parse->segment.last_stop < lace_time) {
1948 parse->segment.last_stop = lace_time;
1951 last_stop_end = lace_time;
1953 GST_BUFFER_DURATION (sub) = duration / laces;
1954 last_stop_end += GST_BUFFER_DURATION (sub);
1957 if (!GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) ||
1958 parse->last_stop_end < last_stop_end)
1959 parse->last_stop_end = last_stop_end;
1961 if (parse->segment.duration == -1 ||
1962 parse->segment.duration < lace_time) {
1963 gst_segment_set_duration (&parse->segment, GST_FORMAT_TIME,
1965 gst_element_post_message (GST_ELEMENT_CAST (parse),
1966 gst_message_new_duration (GST_OBJECT_CAST (parse),
1967 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
1971 stream->pos = lace_time;
1973 gst_matroska_parse_sync_streams (parse);
1975 if (stream->set_discont) {
1976 GST_DEBUG_OBJECT (parse, "marking DISCONT");
1977 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
1978 stream->set_discont = FALSE;
1981 /* reverse playback book-keeping */
1982 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
1983 stream->from_time = lace_time;
1984 if (stream->from_offset == -1)
1985 stream->from_offset = offset;
1987 GST_DEBUG_OBJECT (parse,
1988 "Pushing lace %d, data of size %d for stream %d, time=%"
1989 GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
1990 GST_BUFFER_SIZE (sub), stream_num,
1991 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
1992 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
1994 if (parse->element_index) {
1995 if (stream->index_writer_id == -1)
1996 gst_index_get_writer_id (parse->element_index,
1997 GST_OBJECT (stream->pad), &stream->index_writer_id);
1999 GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
2000 G_GUINT64_FORMAT " for writer id %d",
2001 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
2002 stream->index_writer_id);
2003 gst_index_add_association (parse->element_index,
2004 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
2005 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
2006 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
2007 cluster_offset, NULL);
2010 gst_buffer_set_caps (sub, GST_PAD_CAPS (parse->srcpad));
2012 /* Postprocess the buffers depending on the codec used */
2013 if (stream->postprocess_frame) {
2014 GST_LOG_OBJECT (parse, "running post process");
2015 ret = stream->postprocess_frame (GST_ELEMENT (parse), stream, &sub);
2018 ret = gst_pad_push (stream->pad, sub);
2019 if (parse->segment.rate < 0) {
2020 if (lace_time > parse->segment.stop && ret == GST_FLOW_EOS) {
2021 /* In reverse playback we can get a GST_FLOW_EOS when
2022 * we are at the end of the segment, so we just need to jump
2023 * back to the previous section. */
2024 GST_DEBUG_OBJECT (parse, "downstream has reached end of segment");
2029 ret = gst_matroska_parse_combine_flows (parse, stream, ret);
2033 size -= lace_size[n];
2034 if (lace_time != GST_CLOCK_TIME_NONE && duration)
2035 lace_time += duration / laces;
2037 lace_time = GST_CLOCK_TIME_NONE;
2043 gst_buffer_unmap (buf, &map);
2044 gst_buffer_unref (buf);
2053 GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
2054 /* non-fatal, try next block(group) */
2060 GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Data error"));
2061 /* non-fatal, try next block(group) */
2067 /* return FALSE if block(group) should be skipped (due to a seek) */
2068 static inline gboolean
2069 gst_matroska_parse_seek_block (GstMatroskaParse * parse)
2071 if (G_UNLIKELY (parse->seek_block)) {
2072 if (!(--parse->seek_block)) {
2075 GST_LOG_OBJECT (parse, "should skip block due to seek");
2083 static GstFlowReturn
2084 gst_matroska_parse_parse_contents_seekentry (GstMatroskaParse * parse,
2088 guint64 seek_pos = (guint64) - 1;
2089 guint32 seek_id = 0;
2092 DEBUG_ELEMENT_START (parse, ebml, "Seek");
2094 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2095 DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2099 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2100 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2104 case GST_MATROSKA_ID_SEEKID:
2108 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2111 GST_DEBUG_OBJECT (parse, "SeekID: %" G_GUINT64_FORMAT, t);
2116 case GST_MATROSKA_ID_SEEKPOSITION:
2120 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2123 if (t > G_MAXINT64) {
2124 GST_WARNING_OBJECT (parse,
2125 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
2129 GST_DEBUG_OBJECT (parse, "SeekPosition: %" G_GUINT64_FORMAT, t);
2135 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2141 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
2144 if (!seek_id || seek_pos == (guint64) - 1) {
2145 GST_WARNING_OBJECT (parse, "Incomplete seekhead entry (0x%x/%"
2146 G_GUINT64_FORMAT ")", seek_id, seek_pos);
2151 case GST_MATROSKA_ID_SEEKHEAD:
2154 case GST_MATROSKA_ID_CUES:
2155 case GST_MATROSKA_ID_TAGS:
2156 case GST_MATROSKA_ID_TRACKS:
2157 case GST_MATROSKA_ID_SEGMENTINFO:
2158 case GST_MATROSKA_ID_ATTACHMENTS:
2159 case GST_MATROSKA_ID_CHAPTERS:
2164 length = gst_matroska_read_common_get_length (&parse->common);
2166 if (length == (guint64) - 1) {
2167 GST_DEBUG_OBJECT (parse, "no upstream length, skipping SeakHead entry");
2171 /* check for validity */
2172 if (seek_pos + parse->common.ebml_segment_start + 12 >= length) {
2173 GST_WARNING_OBJECT (parse,
2174 "SeekHead reference lies outside file!" " (%"
2175 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
2176 G_GUINT64_FORMAT ")", seek_pos, parse->common.ebml_segment_start,
2181 /* only pick up index location when streaming */
2182 if (seek_id == GST_MATROSKA_ID_CUES) {
2183 parse->index_offset = seek_pos + parse->common.ebml_segment_start;
2184 GST_DEBUG_OBJECT (parse, "Cues located at offset %" G_GUINT64_FORMAT,
2185 parse->index_offset);
2191 GST_DEBUG_OBJECT (parse, "Ignoring Seek entry for ID=0x%x", seek_id);
2194 DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2199 static GstFlowReturn
2200 gst_matroska_parse_parse_contents (GstMatroskaParse * parse, GstEbmlRead * ebml)
2202 GstFlowReturn ret = GST_FLOW_OK;
2205 DEBUG_ELEMENT_START (parse, ebml, "SeekHead");
2207 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2208 DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2212 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2213 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2217 case GST_MATROSKA_ID_SEEKENTRY:
2219 ret = gst_matroska_parse_parse_contents_seekentry (parse, ebml);
2220 /* Ignore EOS and errors here */
2221 if (ret != GST_FLOW_OK) {
2222 GST_DEBUG_OBJECT (parse, "Ignoring %s", gst_flow_get_name (ret));
2229 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2235 DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2240 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
2242 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
2244 static inline GstFlowReturn
2245 gst_matroska_parse_check_read_size (GstMatroskaParse * parse, guint64 bytes)
2247 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
2248 /* only a few blocks are expected/allowed to be large,
2249 * and will be recursed into, whereas others will be read and must fit */
2250 /* fatal in streaming case, as we can't step over easily */
2251 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2252 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
2253 "file might be corrupt.", bytes));
2254 return GST_FLOW_ERROR;
2261 /* returns TRUE if we truely are in error state, and should give up */
2262 static inline gboolean
2263 gst_matroska_parse_check_parse_error (GstMatroskaParse * parse)
2267 /* sigh, one last attempt above and beyond call of duty ...;
2268 * search for cluster mark following current pos */
2269 pos = parse->common.offset;
2270 GST_WARNING_OBJECT (parse, "parse error, looking for next cluster");
2271 if (gst_matroska_parse_search_cluster (parse, &pos) != GST_FLOW_OK) {
2272 /* did not work, give up */
2275 GST_DEBUG_OBJECT (parse, "... found at %" G_GUINT64_FORMAT, pos);
2276 /* try that position */
2277 parse->common.offset = pos;
2283 /* initializes @ebml with @bytes from input stream at current offset.
2284 * Returns EOS if insufficient available,
2285 * ERROR if too much was attempted to read. */
2286 static inline GstFlowReturn
2287 gst_matroska_parse_take (GstMatroskaParse * parse, guint64 bytes,
2290 GstBuffer *buffer = NULL;
2291 GstFlowReturn ret = GST_FLOW_OK;
2293 GST_LOG_OBJECT (parse, "taking %" G_GUINT64_FORMAT " bytes for parsing",
2295 ret = gst_matroska_parse_check_read_size (parse, bytes);
2296 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
2297 /* otherwise fatal */
2298 ret = GST_FLOW_ERROR;
2301 if (gst_adapter_available (parse->common.adapter) < bytes)
2302 return GST_FLOW_EOS;
2304 buffer = gst_adapter_take_buffer (parse->common.adapter, bytes);
2305 if (G_LIKELY (buffer)) {
2306 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (parse), buffer,
2307 parse->common.offset);
2308 parse->common.offset += bytes;
2310 ret = GST_FLOW_ERROR;
2318 gst_matroska_parse_check_seekability (GstMatroskaParse * parse)
2321 gboolean seekable = FALSE;
2322 gint64 start = -1, stop = -1;
2324 query = gst_query_new_seeking (GST_FORMAT_BYTES);
2325 if (!gst_pad_peer_query (parse->common.sinkpad, query)) {
2326 GST_DEBUG_OBJECT (parse, "seeking query failed");
2330 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
2332 /* try harder to query upstream size if we didn't get it the first time */
2333 if (seekable && stop == -1) {
2334 GST_DEBUG_OBJECT (parse, "doing duration query to fix up unset stop");
2335 gst_pad_peer_query_duration (parse->common.sinkpad, GST_FORMAT_BYTES,
2339 /* if upstream doesn't know the size, it's likely that it's not seekable in
2340 * practice even if it technically may be seekable */
2341 if (seekable && (start != 0 || stop <= start)) {
2342 GST_DEBUG_OBJECT (parse, "seekable but unknown start/stop -> disable");
2347 GST_INFO_OBJECT (parse, "seekable: %d (%" G_GUINT64_FORMAT " - %"
2348 G_GUINT64_FORMAT ")", seekable, start, stop);
2349 parse->seekable = seekable;
2351 gst_query_unref (query);
2355 static GstFlowReturn
2356 gst_matroska_parse_find_tracks (GstMatroskaParse * parse)
2362 GstFlowReturn ret = GST_FLOW_OK;
2364 GST_WARNING_OBJECT (parse,
2365 "Found Cluster element before Tracks, searching Tracks");
2368 before_pos = parse->common.offset;
2370 /* Search Tracks element */
2372 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2373 GST_ELEMENT_CAST (parse), &id, &length, &needed);
2374 if (ret != GST_FLOW_OK)
2377 if (id != GST_MATROSKA_ID_TRACKS) {
2378 /* we may be skipping large cluster here, so forego size check etc */
2379 /* ... but we can't skip undefined size; force error */
2380 if (length == G_MAXUINT64) {
2381 ret = gst_matroska_parse_check_read_size (parse, length);
2384 parse->common.offset += needed;
2385 parse->offset += length;
2390 /* will lead to track parsing ... */
2391 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2396 parse->offset = before_pos;
2402 #define GST_READ_CHECK(stmt) \
2404 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
2405 if (ret == GST_FLOW_OVERFLOW) { \
2406 ret = GST_FLOW_OK; \
2413 gst_matroska_parse_accumulate_streamheader (GstMatroskaParse * parse,
2416 if (parse->pushed_headers) {
2417 GST_WARNING_OBJECT (parse,
2418 "Accumulating headers, but headers are already pushed");
2421 if (parse->streamheader) {
2422 parse->streamheader = gst_buffer_append (parse->streamheader,
2423 gst_buffer_ref (buffer));
2425 parse->streamheader = gst_buffer_ref (buffer);
2428 GST_DEBUG ("%" G_GSIZE_FORMAT, gst_buffer_get_size (parse->streamheader));
2431 static GstFlowReturn
2432 gst_matroska_parse_output (GstMatroskaParse * parse, GstBuffer * buffer,
2437 if (!parse->pushed_headers) {
2440 GValue streamheader = { 0 };
2441 GValue bufval = { 0 };
2444 caps = gst_pad_get_current_caps (parse->common.sinkpad);
2446 caps = gst_matroska_parse_forge_caps (parse->common.is_webm,
2447 parse->common.has_video);
2449 caps = gst_caps_make_writable (caps);
2451 s = gst_caps_get_structure (caps, 0);
2452 g_value_init (&streamheader, GST_TYPE_ARRAY);
2453 g_value_init (&bufval, GST_TYPE_BUFFER);
2454 buf = gst_buffer_copy (parse->streamheader);
2455 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2456 gst_value_set_buffer (&bufval, buf);
2457 gst_buffer_unref (buf);
2458 gst_value_array_append_value (&streamheader, &bufval);
2459 g_value_unset (&bufval);
2460 gst_structure_set_value (s, "streamheader", &streamheader);
2461 g_value_unset (&streamheader);
2462 //gst_caps_replace (parse->caps, caps);
2463 gst_pad_set_caps (parse->srcpad, caps);
2465 if (parse->need_newsegment) {
2466 gst_pad_push_event (parse->srcpad,
2467 gst_event_new_segment (&parse->common.segment));
2468 parse->need_newsegment = FALSE;
2471 buf = gst_buffer_copy (parse->streamheader);
2472 gst_caps_unref (caps);
2474 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2475 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2476 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
2478 ret = gst_pad_push (parse->srcpad, buf);
2479 if (ret != GST_FLOW_OK) {
2480 GST_WARNING_OBJECT (parse, "Failed to push buffer");
2484 parse->pushed_headers = TRUE;
2488 GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2490 GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2492 if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE) {
2493 parse->last_timestamp = GST_BUFFER_TIMESTAMP (buffer);
2495 GST_BUFFER_TIMESTAMP (buffer) = parse->last_timestamp;
2498 return gst_pad_push (parse->srcpad, gst_buffer_ref (buffer));
2501 static GstFlowReturn
2502 gst_matroska_parse_parse_id (GstMatroskaParse * parse, guint32 id,
2503 guint64 length, guint needed)
2505 GstEbmlRead ebml = { 0, };
2506 GstFlowReturn ret = GST_FLOW_OK;
2508 //GstBuffer *buffer;
2510 GST_DEBUG_OBJECT (parse, "Parsing Element id 0x%x, "
2511 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
2514 if (gst_adapter_available (parse->adapter) >= length + needed) {
2515 buffer = gst_adapter_take_buffer (parse->adapter, length + needed);
2516 gst_pad_push (parse->srcpad, buffer);
2520 //GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2527 /* if we plan to read and parse this element, we need prefix (id + length)
2528 * and the contents */
2529 /* mind about overflow wrap-around when dealing with undefined size */
2531 if (G_LIKELY (length != G_MAXUINT64))
2534 switch (parse->common.state) {
2535 case GST_MATROSKA_READ_STATE_START:
2537 case GST_EBML_ID_HEADER:
2538 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2539 ret = gst_matroska_read_common_parse_header (&parse->common, &ebml);
2540 if (ret != GST_FLOW_OK)
2542 parse->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
2543 gst_matroska_parse_check_seekability (parse);
2544 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2547 goto invalid_header;
2551 case GST_MATROSKA_READ_STATE_SEGMENT:
2553 case GST_MATROSKA_ID_SEGMENT:
2554 /* eat segment prefix */
2555 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2556 GST_DEBUG_OBJECT (parse,
2557 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
2558 G_GUINT64_FORMAT, parse->common.offset, length);
2559 /* seeks are from the beginning of the segment,
2560 * after the segment ID/length */
2561 parse->common.ebml_segment_start = parse->common.offset;
2563 length = G_MAXUINT64;
2564 parse->common.ebml_segment_length = length;
2565 parse->common.state = GST_MATROSKA_READ_STATE_HEADER;
2566 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2569 GST_WARNING_OBJECT (parse,
2570 "Expected a Segment ID (0x%x), but received 0x%x!",
2571 GST_MATROSKA_ID_SEGMENT, id);
2572 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2573 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2577 case GST_MATROSKA_READ_STATE_SCANNING:
2578 if (id != GST_MATROSKA_ID_CLUSTER &&
2579 id != GST_MATROSKA_ID_CLUSTERTIMECODE) {
2580 /* we need to skip byte per byte if we are scanning for a new cluster */
2584 GST_LOG_OBJECT (parse, "Resync done, new cluster found!");
2585 parse->common.start_resync_offset = -1;
2586 parse->common.state = parse->common.state_to_restore;
2589 case GST_MATROSKA_READ_STATE_HEADER:
2590 case GST_MATROSKA_READ_STATE_DATA:
2591 case GST_MATROSKA_READ_STATE_SEEK:
2593 case GST_MATROSKA_ID_SEGMENTINFO:
2594 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2595 if (!parse->common.segmentinfo_parsed) {
2596 ret = gst_matroska_read_common_parse_info (&parse->common,
2597 GST_ELEMENT_CAST (parse), &ebml);
2598 if (ret == GST_FLOW_OK)
2599 gst_matroska_parse_send_tags (parse);
2601 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2603 case GST_MATROSKA_ID_TRACKS:
2604 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2605 if (!parse->tracks_parsed) {
2606 ret = gst_matroska_parse_parse_tracks (parse, &ebml);
2608 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2610 case GST_MATROSKA_ID_CLUSTER:
2611 if (G_UNLIKELY (!parse->tracks_parsed)) {
2612 GST_DEBUG_OBJECT (parse, "Cluster before Track");
2613 goto not_streamable;
2615 if (G_UNLIKELY (parse->common.state
2616 == GST_MATROSKA_READ_STATE_HEADER)) {
2617 parse->common.state = GST_MATROSKA_READ_STATE_DATA;
2618 parse->first_cluster_offset = parse->common.offset;
2619 GST_DEBUG_OBJECT (parse, "signaling no more pads");
2621 parse->cluster_time = GST_CLOCK_TIME_NONE;
2622 parse->cluster_offset = parse->common.offset;
2623 if (G_UNLIKELY (!parse->seek_first && parse->seek_block)) {
2624 GST_DEBUG_OBJECT (parse, "seek target block %" G_GUINT64_FORMAT
2625 " not found in Cluster, trying next Cluster's first block instead",
2627 parse->seek_block = 0;
2629 parse->seek_first = FALSE;
2630 /* record next cluster for recovery */
2631 if (read != G_MAXUINT64)
2632 parse->next_cluster_offset = parse->cluster_offset + read;
2633 /* eat cluster prefix */
2634 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2635 ret = gst_matroska_parse_output (parse, ebml.buf, TRUE);
2636 //gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2638 case GST_MATROSKA_ID_CLUSTERTIMECODE:
2642 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2643 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
2645 GST_DEBUG_OBJECT (parse, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
2646 parse->cluster_time = num;
2648 if (parse->common.element_index) {
2649 if (parse->common.element_index_writer_id == -1)
2650 gst_index_get_writer_id (parse->common.element_index,
2651 GST_OBJECT (parse), &parse->common.element_index_writer_id);
2652 GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
2653 G_GUINT64_FORMAT " for writer id %d",
2654 GST_TIME_ARGS (parse->cluster_time), parse->cluster_offset,
2655 parse->common.element_index_writer_id);
2656 gst_index_add_association (parse->common.element_index,
2657 parse->common.element_index_writer_id,
2658 GST_ASSOCIATION_FLAG_KEY_UNIT,
2659 GST_FORMAT_TIME, parse->cluster_time,
2660 GST_FORMAT_BYTES, parse->cluster_offset, NULL);
2663 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2666 case GST_MATROSKA_ID_BLOCKGROUP:
2667 if (!gst_matroska_parse_seek_block (parse))
2669 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2670 DEBUG_ELEMENT_START (parse, &ebml, "BlockGroup");
2671 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
2672 ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
2673 &ebml, parse->cluster_time, parse->cluster_offset, FALSE);
2675 DEBUG_ELEMENT_STOP (parse, &ebml, "BlockGroup", ret);
2676 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2678 case GST_MATROSKA_ID_SIMPLEBLOCK:
2679 if (!gst_matroska_parse_seek_block (parse))
2681 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2682 DEBUG_ELEMENT_START (parse, &ebml, "SimpleBlock");
2683 ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
2684 &ebml, parse->cluster_time, parse->cluster_offset, TRUE);
2685 DEBUG_ELEMENT_STOP (parse, &ebml, "SimpleBlock", ret);
2686 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2688 case GST_MATROSKA_ID_ATTACHMENTS:
2689 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2690 if (!parse->common.attachments_parsed) {
2691 ret = gst_matroska_read_common_parse_attachments (&parse->common,
2692 GST_ELEMENT_CAST (parse), &ebml);
2693 if (ret == GST_FLOW_OK)
2694 gst_matroska_parse_send_tags (parse);
2696 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2698 case GST_MATROSKA_ID_TAGS:
2699 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2700 ret = gst_matroska_read_common_parse_metadata (&parse->common,
2701 GST_ELEMENT_CAST (parse), &ebml);
2702 if (ret == GST_FLOW_OK)
2703 gst_matroska_parse_send_tags (parse);
2704 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2706 case GST_MATROSKA_ID_CHAPTERS:
2707 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2708 ret = gst_matroska_read_common_parse_chapters (&parse->common, &ebml);
2709 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2711 case GST_MATROSKA_ID_SEEKHEAD:
2712 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2713 ret = gst_matroska_parse_parse_contents (parse, &ebml);
2714 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2716 case GST_MATROSKA_ID_CUES:
2717 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2718 if (!parse->common.index_parsed) {
2719 ret = gst_matroska_read_common_parse_index (&parse->common, &ebml);
2720 /* only push based; delayed index building */
2721 if (ret == GST_FLOW_OK
2722 && parse->common.state == GST_MATROSKA_READ_STATE_SEEK) {
2725 GST_OBJECT_LOCK (parse);
2726 event = parse->seek_event;
2727 parse->seek_event = NULL;
2728 GST_OBJECT_UNLOCK (parse);
2731 /* unlikely to fail, since we managed to seek to this point */
2732 if (!gst_matroska_parse_handle_seek_event (parse, NULL, event))
2734 /* resume data handling, main thread clear to seek again */
2735 GST_OBJECT_LOCK (parse);
2736 parse->common.state = GST_MATROSKA_READ_STATE_DATA;
2737 GST_OBJECT_UNLOCK (parse);
2740 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2742 case GST_MATROSKA_ID_POSITION:
2743 case GST_MATROSKA_ID_PREVSIZE:
2744 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
2745 case GST_MATROSKA_ID_SILENTTRACKS:
2746 GST_DEBUG_OBJECT (parse,
2747 "Skipping Cluster subelement 0x%x - ignoring", id);
2751 GST_DEBUG_OBJECT (parse, "skipping Element 0x%x", id);
2752 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2753 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2759 if (ret == GST_FLOW_PARSE)
2763 gst_ebml_read_clear (&ebml);
2769 /* simply exit, maybe not enough data yet */
2770 /* no ebml to clear if read error */
2775 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2776 ("Failed to parse Element 0x%x", id));
2777 ret = GST_FLOW_ERROR;
2782 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2783 ("File layout does not permit streaming"));
2784 ret = GST_FLOW_ERROR;
2790 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2791 ("No Tracks element found"));
2792 ret = GST_FLOW_ERROR;
2798 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Invalid header"));
2799 ret = GST_FLOW_ERROR;
2804 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Failed to seek"));
2805 ret = GST_FLOW_ERROR;
2812 gst_matroska_parse_loop (GstPad * pad)
2814 GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
2820 /* If we have to close a segment, send a new segment to do this now */
2821 if (G_LIKELY (parse->common.state == GST_MATROSKA_READ_STATE_DATA)) {
2822 if (G_UNLIKELY (parse->close_segment)) {
2823 gst_matroska_parse_send_event (parse, parse->close_segment);
2824 parse->close_segment = NULL;
2826 if (G_UNLIKELY (parse->new_segment)) {
2827 gst_matroska_parse_send_event (parse, parse->new_segment);
2828 parse->new_segment = NULL;
2832 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2833 GST_ELEMENT_CAST (parse), &id, &length, &needed);
2834 if (ret == GST_FLOW_EOS)
2836 if (ret != GST_FLOW_OK) {
2837 if (gst_matroska_parse_check_parse_error (parse))
2843 GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2844 "size %" G_GUINT64_FORMAT ", needed %d", parse->offset, id,
2847 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2848 if (ret == GST_FLOW_EOS)
2850 if (ret != GST_FLOW_OK)
2853 /* check if we're at the end of a configured segment */
2854 if (G_LIKELY (parse->src->len)) {
2857 g_assert (parse->num_streams == parse->src->len);
2858 for (i = 0; i < parse->src->len; i++) {
2859 GstMatroskaTrackContext *context = g_ptr_array_index (parse->src, i);
2860 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
2861 GST_TIME_ARGS (context->pos));
2862 if (context->eos == FALSE)
2866 GST_INFO_OBJECT (parse, "All streams are EOS");
2872 if (G_UNLIKELY (parse->offset ==
2873 gst_matroska_read_common_get_length (&parse->common))) {
2874 GST_LOG_OBJECT (parse, "Reached end of stream");
2884 if (parse->segment.rate < 0.0) {
2885 ret = gst_matroska_parse_seek_to_previous_keyframe (parse);
2886 if (ret == GST_FLOW_OK)
2893 const gchar *reason = gst_flow_get_name (ret);
2894 gboolean push_eos = FALSE;
2896 GST_LOG_OBJECT (parse, "pausing task, reason %s", reason);
2897 parse->segment_running = FALSE;
2898 gst_pad_pause_task (parse->common.sinkpad);
2900 if (ret == GST_FLOW_EOS) {
2901 /* perform EOS logic */
2903 /* Close the segment, i.e. update segment stop with the duration
2904 * if no stop was set */
2905 if (GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) &&
2906 !GST_CLOCK_TIME_IS_VALID (parse->segment.stop)) {
2908 gst_event_new_new_segment_full (TRUE, parse->segment.rate,
2909 parse->segment.applied_rate, parse->segment.format,
2910 parse->segment.start,
2911 MAX (parse->last_stop_end, parse->segment.start),
2912 parse->segment.time);
2913 gst_matroska_parse_send_event (parse, event);
2916 if (parse->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2919 /* for segment playback we need to post when (in stream time)
2920 * we stopped, this is either stop (when set) or the duration. */
2921 if ((stop = parse->segment.stop) == -1)
2922 stop = parse->last_stop_end;
2924 GST_LOG_OBJECT (parse, "Sending segment done, at end of segment");
2925 gst_element_post_message (GST_ELEMENT (parse),
2926 gst_message_new_segment_done (GST_OBJECT (parse), GST_FORMAT_TIME,
2928 gst_matroska_parse_send_event (parse,
2929 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
2933 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
2934 /* for fatal errors we post an error message */
2935 GST_ELEMENT_FLOW_ERROR (parse, ret);
2939 /* send EOS, and prevent hanging if no streams yet */
2940 GST_LOG_OBJECT (parse, "Sending EOS, at end of stream");
2941 if (!gst_matroska_parse_send_event (parse, gst_event_new_eos ()) &&
2942 (ret == GST_FLOW_EOS)) {
2943 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
2944 (NULL), ("got eos but no streams (yet)"));
2953 * Create and push a flushing seek event upstream
2956 perform_seek_to_offset (GstMatroskaParse * parse, guint64 offset)
2961 GST_DEBUG_OBJECT (parse, "Seeking to %" G_GUINT64_FORMAT, offset);
2964 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
2965 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
2966 GST_SEEK_TYPE_NONE, -1);
2968 res = gst_pad_push_event (parse->common.sinkpad, event);
2970 /* newsegment event will update offset */
2975 * Forge empty default caps when all we know is the stream's EBML
2976 * type and whether it has video or not.
2978 * FIXME: Do something with video/x-matroska-3d if possible
2981 gst_matroska_parse_forge_caps (gboolean is_webm, gboolean has_video)
2987 caps = gst_caps_new_empty_simple ("video/webm");
2989 caps = gst_caps_new_empty_simple ("audio/webm");
2992 caps = gst_caps_new_empty_simple ("video/x-matroska");
2994 caps = gst_caps_new_empty_simple ("audio/x-matroska");
2999 static GstFlowReturn
3000 gst_matroska_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
3002 GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
3004 GstFlowReturn ret = GST_FLOW_OK;
3009 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
3010 GST_DEBUG_OBJECT (parse, "got DISCONT");
3011 gst_adapter_clear (parse->common.adapter);
3012 GST_OBJECT_LOCK (parse);
3013 gst_matroska_read_common_reset_streams (&parse->common,
3014 GST_CLOCK_TIME_NONE, FALSE);
3015 GST_OBJECT_UNLOCK (parse);
3018 gst_adapter_push (parse->common.adapter, buffer);
3022 available = gst_adapter_available (parse->common.adapter);
3024 ret = gst_matroska_read_common_peek_id_length_push (&parse->common,
3025 GST_ELEMENT_CAST (parse), &id, &length, &needed);
3026 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
3027 if (parse->common.ebml_segment_length != G_MAXUINT64
3028 && parse->common.offset >=
3029 parse->common.ebml_segment_start + parse->common.ebml_segment_length) {
3030 return GST_FLOW_EOS;
3033 * parsing error: we need to flush a byte from the adapter if the id is
3034 * not a cluster and so on until we found a new cluser or the
3035 * INVALID_DATA_THRESHOLD is exceeded, we reuse gst_matroska_parse_parse_id
3036 * setting the state to GST_MATROSKA_READ_STATE_SCANNING so the bytes
3037 * are skipped until a new cluster is found
3039 gint64 bytes_scanned;
3040 if (parse->common.start_resync_offset == -1) {
3041 parse->common.start_resync_offset = parse->common.offset;
3042 parse->common.state_to_restore = parse->common.state;
3044 bytes_scanned = parse->common.offset - parse->common.start_resync_offset;
3045 if (bytes_scanned <= INVALID_DATA_THRESHOLD) {
3046 GST_WARNING_OBJECT (parse,
3047 "parse error, looking for next cluster, actual offset %"
3048 G_GUINT64_FORMAT ", start resync offset %" G_GUINT64_FORMAT,
3049 parse->common.offset, parse->common.start_resync_offset);
3050 parse->common.state = GST_MATROSKA_READ_STATE_SCANNING;
3053 GST_WARNING_OBJECT (parse,
3054 "unrecoverable parse error, next cluster not found and threshold "
3055 "exceeded, bytes scanned %" G_GINT64_FORMAT, bytes_scanned);
3061 GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
3062 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
3063 parse->common.offset, id, length, needed, available);
3065 if (needed > available)
3068 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
3069 if (ret == GST_FLOW_EOS) {
3070 /* need more data */
3072 } else if (ret != GST_FLOW_OK) {
3079 gst_matroska_parse_handle_sink_event (GstPad * pad, GstObject * parent,
3082 gboolean res = TRUE;
3083 GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
3085 GST_DEBUG_OBJECT (parse,
3086 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
3088 switch (GST_EVENT_TYPE (event)) {
3089 case GST_EVENT_SEGMENT:
3091 const GstSegment *segment;
3093 /* some debug output */
3094 gst_event_parse_segment (event, &segment);
3095 GST_DEBUG_OBJECT (parse,
3096 "received format %d newsegment %" GST_SEGMENT_FORMAT,
3097 segment->format, segment);
3099 if (parse->common.state < GST_MATROSKA_READ_STATE_DATA) {
3100 GST_DEBUG_OBJECT (parse, "still starting");
3104 /* we only expect a BYTE segment, e.g. following a seek */
3105 if (segment->format != GST_FORMAT_BYTES) {
3106 GST_DEBUG_OBJECT (parse, "unsupported segment format, ignoring");
3110 GST_DEBUG_OBJECT (parse, "clearing segment state");
3111 /* clear current segment leftover */
3112 gst_adapter_clear (parse->common.adapter);
3113 /* and some streaming setup */
3114 parse->common.offset = segment->start;
3115 /* do not know where we are;
3116 * need to come across a cluster and generate newsegment */
3117 parse->common.segment.position = GST_CLOCK_TIME_NONE;
3118 parse->cluster_time = GST_CLOCK_TIME_NONE;
3119 parse->cluster_offset = 0;
3120 parse->need_newsegment = TRUE;
3121 /* but keep some of the upstream segment */
3122 parse->common.segment.rate = segment->rate;
3124 /* chain will send initial newsegment after pads have been added,
3125 * or otherwise come up with one */
3126 GST_DEBUG_OBJECT (parse, "eating event");
3127 gst_event_unref (event);
3133 if (parse->common.state != GST_MATROSKA_READ_STATE_DATA
3134 && parse->common.state != GST_MATROSKA_READ_STATE_SCANNING) {
3135 gst_event_unref (event);
3136 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3137 (NULL), ("got eos and didn't receive a complete header object"));
3138 } else if (parse->common.num_streams == 0) {
3139 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3140 (NULL), ("got eos but no streams (yet)"));
3142 gst_matroska_parse_send_event (parse, event);
3146 case GST_EVENT_FLUSH_STOP:
3148 gst_adapter_clear (parse->common.adapter);
3149 GST_OBJECT_LOCK (parse);
3150 gst_matroska_read_common_reset_streams (&parse->common,
3151 GST_CLOCK_TIME_NONE, TRUE);
3152 GST_OBJECT_UNLOCK (parse);
3153 parse->common.segment.position = GST_CLOCK_TIME_NONE;
3154 parse->cluster_time = GST_CLOCK_TIME_NONE;
3155 parse->cluster_offset = 0;
3159 res = gst_pad_event_default (pad, parent, event);
3168 gst_matroska_parse_set_index (GstElement * element, GstIndex * index)
3170 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3172 GST_OBJECT_LOCK (parse);
3173 if (parse->common.element_index)
3174 gst_object_unref (parse->common.element_index);
3175 parse->common.element_index = index ? gst_object_ref (index) : NULL;
3176 GST_OBJECT_UNLOCK (parse);
3177 GST_DEBUG_OBJECT (parse, "Set index %" GST_PTR_FORMAT,
3178 parse->common.element_index);
3182 gst_matroska_parse_get_index (GstElement * element)
3184 GstIndex *result = NULL;
3185 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3187 GST_OBJECT_LOCK (parse);
3188 if (parse->common.element_index)
3189 result = gst_object_ref (parse->common.element_index);
3190 GST_OBJECT_UNLOCK (parse);
3192 GST_DEBUG_OBJECT (parse, "Returning index %" GST_PTR_FORMAT, result);
3198 static GstStateChangeReturn
3199 gst_matroska_parse_change_state (GstElement * element,
3200 GstStateChange transition)
3202 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3203 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
3205 /* handle upwards state changes here */
3206 switch (transition) {
3211 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
3213 /* handle downwards state changes */
3214 switch (transition) {
3215 case GST_STATE_CHANGE_PAUSED_TO_READY:
3216 gst_matroska_parse_reset (GST_ELEMENT (parse));
3226 gst_matroska_parse_plugin_init (GstPlugin * plugin)
3230 /* create an elementfactory for the matroska_parse element */
3231 if (!gst_element_register (plugin, "matroskaparse",
3232 GST_RANK_NONE, GST_TYPE_MATROSKA_PARSE))