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 parsing is done correct for all codecs according to spec
31 * TODO: seeking with incomplete or without CUE
35 * SECTION:element-matroskaparse
36 * @title: matroskaparse
38 * matroskaparse parsees a Matroska file into the different contained streams.
40 * ## Example launch line
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 "gstmatroskaelements.h"
67 #include "matroska-parse.h"
68 #include "matroska-ids.h"
70 GST_DEBUG_CATEGORY_STATIC (matroskaparse_debug);
71 #define GST_CAT_DEFAULT matroskaparse_debug
73 #define DEBUG_ELEMENT_START(parse, ebml, element) \
74 GST_DEBUG_OBJECT (parse, "Parsing " element " element at offset %" \
75 G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
77 #define DEBUG_ELEMENT_STOP(parse, ebml, element, ret) \
78 GST_DEBUG_OBJECT (parse, "Parsing " element " element " \
79 " finished with '%s'", gst_flow_get_name (ret))
81 #define INVALID_DATA_THRESHOLD (2 * 1024 * 1024)
88 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
91 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
92 "video/x-matroska-3d; audio/webm; video/webm")
95 static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
98 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
99 "video/x-matroska-3d; audio/webm; video/webm")
102 static GstFlowReturn gst_matroska_parse_parse_id (GstMatroskaParse * parse,
103 guint32 id, guint64 length, guint needed);
105 /* element functions */
106 //static void gst_matroska_parse_loop (GstPad * pad);
108 static gboolean gst_matroska_parse_element_send_event (GstElement * element,
110 static gboolean gst_matroska_parse_element_query (GstElement * element,
114 static gboolean gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
115 GstPad * pad, GstEvent * event);
116 static gboolean gst_matroska_parse_handle_src_event (GstPad * pad,
117 GstObject * parent, GstEvent * event);
118 static gboolean gst_matroska_parse_handle_src_query (GstPad * pad,
119 GstObject * parent, GstQuery * query);
121 static gboolean gst_matroska_parse_handle_sink_event (GstPad * pad,
122 GstObject * parent, GstEvent * event);
123 static GstFlowReturn gst_matroska_parse_chain (GstPad * pad,
124 GstObject * parent, GstBuffer * buffer);
126 static GstStateChangeReturn
127 gst_matroska_parse_change_state (GstElement * element,
128 GstStateChange transition);
131 gst_matroska_parse_set_index (GstElement * element, GstIndex * index);
132 static GstIndex *gst_matroska_parse_get_index (GstElement * element);
136 static void gst_matroska_parse_reset (GstElement * element);
137 static gboolean perform_seek_to_offset (GstMatroskaParse * parse,
139 static GstCaps *gst_matroska_parse_forge_caps (gboolean is_webm,
142 GType gst_matroska_parse_get_type (void);
143 #define parent_class gst_matroska_parse_parent_class
144 G_DEFINE_TYPE (GstMatroskaParse, gst_matroska_parse, GST_TYPE_ELEMENT);
147 matroska_element_init (plugin);
148 GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (matroskaparse, "matroskaparse",
149 GST_RANK_NONE, GST_TYPE_MATROSKA_PARSE, _do_init);
152 gst_matroska_parse_finalize (GObject * object)
154 GstMatroskaParse *parse = GST_MATROSKA_PARSE (object);
156 gst_matroska_read_common_finalize (&parse->common);
157 G_OBJECT_CLASS (parent_class)->finalize (object);
161 gst_matroska_parse_class_init (GstMatroskaParseClass * klass)
163 GObjectClass *gobject_class = (GObjectClass *) klass;
164 GstElementClass *gstelement_class = (GstElementClass *) klass;
166 GST_DEBUG_CATEGORY_INIT (matroskaparse_debug, "matroskaparse", 0,
169 gobject_class->finalize = gst_matroska_parse_finalize;
171 gstelement_class->change_state =
172 GST_DEBUG_FUNCPTR (gst_matroska_parse_change_state);
173 gstelement_class->send_event =
174 GST_DEBUG_FUNCPTR (gst_matroska_parse_element_send_event);
175 gstelement_class->query =
176 GST_DEBUG_FUNCPTR (gst_matroska_parse_element_query);
179 gstelement_class->set_index =
180 GST_DEBUG_FUNCPTR (gst_matroska_parse_set_index);
181 gstelement_class->get_index =
182 GST_DEBUG_FUNCPTR (gst_matroska_parse_get_index);
185 gst_element_class_add_static_pad_template (gstelement_class, &src_templ);
186 gst_element_class_add_static_pad_template (gstelement_class, &sink_templ);
188 gst_element_class_set_static_metadata (gstelement_class,
189 "Matroska parser", "Codec/Parser",
190 "Parses Matroska/WebM streams into video/audio/subtitles",
191 "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
195 gst_matroska_parse_init (GstMatroskaParse * parse)
197 parse->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
199 gst_pad_set_chain_function (parse->common.sinkpad,
200 GST_DEBUG_FUNCPTR (gst_matroska_parse_chain));
201 gst_pad_set_event_function (parse->common.sinkpad,
202 GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_sink_event));
203 gst_element_add_pad (GST_ELEMENT (parse), parse->common.sinkpad);
205 parse->srcpad = gst_pad_new_from_static_template (&src_templ, "src");
206 gst_pad_set_event_function (parse->srcpad,
207 GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_event));
208 gst_pad_set_query_function (parse->srcpad,
209 GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_query));
210 gst_pad_use_fixed_caps (parse->srcpad);
212 gst_element_add_pad (GST_ELEMENT (parse), parse->srcpad);
214 /* init defaults for common read context */
215 gst_matroska_read_common_init (&parse->common);
217 GST_OBJECT_FLAG_SET (parse, GST_ELEMENT_FLAG_INDEXABLE);
220 gst_matroska_parse_reset (GST_ELEMENT (parse));
224 gst_matroska_parse_reset (GstElement * element)
226 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
228 GST_DEBUG_OBJECT (parse, "Resetting state");
230 gst_matroska_read_common_reset (GST_ELEMENT (parse), &parse->common);
232 parse->num_a_streams = 0;
233 parse->num_t_streams = 0;
234 parse->num_v_streams = 0;
237 parse->tracks_parsed = FALSE;
239 g_list_foreach (parse->seek_parsed,
240 (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
241 g_list_free (parse->seek_parsed);
242 parse->seek_parsed = NULL;
244 parse->last_stop_end = GST_CLOCK_TIME_NONE;
245 parse->seek_block = 0;
246 parse->cluster_time = GST_CLOCK_TIME_NONE;
247 parse->cluster_offset = 0;
248 parse->next_cluster_offset = 0;
249 parse->index_offset = 0;
250 parse->seekable = FALSE;
251 parse->need_newsegment = TRUE;
252 parse->building_index = FALSE;
253 if (parse->seek_event) {
254 gst_event_unref (parse->seek_event);
255 parse->seek_event = NULL;
258 parse->seek_index = NULL;
259 parse->seek_entry = 0;
261 if (parse->close_segment) {
262 gst_event_unref (parse->close_segment);
263 parse->close_segment = NULL;
266 if (parse->new_segment) {
267 gst_event_unref (parse->new_segment);
268 parse->new_segment = NULL;
271 if (parse->streamheader != NULL) {
272 gst_buffer_unref (parse->streamheader);
273 parse->streamheader = NULL;
278 gst_matroska_parse_add_stream (GstMatroskaParse * parse, GstEbmlRead * ebml)
280 GstMatroskaTrackContext *context;
284 DEBUG_ELEMENT_START (parse, ebml, "TrackEntry");
286 /* start with the master */
287 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
288 DEBUG_ELEMENT_STOP (parse, ebml, "TrackEntry", ret);
292 /* allocate generic... if we know the type, we'll g_renew()
293 * with the precise type */
294 context = g_new0 (GstMatroskaTrackContext, 1);
295 g_ptr_array_add (parse->common.src, context);
296 context->index = parse->common.num_streams;
297 context->index_writer_id = -1;
298 context->type = 0; /* no type yet */
299 context->default_duration = 0;
301 context->set_discont = TRUE;
302 context->timecodescale = 1.0;
304 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
305 GST_MATROSKA_TRACK_LACING;
306 context->to_offset = G_MAXINT64;
307 context->alignment = 1;
308 parse->common.num_streams++;
309 g_assert (parse->common.src->len == parse->common.num_streams);
311 GST_DEBUG_OBJECT (parse, "Stream number %d", context->index);
313 /* try reading the trackentry headers */
314 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
315 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
319 /* track number (unique stream ID) */
320 case GST_MATROSKA_ID_TRACKNUMBER:{
323 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
327 GST_ERROR_OBJECT (parse, "Invalid TrackNumber 0");
328 ret = GST_FLOW_ERROR;
330 } else if (!gst_matroska_read_common_tracknumber_unique (&parse->common,
332 GST_ERROR_OBJECT (parse, "TrackNumber %" G_GUINT64_FORMAT
333 " is not unique", num);
334 ret = GST_FLOW_ERROR;
338 GST_DEBUG_OBJECT (parse, "TrackNumber: %" G_GUINT64_FORMAT, num);
342 /* track UID (unique identifier) */
343 case GST_MATROSKA_ID_TRACKUID:{
346 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
350 GST_ERROR_OBJECT (parse, "Invalid TrackUID 0");
351 ret = GST_FLOW_ERROR;
355 GST_DEBUG_OBJECT (parse, "TrackUID: %" G_GUINT64_FORMAT, num);
360 /* track type (video, audio, combined, subtitle, etc.) */
361 case GST_MATROSKA_ID_TRACKTYPE:{
364 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
368 if (context->type != 0 && context->type != track_type) {
369 GST_WARNING_OBJECT (parse,
370 "More than one tracktype defined in a TrackEntry - skipping");
372 } else if (track_type < 1 || track_type > 254) {
373 GST_WARNING_OBJECT (parse, "Invalid TrackType %" G_GUINT64_FORMAT,
378 GST_DEBUG_OBJECT (parse, "TrackType: %" G_GUINT64_FORMAT, track_type);
380 /* ok, so we're actually going to reallocate this thing */
381 switch (track_type) {
382 case GST_MATROSKA_TRACK_TYPE_VIDEO:
383 gst_matroska_track_init_video_context (&context);
384 parse->common.has_video = TRUE;
386 case GST_MATROSKA_TRACK_TYPE_AUDIO:
387 gst_matroska_track_init_audio_context (&context);
389 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
390 gst_matroska_track_init_subtitle_context (&context);
392 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
393 case GST_MATROSKA_TRACK_TYPE_LOGO:
394 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
395 case GST_MATROSKA_TRACK_TYPE_CONTROL:
397 GST_WARNING_OBJECT (parse,
398 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
403 g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
408 /* tracktype specific stuff for video */
409 case GST_MATROSKA_ID_TRACKVIDEO:{
410 GstMatroskaTrackVideoContext *videocontext;
412 DEBUG_ELEMENT_START (parse, ebml, "TrackVideo");
414 if (!gst_matroska_track_init_video_context (&context)) {
415 GST_WARNING_OBJECT (parse,
416 "TrackVideo element in non-video track - ignoring track");
417 ret = GST_FLOW_ERROR;
419 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
422 videocontext = (GstMatroskaTrackVideoContext *) context;
423 g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
426 while (ret == GST_FLOW_OK &&
427 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
428 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
432 /* Should be one level up but some broken muxers write it here. */
433 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
436 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
440 GST_WARNING_OBJECT (parse, "Invalid TrackDefaultDuration 0");
444 GST_DEBUG_OBJECT (parse,
445 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
446 context->default_duration = num;
450 /* video framerate */
451 /* NOTE: This one is here only for backward compatibility.
452 * Use _TRACKDEFAULDURATION one level up. */
453 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
456 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
460 GST_WARNING_OBJECT (parse, "Invalid TrackVideoFPS %lf", num);
464 GST_DEBUG_OBJECT (parse, "TrackVideoFrameRate: %lf", num);
465 if (context->default_duration == 0)
466 context->default_duration =
467 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
468 videocontext->default_fps = num;
472 /* width of the size to display the video at */
473 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
476 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
480 GST_WARNING_OBJECT (parse, "Invalid TrackVideoDisplayWidth 0");
484 GST_DEBUG_OBJECT (parse,
485 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
486 videocontext->display_width = num;
490 /* height of the size to display the video at */
491 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
494 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
498 GST_WARNING_OBJECT (parse, "Invalid TrackVideoDisplayHeight 0");
502 GST_DEBUG_OBJECT (parse,
503 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
504 videocontext->display_height = num;
508 /* width of the video in the file */
509 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
512 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
516 GST_WARNING_OBJECT (parse, "Invalid TrackVideoPixelWidth 0");
520 GST_DEBUG_OBJECT (parse,
521 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
522 videocontext->pixel_width = num;
526 /* height of the video in the file */
527 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
530 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
534 GST_WARNING_OBJECT (parse, "Invalid TrackVideoPixelHeight 0");
538 GST_DEBUG_OBJECT (parse,
539 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
540 videocontext->pixel_height = num;
544 /* whether the video is interlaced */
545 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
548 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
552 videocontext->interlace_mode =
553 GST_MATROSKA_INTERLACE_MODE_INTERLACED;
555 videocontext->interlace_mode =
556 GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
558 videocontext->interlace_mode =
559 GST_MATROSKA_INTERLACE_MODE_UNKNOWN;
561 GST_DEBUG_OBJECT (parse, "video track interlacing mode: %d",
562 videocontext->interlace_mode);
566 /* interlaced field order */
567 case GST_MATROSKA_ID_VIDEOFIELDORDER:{
570 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
573 if (videocontext->interlace_mode !=
574 GST_MATROSKA_INTERLACE_MODE_INTERLACED) {
575 GST_WARNING_OBJECT (parse,
576 "FieldOrder element when not interlaced - ignoring");
581 /* turns out we're actually progressive */
582 videocontext->interlace_mode =
583 GST_MATROSKA_INTERLACE_MODE_PROGRESSIVE;
585 videocontext->field_order = GST_VIDEO_FIELD_ORDER_UNKNOWN;
587 videocontext->field_order =
588 GST_VIDEO_FIELD_ORDER_TOP_FIELD_FIRST;
590 videocontext->field_order =
591 GST_VIDEO_FIELD_ORDER_BOTTOM_FIELD_FIRST;
593 GST_FIXME_OBJECT (parse,
594 "Unknown or unsupported FieldOrder %" G_GUINT64_FORMAT,
596 videocontext->field_order = GST_VIDEO_FIELD_ORDER_UNKNOWN;
599 GST_DEBUG_OBJECT (parse, "video track field order: %d",
600 videocontext->field_order);
604 /* aspect ratio behaviour */
605 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
608 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
611 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
612 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
613 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
614 GST_WARNING_OBJECT (parse,
615 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
618 GST_DEBUG_OBJECT (parse,
619 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
620 videocontext->asr_mode = num;
624 /* colourspace (only matters for raw video) fourcc */
625 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
630 gst_ebml_read_binary (ebml, &id, &data,
631 &datalen)) != GST_FLOW_OK)
636 GST_WARNING_OBJECT (parse,
637 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
642 memcpy (&videocontext->fourcc, data, 4);
643 GST_DEBUG_OBJECT (parse,
644 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
645 GST_FOURCC_ARGS (videocontext->fourcc));
651 GST_WARNING_OBJECT (parse,
652 "Unknown TrackVideo subelement 0x%x - ignoring", id);
654 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
655 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
656 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
657 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
658 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
659 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
660 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
661 ret = gst_ebml_read_skip (ebml);
666 DEBUG_ELEMENT_STOP (parse, ebml, "TrackVideo", ret);
670 /* tracktype specific stuff for audio */
671 case GST_MATROSKA_ID_TRACKAUDIO:{
672 GstMatroskaTrackAudioContext *audiocontext;
674 DEBUG_ELEMENT_START (parse, ebml, "TrackAudio");
676 if (!gst_matroska_track_init_audio_context (&context)) {
677 GST_WARNING_OBJECT (parse,
678 "TrackAudio element in non-audio track - ignoring track");
679 ret = GST_FLOW_ERROR;
683 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
686 audiocontext = (GstMatroskaTrackAudioContext *) context;
687 g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
690 while (ret == GST_FLOW_OK &&
691 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
692 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
697 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
700 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
705 GST_WARNING_OBJECT (parse,
706 "Invalid TrackAudioSamplingFrequency %lf", num);
710 GST_DEBUG_OBJECT (parse, "TrackAudioSamplingFrequency: %lf", num);
711 audiocontext->samplerate = num;
716 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
719 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
723 GST_WARNING_OBJECT (parse, "Invalid TrackAudioBitDepth 0");
727 GST_DEBUG_OBJECT (parse, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
729 audiocontext->bitdepth = num;
734 case GST_MATROSKA_ID_AUDIOCHANNELS:{
737 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
741 GST_WARNING_OBJECT (parse, "Invalid TrackAudioChannels 0");
745 GST_DEBUG_OBJECT (parse, "TrackAudioChannels: %" G_GUINT64_FORMAT,
747 audiocontext->channels = num;
752 GST_WARNING_OBJECT (parse,
753 "Unknown TrackAudio subelement 0x%x - ignoring", id);
755 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
756 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
757 ret = gst_ebml_read_skip (ebml);
762 DEBUG_ELEMENT_STOP (parse, ebml, "TrackAudio", ret);
767 /* codec identifier */
768 case GST_MATROSKA_ID_CODECID:{
771 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
774 GST_DEBUG_OBJECT (parse, "CodecID: %s", GST_STR_NULL (text));
775 context->codec_id = text;
779 /* codec private data */
780 case GST_MATROSKA_ID_CODECPRIVATE:{
785 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
788 context->codec_priv = data;
789 context->codec_priv_size = size;
791 GST_DEBUG_OBJECT (parse, "CodecPrivate of size %" G_GUINT64_FORMAT,
796 /* name of the codec */
797 case GST_MATROSKA_ID_CODECNAME:{
800 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
803 GST_DEBUG_OBJECT (parse, "CodecName: %s", GST_STR_NULL (text));
804 context->codec_name = text;
808 /* name of this track */
809 case GST_MATROSKA_ID_TRACKNAME:{
812 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
815 context->name = text;
816 GST_DEBUG_OBJECT (parse, "TrackName: %s", GST_STR_NULL (text));
820 /* language (matters for audio/subtitles, mostly) */
821 case GST_MATROSKA_ID_TRACKLANGUAGE:{
824 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
828 context->language = text;
831 if (strlen (context->language) >= 4 && context->language[3] == '-')
832 context->language[3] = '\0';
834 GST_DEBUG_OBJECT (parse, "TrackLanguage: %s",
835 GST_STR_NULL (context->language));
839 /* whether this is actually used */
840 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
843 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
847 context->flags |= GST_MATROSKA_TRACK_ENABLED;
849 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
851 GST_DEBUG_OBJECT (parse, "TrackEnabled: %d",
852 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
856 /* whether it's the default for this track type */
857 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
860 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
864 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
866 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
868 GST_DEBUG_OBJECT (parse, "TrackDefault: %d",
869 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
873 /* whether the track must be used during playback */
874 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
877 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
881 context->flags |= GST_MATROSKA_TRACK_FORCED;
883 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
885 GST_DEBUG_OBJECT (parse, "TrackForced: %d",
886 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
890 /* lacing (like MPEG, where blocks don't end/start on frame
892 case GST_MATROSKA_ID_TRACKFLAGLACING:{
895 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
899 context->flags |= GST_MATROSKA_TRACK_LACING;
901 context->flags &= ~GST_MATROSKA_TRACK_LACING;
903 GST_DEBUG_OBJECT (parse, "TrackLacing: %d",
904 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
908 /* default length (in time) of one data block in this track */
909 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
912 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
917 GST_WARNING_OBJECT (parse, "Invalid TrackDefaultDuration 0");
921 GST_DEBUG_OBJECT (parse, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
923 context->default_duration = num;
927 case GST_MATROSKA_ID_CONTENTENCODINGS:{
928 ret = gst_matroska_read_common_read_track_encodings (&parse->common,
933 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
936 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
940 GST_WARNING_OBJECT (parse, "Invalid TrackTimeCodeScale %lf", num);
944 GST_DEBUG_OBJECT (parse, "TrackTimeCodeScale: %lf", num);
945 context->timecodescale = num;
950 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
953 /* we ignore these because they're nothing useful (i.e. crap)
954 * or simply not implemented yet. */
955 case GST_MATROSKA_ID_TRACKMINCACHE:
956 case GST_MATROSKA_ID_TRACKMAXCACHE:
957 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
958 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
959 case GST_MATROSKA_ID_TRACKOVERLAY:
960 case GST_MATROSKA_ID_TRACKTRANSLATE:
961 case GST_MATROSKA_ID_TRACKOFFSET:
962 case GST_MATROSKA_ID_CODECSETTINGS:
963 case GST_MATROSKA_ID_CODECINFOURL:
964 case GST_MATROSKA_ID_CODECDOWNLOADURL:
965 case GST_MATROSKA_ID_CODECDECODEALL:
966 ret = gst_ebml_read_skip (ebml);
971 DEBUG_ELEMENT_STOP (parse, ebml, "TrackEntry", ret);
973 /* Decode codec private data if necessary */
974 if (context->encodings && context->encodings->len > 0 && context->codec_priv
975 && context->codec_priv_size > 0) {
976 if (!gst_matroska_decode_data (context->encodings,
977 &context->codec_priv, &context->codec_priv_size,
978 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
979 GST_WARNING_OBJECT (parse, "Decoding codec private data failed");
980 ret = GST_FLOW_ERROR;
984 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
985 && ret != GST_FLOW_EOS)) {
986 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
987 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
989 parse->common.num_streams--;
990 g_ptr_array_remove_index (parse->common.src, parse->common.num_streams);
991 g_assert (parse->common.src->len == parse->common.num_streams);
992 gst_matroska_track_free (context);
997 if ((context->language == NULL || *context->language == '\0') &&
998 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
999 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1000 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1001 context->language = g_strdup ("eng");
1010 gst_matroska_parse_query (GstMatroskaParse * parse, GstPad * pad,
1013 gboolean res = FALSE;
1014 GstMatroskaTrackContext *context = NULL;
1017 context = gst_pad_get_element_private (pad);
1020 switch (GST_QUERY_TYPE (query)) {
1021 case GST_QUERY_POSITION:
1025 gst_query_parse_position (query, &format, NULL);
1027 if (format == GST_FORMAT_TIME) {
1028 GST_OBJECT_LOCK (parse);
1030 gst_query_set_position (query, GST_FORMAT_TIME, context->pos);
1032 gst_query_set_position (query, GST_FORMAT_TIME,
1033 parse->common.segment.position);
1034 GST_OBJECT_UNLOCK (parse);
1035 } else if (format == GST_FORMAT_DEFAULT && context
1036 && context->default_duration) {
1037 GST_OBJECT_LOCK (parse);
1038 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1039 context->pos / context->default_duration);
1040 GST_OBJECT_UNLOCK (parse);
1042 GST_DEBUG_OBJECT (parse,
1043 "only position query in TIME and DEFAULT format is supported");
1049 case GST_QUERY_DURATION:
1053 gst_query_parse_duration (query, &format, NULL);
1055 if (format == GST_FORMAT_TIME) {
1056 GST_OBJECT_LOCK (parse);
1057 gst_query_set_duration (query, GST_FORMAT_TIME,
1058 parse->common.segment.duration);
1059 GST_OBJECT_UNLOCK (parse);
1060 } else if (format == GST_FORMAT_DEFAULT && context
1061 && context->default_duration) {
1062 GST_OBJECT_LOCK (parse);
1063 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1064 parse->common.segment.duration / context->default_duration);
1065 GST_OBJECT_UNLOCK (parse);
1067 GST_DEBUG_OBJECT (parse,
1068 "only duration query in TIME and DEFAULT format is supported");
1075 case GST_QUERY_SEEKING:
1079 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1080 if (fmt == GST_FORMAT_TIME) {
1083 /* assuming we'll be able to get an index ... */
1084 seekable = parse->seekable;
1086 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1087 0, parse->common.segment.duration);
1094 res = gst_pad_query_default (pad, (GstObject *) parse, query);
1102 gst_matroska_parse_element_query (GstElement * element, GstQuery * query)
1104 return gst_matroska_parse_query (GST_MATROSKA_PARSE (element), NULL, query);
1108 gst_matroska_parse_handle_src_query (GstPad * pad, GstObject * parent,
1112 GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
1114 ret = gst_matroska_parse_query (parse, pad, query);
1120 gst_matroska_parse_send_tags (GstMatroskaParse * parse)
1122 if (G_UNLIKELY (parse->common.global_tags_changed)) {
1123 GstEvent *tag_event;
1124 gst_tag_list_add (parse->common.global_tags, GST_TAG_MERGE_REPLACE,
1125 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1126 GST_DEBUG_OBJECT (parse, "Sending global_tags %p : %" GST_PTR_FORMAT,
1127 parse->common.global_tags, parse->common.global_tags);
1129 /* Send a copy as we want to keep our local ref writable to add more tags
1130 * if any are found */
1132 gst_event_new_tag (gst_tag_list_copy (parse->common.global_tags));
1134 gst_pad_push_event (parse->srcpad, tag_event);
1136 parse->common.global_tags_changed = FALSE;
1140 /* returns FALSE if there are no pads to deliver event to,
1141 * otherwise TRUE (whatever the outcome of event sending),
1142 * takes ownership of the passed event! */
1144 gst_matroska_parse_send_event (GstMatroskaParse * parse, GstEvent * event)
1146 gboolean ret = FALSE;
1148 g_return_val_if_fail (event != NULL, FALSE);
1150 GST_DEBUG_OBJECT (parse, "Sending event of type %s to all source pads",
1151 GST_EVENT_TYPE_NAME (event));
1153 gst_pad_push_event (parse->srcpad, event);
1159 gst_matroska_parse_element_send_event (GstElement * element, GstEvent * event)
1161 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
1164 g_return_val_if_fail (event != NULL, FALSE);
1166 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1167 res = gst_matroska_parse_handle_seek_event (parse, NULL, event);
1169 GST_WARNING_OBJECT (parse, "Unhandled event of type %s",
1170 GST_EVENT_TYPE_NAME (event));
1173 gst_event_unref (event);
1178 /* searches for a cluster start from @pos,
1179 * return GST_FLOW_OK and cluster position in @pos if found */
1180 static GstFlowReturn
1181 gst_matroska_parse_search_cluster (GstMatroskaParse * parse, gint64 * pos)
1183 gint64 newpos = *pos;
1185 GstFlowReturn ret = GST_FLOW_OK;
1186 const guint chunk = 64 * 1024;
1195 orig_offset = parse->common.offset;
1197 /* read in at newpos and scan for ebml cluster id */
1199 GstByteReader reader;
1203 ret = gst_pad_pull_range (parse->common.sinkpad, newpos, chunk, &buf);
1204 if (ret != GST_FLOW_OK)
1206 GST_DEBUG_OBJECT (parse,
1207 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1208 gst_buffer_get_size (buf), newpos);
1209 gst_buffer_map (buf, &map, GST_MAP_READ);
1212 gst_byte_reader_init (&reader, data, size);
1215 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1216 GST_MATROSKA_ID_CLUSTER, cluster_pos, size - cluster_pos);
1217 if (cluster_pos >= 0) {
1218 newpos += cluster_pos;
1219 GST_DEBUG_OBJECT (parse,
1220 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1221 /* extra checks whether we really sync'ed to a cluster:
1222 * - either it is the first and only cluster
1223 * - either there is a cluster after this one
1224 * - either cluster length is undefined
1226 /* ok if first cluster (there may not a subsequent one) */
1227 if (newpos == parse->first_cluster_offset) {
1228 GST_DEBUG_OBJECT (parse, "cluster is first cluster -> OK");
1231 parse->common.offset = newpos;
1232 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1233 GST_ELEMENT_CAST (parse), &id, &length, &needed);
1234 if (ret != GST_FLOW_OK)
1236 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1237 GST_DEBUG_OBJECT (parse, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1239 /* ok if undefined length or first cluster */
1240 if (length == G_MAXUINT64) {
1241 GST_DEBUG_OBJECT (parse, "cluster has undefined length -> OK");
1245 parse->common.offset += length + needed;
1246 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1247 GST_ELEMENT_CAST (parse), &id, &length, &needed);
1248 if (ret != GST_FLOW_OK)
1250 GST_DEBUG_OBJECT (parse, "next element is %scluster",
1251 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1252 if (id == GST_MATROSKA_ID_CLUSTER)
1254 /* not ok, resume */
1257 /* partial cluster id may have been in tail of buffer */
1258 newpos += MAX (size, 4) - 3;
1259 gst_buffer_unmap (buf, &map);
1260 gst_buffer_unref (buf);
1266 gst_buffer_unmap (buf, &map);
1267 gst_buffer_unref (buf);
1271 parse->common.offset = orig_offset;
1278 gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
1279 GstPad * pad, GstEvent * event)
1281 GstMatroskaIndex *entry = NULL;
1283 GstSeekType cur_type, stop_type;
1287 GstMatroskaTrackContext *track = NULL;
1288 GstSegment seeksegment = { 0, };
1290 GstSearchMode snap_dir;
1293 track = gst_pad_get_element_private (pad);
1295 track = gst_matroska_read_common_get_seek_track (&parse->common, track);
1297 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1300 /* we can only seek on time */
1301 if (format != GST_FORMAT_TIME) {
1302 GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1306 /* copy segment, we need this because we still need the old
1307 * segment when we close the current segment. */
1308 memcpy (&seeksegment, &parse->common.segment, sizeof (GstSegment));
1311 GST_DEBUG_OBJECT (parse, "configuring seek");
1312 gst_segment_do_seek (&seeksegment, rate, format, flags,
1313 cur_type, cur, stop_type, stop, &update);
1316 GST_DEBUG_OBJECT (parse, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1318 if (seeksegment.rate < 0)
1319 snap_dir = GST_SEARCH_MODE_AFTER;
1321 snap_dir = GST_SEARCH_MODE_BEFORE;
1323 /* check sanity before we start flushing and all that */
1324 GST_OBJECT_LOCK (parse);
1325 if ((entry = gst_matroska_read_common_do_index_seek (&parse->common, track,
1326 seeksegment.position, &parse->seek_index, &parse->seek_entry,
1327 snap_dir)) == NULL) {
1328 /* pull mode without index can scan later on */
1329 GST_DEBUG_OBJECT (parse, "No matching seek entry in index");
1330 GST_OBJECT_UNLOCK (parse);
1333 GST_DEBUG_OBJECT (parse, "Seek position looks sane");
1334 GST_OBJECT_UNLOCK (parse);
1336 /* need to seek to cluster start to pick up cluster time */
1337 /* upstream takes care of flushing and all that
1338 * ... and newsegment event handling takes care of the rest */
1339 return perform_seek_to_offset (parse, entry->pos
1340 + parse->common.ebml_segment_start);
1344 * Handle whether we can perform the seek event or if we have to let the chain
1345 * function handle seeks to build the seek indexes first.
1348 gst_matroska_parse_handle_seek_push (GstMatroskaParse * parse, GstPad * pad,
1352 GstSeekType cur_type, stop_type;
1357 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1362 /* we can only seek on time */
1363 if (format != GST_FORMAT_TIME) {
1364 GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1368 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
1369 GST_DEBUG_OBJECT (parse, "Seek end-time not supported in streaming mode");
1373 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
1374 GST_DEBUG_OBJECT (parse,
1375 "Non-flushing seek not supported in streaming mode");
1379 if (flags & GST_SEEK_FLAG_SEGMENT) {
1380 GST_DEBUG_OBJECT (parse, "Segment seek not supported in streaming mode");
1384 /* check for having parsed index already */
1385 if (!parse->common.index_parsed) {
1386 gboolean building_index;
1389 if (!parse->index_offset) {
1390 GST_DEBUG_OBJECT (parse, "no index (location); no seek in push mode");
1394 GST_OBJECT_LOCK (parse);
1395 /* handle the seek event in the chain function */
1396 parse->common.state = GST_MATROSKA_READ_STATE_SEEK;
1397 /* no more seek can be issued until state reset to _DATA */
1399 /* copy the event */
1400 if (parse->seek_event)
1401 gst_event_unref (parse->seek_event);
1402 parse->seek_event = gst_event_ref (event);
1404 /* set the building_index flag so that only one thread can setup the
1405 * structures for index seeking. */
1406 building_index = parse->building_index;
1407 if (!building_index) {
1408 parse->building_index = TRUE;
1409 offset = parse->index_offset;
1411 GST_OBJECT_UNLOCK (parse);
1413 if (!building_index) {
1414 /* seek to the first subindex or legacy index */
1415 GST_INFO_OBJECT (parse, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
1416 return perform_seek_to_offset (parse, offset);
1419 /* well, we are handling it already */
1423 /* delegate to tweaked regular seek */
1424 return gst_matroska_parse_handle_seek_event (parse, pad, event);
1428 gst_matroska_parse_handle_src_event (GstPad * pad, GstObject * parent,
1431 GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
1432 gboolean res = TRUE;
1434 switch (GST_EVENT_TYPE (event)) {
1435 case GST_EVENT_SEEK:
1436 /* no seeking until we are (safely) ready */
1437 if (parse->common.state != GST_MATROSKA_READ_STATE_DATA) {
1438 GST_DEBUG_OBJECT (parse, "not ready for seeking yet");
1441 res = gst_matroska_parse_handle_seek_push (parse, pad, event);
1442 gst_event_unref (event);
1447 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
1448 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
1449 GstMatroskaTrackVideoContext *videocontext =
1450 (GstMatroskaTrackVideoContext *) context;
1452 GstClockTimeDiff diff;
1453 GstClockTime timestamp;
1455 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
1457 GST_OBJECT_LOCK (parse);
1458 videocontext->earliest_time = timestamp + diff;
1459 GST_OBJECT_UNLOCK (parse);
1462 gst_event_unref (event);
1466 /* events we don't need to handle */
1467 case GST_EVENT_NAVIGATION:
1468 gst_event_unref (event);
1472 case GST_EVENT_LATENCY:
1474 res = gst_pad_push_event (parse->common.sinkpad, event);
1481 static GstFlowReturn
1482 gst_matroska_parse_parse_tracks (GstMatroskaParse * parse, GstEbmlRead * ebml)
1484 GstFlowReturn ret = GST_FLOW_OK;
1487 DEBUG_ELEMENT_START (parse, ebml, "Tracks");
1489 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1490 DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1494 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1495 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1499 /* one track within the "all-tracks" header */
1500 case GST_MATROSKA_ID_TRACKENTRY:
1501 ret = gst_matroska_parse_add_stream (parse, ebml);
1505 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1510 DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1512 parse->tracks_parsed = TRUE;
1518 * Read signed/unsigned "EBML" numbers.
1519 * Return: number of bytes processed.
1523 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
1525 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
1533 while (read <= 8 && !(total & len_mask)) {
1540 if ((total &= (len_mask - 1)) == len_mask - 1)
1545 if (data[n] == 0xff)
1547 total = (total << 8) | data[n];
1551 if (read == num_ffs && total != 0)
1560 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
1565 /* read as unsigned number first */
1566 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
1570 if (unum == G_MAXUINT64)
1573 *num = unum - ((1 << ((7 * res) - 1)) - 1);
1578 static GstFlowReturn
1579 gst_matroska_parse_parse_blockgroup_or_simpleblock (GstMatroskaParse * parse,
1580 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
1581 gboolean is_simpleblock)
1583 GstMatroskaTrackContext *stream = NULL;
1584 GstFlowReturn ret = GST_FLOW_OK;
1585 gboolean readblock = FALSE;
1587 guint64 block_duration = 0;
1588 GstBuffer *buf = NULL;
1590 gint stream_num = -1, n, laces = 0;
1592 gint *lace_size = NULL;
1595 gint64 referenceblock = 0;
1597 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1598 if (!is_simpleblock) {
1599 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
1603 id = GST_MATROSKA_ID_SIMPLEBLOCK;
1607 /* one block inside the group. Note, block parsing is one
1608 * of the harder things, so this code is a bit complicated.
1609 * See http://www.matroska.org/ for documentation. */
1610 case GST_MATROSKA_ID_SIMPLEBLOCK:
1611 case GST_MATROSKA_ID_BLOCK:
1617 gst_buffer_unref (buf);
1620 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
1623 gst_buffer_map (buf, &map, GST_MAP_READ);
1627 /* first byte(s): blocknum */
1628 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1633 /* fetch stream from num */
1634 stream_num = gst_matroska_read_common_stream_from_num (&parse->common,
1636 if (G_UNLIKELY (size < 3)) {
1637 GST_WARNING_OBJECT (parse, "Invalid size %u", size);
1638 /* non-fatal, try next block(group) */
1641 } else if (G_UNLIKELY (stream_num < 0 ||
1642 stream_num >= parse->common.num_streams)) {
1643 /* let's not give up on a stray invalid track number */
1644 GST_WARNING_OBJECT (parse,
1645 "Invalid stream %d for track number %" G_GUINT64_FORMAT
1646 "; ignoring block", stream_num, num);
1650 stream = g_ptr_array_index (parse->common.src, stream_num);
1652 /* time (relative to cluster time) */
1653 time = ((gint16) GST_READ_UINT16_BE (data));
1656 flags = GST_READ_UINT8 (data);
1660 GST_LOG_OBJECT (parse, "time %" G_GUINT64_FORMAT ", flags %d", time,
1663 switch ((flags & 0x06) >> 1) {
1664 case 0x0: /* no lacing */
1666 lace_size = g_new (gint, 1);
1667 lace_size[0] = size;
1670 case 0x1: /* xiph lacing */
1671 case 0x2: /* fixed-size lacing */
1672 case 0x3: /* EBML lacing */
1674 goto invalid_lacing;
1675 laces = GST_READ_UINT8 (data) + 1;
1678 lace_size = g_new0 (gint, laces);
1680 switch ((flags & 0x06) >> 1) {
1681 case 0x1: /* xiph lacing */ {
1682 guint temp, total = 0;
1684 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
1687 goto invalid_lacing;
1688 temp = GST_READ_UINT8 (data);
1689 lace_size[n] += temp;
1695 total += lace_size[n];
1697 lace_size[n] = size - total;
1701 case 0x2: /* fixed-size lacing */
1702 for (n = 0; n < laces; n++)
1703 lace_size[n] = size / laces;
1706 case 0x3: /* EBML lacing */ {
1709 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1713 total = lace_size[0] = num;
1714 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
1718 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
1722 lace_size[n] = lace_size[n - 1] + snum;
1723 total += lace_size[n];
1726 lace_size[n] = size - total;
1733 if (ret != GST_FLOW_OK)
1740 case GST_MATROSKA_ID_BLOCKDURATION:{
1741 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
1742 GST_DEBUG_OBJECT (parse, "BlockDuration: %" G_GUINT64_FORMAT,
1747 case GST_MATROSKA_ID_REFERENCEBLOCK:{
1748 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
1749 GST_DEBUG_OBJECT (parse, "ReferenceBlock: %" G_GINT64_FORMAT,
1754 case GST_MATROSKA_ID_CODECSTATE:{
1756 guint64 data_len = 0;
1759 gst_ebml_read_binary (ebml, &id, &data,
1760 &data_len)) != GST_FLOW_OK)
1763 if (G_UNLIKELY (stream == NULL)) {
1764 GST_WARNING_OBJECT (parse,
1765 "Unexpected CodecState subelement - ignoring");
1769 g_free (stream->codec_state);
1770 stream->codec_state = data;
1771 stream->codec_state_size = data_len;
1777 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1781 case GST_MATROSKA_ID_BLOCKVIRTUAL:
1782 case GST_MATROSKA_ID_BLOCKADDITIONS:
1783 case GST_MATROSKA_ID_REFERENCEPRIORITY:
1784 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
1785 case GST_MATROSKA_ID_SLICES:
1786 GST_DEBUG_OBJECT (parse,
1787 "Skipping BlockGroup subelement 0x%x - ignoring", id);
1788 ret = gst_ebml_read_skip (ebml);
1796 /* reading a number or so could have failed */
1797 if (ret != GST_FLOW_OK)
1800 if (ret == GST_FLOW_OK && readblock) {
1801 guint64 duration = 0;
1802 gint64 lace_time = 0;
1803 gboolean delta_unit;
1805 stream = g_ptr_array_index (parse->common.src, stream_num);
1807 if (cluster_time != GST_CLOCK_TIME_NONE) {
1808 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
1809 * Drop unless the lace contains timestamp 0? */
1810 if (time < 0 && (-time) > cluster_time) {
1813 if (stream->timecodescale == 1.0)
1814 lace_time = (cluster_time + time) * parse->common.time_scale;
1817 gst_util_guint64_to_gdouble ((cluster_time + time) *
1818 parse->common.time_scale) * stream->timecodescale;
1821 lace_time = GST_CLOCK_TIME_NONE;
1824 if (lace_time != GST_CLOCK_TIME_NONE) {
1825 parse->last_timestamp = lace_time;
1827 /* need to refresh segment info ASAP */
1828 if (GST_CLOCK_TIME_IS_VALID (lace_time) && parse->need_newsegment) {
1830 GST_DEBUG_OBJECT (parse,
1831 "generating segment starting at %" GST_TIME_FORMAT,
1832 GST_TIME_ARGS (lace_time));
1833 /* pretend we seeked here */
1834 gst_segment_do_seek (&parse->common.segment, parse->common.segment.rate,
1835 GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, lace_time,
1836 GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE, NULL);
1837 /* now convey our segment notion downstream */
1838 segment = parse->common.segment;
1839 segment.position = segment.start;
1840 gst_matroska_parse_send_event (parse, gst_event_new_segment (&segment));
1841 parse->need_newsegment = FALSE;
1844 if (block_duration) {
1845 if (stream->timecodescale == 1.0)
1846 duration = gst_util_uint64_scale (block_duration,
1847 parse->common.time_scale, 1);
1850 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
1851 (gst_util_uint64_scale (block_duration, parse->common.time_scale,
1852 1)) * stream->timecodescale);
1853 } else if (stream->default_duration) {
1854 duration = stream->default_duration * laces;
1856 /* else duration is diff between timecode of this and next block */
1858 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
1859 a ReferenceBlock implies that this is not a keyframe. In either
1860 case, it only makes sense for video streams. */
1861 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1862 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
1864 if (delta_unit && stream->set_discont) {
1865 /* When doing seeks or such, we need to restart on key frames or
1866 * decoders might choke. */
1867 GST_DEBUG_OBJECT (parse, "skipping delta unit");
1871 for (n = 0; n < laces; n++) {
1872 if (G_UNLIKELY (lace_size[n] > size)) {
1873 GST_WARNING_OBJECT (parse, "Invalid lace size");
1877 /* QoS for video track with an index. the assumption is that
1878 index entries point to keyframes, but if that is not true we
1879 will instead skip until the next keyframe. */
1880 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1881 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1882 stream->index_table && parse->common.segment.rate > 0.0) {
1883 GstMatroskaTrackVideoContext *videocontext =
1884 (GstMatroskaTrackVideoContext *) stream;
1885 GstClockTime earliest_time;
1886 GstClockTime earliest_stream_time;
1888 GST_OBJECT_LOCK (parse);
1889 earliest_time = videocontext->earliest_time;
1890 GST_OBJECT_UNLOCK (parse);
1891 earliest_stream_time =
1892 gst_segment_position_from_running_time (&parse->common.segment,
1893 GST_FORMAT_TIME, earliest_time);
1895 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1896 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
1897 lace_time <= earliest_stream_time) {
1898 /* find index entry (keyframe) <= earliest_stream_time */
1899 GstMatroskaIndex *entry =
1900 gst_util_array_binary_search (stream->index_table->data,
1901 stream->index_table->len, sizeof (GstMatroskaIndex),
1902 (GCompareDataFunc) gst_matroska_index_seek_find,
1903 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
1905 /* if that entry (keyframe) is after the current the current
1906 buffer, we can skip pushing (and thus decoding) all
1907 buffers until that keyframe. */
1908 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
1909 entry->time > lace_time) {
1910 GST_LOG_OBJECT (parse, "Skipping lace before late keyframe");
1911 stream->set_discont = TRUE;
1917 sub = gst_buffer_create_sub (buf,
1918 GST_BUFFER_SIZE (buf) - size, lace_size[n]);
1919 GST_DEBUG_OBJECT (parse, "created subbuffer %p", sub);
1922 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1924 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1926 if (stream->encodings != NULL && stream->encodings->len > 0)
1927 sub = gst_matroska_decode_buffer (stream, sub);
1930 GST_WARNING_OBJECT (parse, "Decoding buffer failed");
1934 GST_BUFFER_TIMESTAMP (sub) = lace_time;
1936 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
1937 GstClockTime last_stop_end;
1939 /* Check if this stream is after segment stop */
1940 if (GST_CLOCK_TIME_IS_VALID (parse->common.segment.stop) &&
1941 lace_time >= parse->common.segment.stop) {
1942 GST_DEBUG_OBJECT (parse,
1943 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
1944 GST_TIME_ARGS (parse->common.segment.stop));
1945 gst_buffer_unref (sub);
1948 if (offset >= stream->to_offset) {
1949 GST_DEBUG_OBJECT (parse, "Stream %d after playback section",
1951 gst_buffer_unref (sub);
1955 /* handle gaps, e.g. non-zero start-time, or an cue index entry
1956 * that landed us with timestamps not quite intended */
1957 if (GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop) &&
1958 parse->segment.rate > 0.0) {
1959 GstClockTimeDiff diff;
1961 /* only send newsegments with increasing start times,
1962 * otherwise if these go back and forth downstream (sinks) increase
1963 * accumulated time and running_time */
1964 diff = GST_CLOCK_DIFF (parse->segment.last_stop, lace_time);
1965 if (diff > 2 * GST_SECOND && lace_time > parse->segment.start &&
1966 (!GST_CLOCK_TIME_IS_VALID (parse->segment.stop) ||
1967 lace_time < parse->segment.stop)) {
1968 GST_DEBUG_OBJECT (parse,
1969 "Gap of %" G_GINT64_FORMAT " ns detected in"
1970 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
1971 "Sending updated NEWSEGMENT events", diff,
1972 stream->index, GST_TIME_ARGS (stream->pos),
1973 GST_TIME_ARGS (lace_time));
1974 /* send newsegment events such that the gap is not accounted in
1975 * accum time, hence running_time */
1976 /* close ahead of gap */
1977 gst_matroska_parse_send_event (parse,
1978 gst_event_new_new_segment (TRUE, parse->segment.rate,
1979 parse->segment.format, parse->segment.last_stop,
1980 parse->segment.last_stop, parse->segment.last_stop));
1982 gst_matroska_parse_send_event (parse,
1983 gst_event_new_new_segment (FALSE, parse->segment.rate,
1984 parse->segment.format, lace_time, parse->segment.stop,
1986 /* align segment view with downstream,
1987 * prevents double-counting accum when closing segment */
1988 gst_segment_set_newsegment (&parse->segment, FALSE,
1989 parse->segment.rate, parse->segment.format, lace_time,
1990 parse->segment.stop, lace_time);
1991 parse->segment.last_stop = lace_time;
1995 if (!GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop)
1996 || parse->segment.last_stop < lace_time) {
1997 parse->segment.last_stop = lace_time;
2000 last_stop_end = lace_time;
2002 GST_BUFFER_DURATION (sub) = duration / laces;
2003 last_stop_end += GST_BUFFER_DURATION (sub);
2006 if (!GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) ||
2007 parse->last_stop_end < last_stop_end)
2008 parse->last_stop_end = last_stop_end;
2010 if (parse->segment.duration == -1 ||
2011 parse->segment.duration < lace_time) {
2012 gst_segment_set_duration (&parse->segment, GST_FORMAT_TIME,
2014 gst_element_post_message (GST_ELEMENT_CAST (parse),
2015 gst_message_new_duration (GST_OBJECT_CAST (parse),
2016 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
2020 stream->pos = lace_time;
2022 gst_matroska_parse_sync_streams (parse);
2024 if (stream->set_discont) {
2025 GST_DEBUG_OBJECT (parse, "marking DISCONT");
2026 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
2027 stream->set_discont = FALSE;
2030 /* reverse playback book-keeping */
2031 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
2032 stream->from_time = lace_time;
2033 if (stream->from_offset == -1)
2034 stream->from_offset = offset;
2036 GST_DEBUG_OBJECT (parse,
2037 "Pushing lace %d, data of size %d for stream %d, time=%"
2038 GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
2039 GST_BUFFER_SIZE (sub), stream_num,
2040 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
2041 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
2043 if (parse->element_index) {
2044 if (stream->index_writer_id == -1)
2045 gst_index_get_writer_id (parse->element_index,
2046 GST_OBJECT (stream->pad), &stream->index_writer_id);
2048 GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
2049 G_GUINT64_FORMAT " for writer id %d",
2050 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
2051 stream->index_writer_id);
2052 gst_index_add_association (parse->element_index,
2053 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
2054 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
2055 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
2056 cluster_offset, NULL);
2059 gst_buffer_set_caps (sub, GST_PAD_CAPS (parse->srcpad));
2061 /* Postprocess the buffers depending on the codec used */
2062 if (stream->postprocess_frame) {
2063 GST_LOG_OBJECT (parse, "running post process");
2064 ret = stream->postprocess_frame (GST_ELEMENT (parse), stream, &sub);
2067 ret = gst_pad_push (stream->pad, sub);
2068 if (parse->segment.rate < 0) {
2069 if (lace_time > parse->segment.stop && ret == GST_FLOW_EOS) {
2070 /* In reverse playback we can get a GST_FLOW_EOS when
2071 * we are at the end of the segment, so we just need to jump
2072 * back to the previous section. */
2073 GST_DEBUG_OBJECT (parse, "downstream has reached end of segment");
2078 ret = gst_matroska_parse_combine_flows (parse, stream, ret);
2082 size -= lace_size[n];
2083 if (lace_time != GST_CLOCK_TIME_NONE && duration)
2084 lace_time += duration / laces;
2086 lace_time = GST_CLOCK_TIME_NONE;
2092 gst_buffer_unmap (buf, &map);
2093 gst_buffer_unref (buf);
2102 GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
2103 /* non-fatal, try next block(group) */
2109 GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Data error"));
2110 /* non-fatal, try next block(group) */
2116 /* return FALSE if block(group) should be skipped (due to a seek) */
2117 static inline gboolean
2118 gst_matroska_parse_seek_block (GstMatroskaParse * parse)
2120 if (G_UNLIKELY (parse->seek_block)) {
2121 if (!(--parse->seek_block)) {
2124 GST_LOG_OBJECT (parse, "should skip block due to seek");
2132 static GstFlowReturn
2133 gst_matroska_parse_parse_contents_seekentry (GstMatroskaParse * parse,
2137 guint64 seek_pos = (guint64) - 1;
2138 guint32 seek_id = 0;
2141 DEBUG_ELEMENT_START (parse, ebml, "Seek");
2143 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2144 DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2148 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2149 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2153 case GST_MATROSKA_ID_SEEKID:
2157 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2160 GST_DEBUG_OBJECT (parse, "SeekID: %" G_GUINT64_FORMAT, t);
2165 case GST_MATROSKA_ID_SEEKPOSITION:
2169 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2172 if (t > G_MAXINT64) {
2173 GST_WARNING_OBJECT (parse,
2174 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
2178 GST_DEBUG_OBJECT (parse, "SeekPosition: %" G_GUINT64_FORMAT, t);
2184 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2190 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
2193 if (!seek_id || seek_pos == (guint64) - 1) {
2194 GST_WARNING_OBJECT (parse, "Incomplete seekhead entry (0x%x/%"
2195 G_GUINT64_FORMAT ")", seek_id, seek_pos);
2200 case GST_MATROSKA_ID_SEEKHEAD:
2203 case GST_MATROSKA_ID_CUES:
2204 case GST_MATROSKA_ID_TAGS:
2205 case GST_MATROSKA_ID_TRACKS:
2206 case GST_MATROSKA_ID_SEGMENTINFO:
2207 case GST_MATROSKA_ID_ATTACHMENTS:
2208 case GST_MATROSKA_ID_CHAPTERS:
2213 length = gst_matroska_read_common_get_length (&parse->common);
2215 if (length == (guint64) - 1) {
2216 GST_DEBUG_OBJECT (parse, "no upstream length, skipping SeakHead entry");
2220 /* check for validity */
2221 if (seek_pos + parse->common.ebml_segment_start + 12 >= length) {
2222 GST_WARNING_OBJECT (parse,
2223 "SeekHead reference lies outside file!" " (%"
2224 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
2225 G_GUINT64_FORMAT ")", seek_pos, parse->common.ebml_segment_start,
2230 /* only pick up index location when streaming */
2231 if (seek_id == GST_MATROSKA_ID_CUES) {
2232 parse->index_offset = seek_pos + parse->common.ebml_segment_start;
2233 GST_DEBUG_OBJECT (parse, "Cues located at offset %" G_GUINT64_FORMAT,
2234 parse->index_offset);
2240 GST_DEBUG_OBJECT (parse, "Ignoring Seek entry for ID=0x%x", seek_id);
2243 DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2248 static GstFlowReturn
2249 gst_matroska_parse_parse_contents (GstMatroskaParse * parse, GstEbmlRead * ebml)
2251 GstFlowReturn ret = GST_FLOW_OK;
2254 DEBUG_ELEMENT_START (parse, ebml, "SeekHead");
2256 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2257 DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2261 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2262 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2266 case GST_MATROSKA_ID_SEEKENTRY:
2268 ret = gst_matroska_parse_parse_contents_seekentry (parse, ebml);
2269 /* Ignore EOS and errors here */
2270 if (ret != GST_FLOW_OK) {
2271 GST_DEBUG_OBJECT (parse, "Ignoring %s", gst_flow_get_name (ret));
2278 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2284 DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2289 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
2291 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
2293 static inline GstFlowReturn
2294 gst_matroska_parse_check_read_size (GstMatroskaParse * parse, guint64 bytes)
2296 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
2297 /* only a few blocks are expected/allowed to be large,
2298 * and will be recursed into, whereas others will be read and must fit */
2299 /* fatal in streaming case, as we can't step over easily */
2300 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2301 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
2302 "file might be corrupt.", bytes));
2303 return GST_FLOW_ERROR;
2310 /* returns TRUE if we truly are in error state, and should give up */
2311 static inline gboolean
2312 gst_matroska_parse_check_parse_error (GstMatroskaParse * parse)
2316 /* sigh, one last attempt above and beyond call of duty ...;
2317 * search for cluster mark following current pos */
2318 pos = parse->common.offset;
2319 GST_WARNING_OBJECT (parse, "parse error, looking for next cluster");
2320 if (gst_matroska_parse_search_cluster (parse, &pos) != GST_FLOW_OK) {
2321 /* did not work, give up */
2324 GST_DEBUG_OBJECT (parse, "... found at %" G_GUINT64_FORMAT, pos);
2325 /* try that position */
2326 parse->common.offset = pos;
2332 /* initializes @ebml with @bytes from input stream at current offset.
2333 * Returns EOS if insufficient available,
2334 * ERROR if too much was attempted to read. */
2335 static inline GstFlowReturn
2336 gst_matroska_parse_take (GstMatroskaParse * parse, guint64 bytes,
2339 GstBuffer *buffer = NULL;
2340 GstFlowReturn ret = GST_FLOW_OK;
2342 GST_LOG_OBJECT (parse, "taking %" G_GUINT64_FORMAT " bytes for parsing",
2344 ret = gst_matroska_parse_check_read_size (parse, bytes);
2345 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
2346 /* otherwise fatal */
2347 ret = GST_FLOW_ERROR;
2350 if (gst_adapter_available (parse->common.adapter) < bytes)
2351 return GST_FLOW_EOS;
2353 buffer = gst_adapter_take_buffer (parse->common.adapter, bytes);
2354 if (G_LIKELY (buffer)) {
2355 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (parse), buffer,
2356 parse->common.offset);
2357 parse->common.offset += bytes;
2359 ret = GST_FLOW_ERROR;
2367 gst_matroska_parse_check_seekability (GstMatroskaParse * parse)
2370 gboolean seekable = FALSE;
2371 gint64 start = -1, stop = -1;
2373 query = gst_query_new_seeking (GST_FORMAT_BYTES);
2374 if (!gst_pad_peer_query (parse->common.sinkpad, query)) {
2375 GST_DEBUG_OBJECT (parse, "seeking query failed");
2379 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
2381 /* try harder to query upstream size if we didn't get it the first time */
2382 if (seekable && stop == -1) {
2383 GST_DEBUG_OBJECT (parse, "doing duration query to fix up unset stop");
2384 gst_pad_peer_query_duration (parse->common.sinkpad, GST_FORMAT_BYTES,
2388 /* if upstream doesn't know the size, it's likely that it's not seekable in
2389 * practice even if it technically may be seekable */
2390 if (seekable && (start != 0 || stop <= start)) {
2391 GST_DEBUG_OBJECT (parse, "seekable but unknown start/stop -> disable");
2396 GST_INFO_OBJECT (parse, "seekable: %d (%" G_GUINT64_FORMAT " - %"
2397 G_GUINT64_FORMAT ")", seekable, start, stop);
2398 parse->seekable = seekable;
2400 gst_query_unref (query);
2404 static GstFlowReturn
2405 gst_matroska_parse_find_tracks (GstMatroskaParse * parse)
2411 GstFlowReturn ret = GST_FLOW_OK;
2413 GST_WARNING_OBJECT (parse,
2414 "Found Cluster element before Tracks, searching Tracks");
2417 before_pos = parse->common.offset;
2419 /* Search Tracks element */
2421 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2422 GST_ELEMENT_CAST (parse), &id, &length, &needed);
2423 if (ret != GST_FLOW_OK)
2426 if (id != GST_MATROSKA_ID_TRACKS) {
2427 /* we may be skipping large cluster here, so forego size check etc */
2428 /* ... but we can't skip undefined size; force error */
2429 if (length == G_MAXUINT64) {
2430 ret = gst_matroska_parse_check_read_size (parse, length);
2433 parse->common.offset += needed;
2434 parse->offset += length;
2439 /* will lead to track parsing ... */
2440 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2445 parse->offset = before_pos;
2451 #define GST_READ_CHECK(stmt) \
2453 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
2454 if (ret == GST_FLOW_OVERFLOW) { \
2455 ret = GST_FLOW_OK; \
2462 gst_matroska_parse_accumulate_streamheader (GstMatroskaParse * parse,
2465 if (parse->pushed_headers) {
2466 GST_WARNING_OBJECT (parse,
2467 "Accumulating headers, but headers are already pushed");
2470 if (parse->streamheader) {
2471 parse->streamheader = gst_buffer_append (parse->streamheader,
2472 gst_buffer_ref (buffer));
2474 parse->streamheader = gst_buffer_ref (buffer);
2477 GST_DEBUG ("%" G_GSIZE_FORMAT, gst_buffer_get_size (parse->streamheader));
2480 static GstFlowReturn
2481 gst_matroska_parse_output (GstMatroskaParse * parse, GstBuffer * buffer,
2486 if (!parse->pushed_headers) {
2489 GValue streamheader = { 0 };
2490 GValue bufval = { 0 };
2493 caps = gst_pad_get_current_caps (parse->common.sinkpad);
2495 caps = gst_matroska_parse_forge_caps (parse->common.is_webm,
2496 parse->common.has_video);
2498 caps = gst_caps_make_writable (caps);
2500 s = gst_caps_get_structure (caps, 0);
2501 g_value_init (&streamheader, GST_TYPE_ARRAY);
2502 g_value_init (&bufval, GST_TYPE_BUFFER);
2503 buf = gst_buffer_copy (parse->streamheader);
2504 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2505 gst_value_set_buffer (&bufval, buf);
2506 gst_buffer_unref (buf);
2507 gst_value_array_append_value (&streamheader, &bufval);
2508 g_value_unset (&bufval);
2509 gst_structure_set_value (s, "streamheader", &streamheader);
2510 g_value_unset (&streamheader);
2511 //gst_caps_replace (parse->caps, caps);
2512 gst_pad_set_caps (parse->srcpad, caps);
2514 if (parse->need_newsegment) {
2515 gst_pad_push_event (parse->srcpad,
2516 gst_event_new_segment (&parse->common.segment));
2517 parse->need_newsegment = FALSE;
2520 buf = gst_buffer_copy (parse->streamheader);
2521 gst_caps_unref (caps);
2523 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2524 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2525 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
2527 ret = gst_pad_push (parse->srcpad, buf);
2528 if (ret != GST_FLOW_OK) {
2529 GST_WARNING_OBJECT (parse, "Failed to push buffer");
2533 parse->pushed_headers = TRUE;
2537 GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2539 GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2541 if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE) {
2542 parse->last_timestamp = GST_BUFFER_TIMESTAMP (buffer);
2544 GST_BUFFER_TIMESTAMP (buffer) = parse->last_timestamp;
2547 return gst_pad_push (parse->srcpad, gst_buffer_ref (buffer));
2550 static GstFlowReturn
2551 gst_matroska_parse_parse_id (GstMatroskaParse * parse, guint32 id,
2552 guint64 length, guint needed)
2554 GstEbmlRead ebml = { 0, };
2555 GstFlowReturn ret = GST_FLOW_OK;
2557 //GstBuffer *buffer;
2559 GST_DEBUG_OBJECT (parse, "Parsing Element id 0x%x, "
2560 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
2563 if (gst_adapter_available (parse->adapter) >= length + needed) {
2564 buffer = gst_adapter_take_buffer (parse->adapter, length + needed);
2565 gst_pad_push (parse->srcpad, buffer);
2569 //GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2576 /* if we plan to read and parse this element, we need prefix (id + length)
2577 * and the contents */
2578 /* mind about overflow wrap-around when dealing with undefined size */
2580 if (G_LIKELY (length != G_MAXUINT64))
2583 switch (parse->common.state) {
2584 case GST_MATROSKA_READ_STATE_START:
2586 case GST_EBML_ID_HEADER:
2587 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2588 ret = gst_matroska_read_common_parse_header (&parse->common, &ebml);
2589 if (ret != GST_FLOW_OK)
2591 parse->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
2592 gst_matroska_parse_check_seekability (parse);
2593 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2596 goto invalid_header;
2600 case GST_MATROSKA_READ_STATE_SEGMENT:
2602 case GST_MATROSKA_ID_SEGMENT:
2603 /* eat segment prefix */
2604 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2605 GST_DEBUG_OBJECT (parse,
2606 "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
2607 G_GUINT64_FORMAT, parse->common.offset, length);
2608 /* seeks are from the beginning of the segment,
2609 * after the segment ID/length */
2610 parse->common.ebml_segment_start = parse->common.offset;
2612 length = G_MAXUINT64;
2613 parse->common.ebml_segment_length = length;
2614 parse->common.state = GST_MATROSKA_READ_STATE_HEADER;
2615 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2618 GST_WARNING_OBJECT (parse,
2619 "Expected a Segment ID (0x%x), but received 0x%x!",
2620 GST_MATROSKA_ID_SEGMENT, id);
2621 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2622 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2626 case GST_MATROSKA_READ_STATE_SCANNING:
2627 if (id != GST_MATROSKA_ID_CLUSTER &&
2628 id != GST_MATROSKA_ID_CLUSTERTIMECODE) {
2629 /* we need to skip byte per byte if we are scanning for a new cluster */
2633 GST_LOG_OBJECT (parse, "Resync done, new cluster found!");
2634 parse->common.start_resync_offset = -1;
2635 parse->common.state = parse->common.state_to_restore;
2638 case GST_MATROSKA_READ_STATE_HEADER:
2639 case GST_MATROSKA_READ_STATE_DATA:
2640 case GST_MATROSKA_READ_STATE_SEEK:
2642 case GST_MATROSKA_ID_SEGMENTINFO:
2643 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2644 if (!parse->common.segmentinfo_parsed) {
2645 ret = gst_matroska_read_common_parse_info (&parse->common,
2646 GST_ELEMENT_CAST (parse), &ebml);
2647 if (ret == GST_FLOW_OK)
2648 gst_matroska_parse_send_tags (parse);
2650 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2652 case GST_MATROSKA_ID_TRACKS:
2653 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2654 if (!parse->tracks_parsed) {
2655 ret = gst_matroska_parse_parse_tracks (parse, &ebml);
2657 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2659 case GST_MATROSKA_ID_CLUSTER:
2660 if (G_UNLIKELY (!parse->tracks_parsed)) {
2661 GST_DEBUG_OBJECT (parse, "Cluster before Track");
2662 goto not_streamable;
2664 if (G_UNLIKELY (parse->common.state
2665 == GST_MATROSKA_READ_STATE_HEADER)) {
2666 parse->common.state = GST_MATROSKA_READ_STATE_DATA;
2667 parse->first_cluster_offset = parse->common.offset;
2668 GST_DEBUG_OBJECT (parse, "signaling no more pads");
2670 parse->cluster_time = GST_CLOCK_TIME_NONE;
2671 parse->cluster_offset = parse->common.offset;
2672 if (G_UNLIKELY (!parse->seek_first && parse->seek_block)) {
2673 GST_DEBUG_OBJECT (parse, "seek target block %" G_GUINT64_FORMAT
2674 " not found in Cluster, trying next Cluster's first block instead",
2676 parse->seek_block = 0;
2678 parse->seek_first = FALSE;
2679 /* record next cluster for recovery */
2680 if (read != G_MAXUINT64)
2681 parse->next_cluster_offset = parse->cluster_offset + read;
2682 /* eat cluster prefix */
2683 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2684 ret = gst_matroska_parse_output (parse, ebml.buf, TRUE);
2685 //gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2687 case GST_MATROSKA_ID_CLUSTERTIMECODE:
2691 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2692 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
2694 GST_DEBUG_OBJECT (parse, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
2695 parse->cluster_time = num;
2697 if (parse->common.element_index) {
2698 if (parse->common.element_index_writer_id == -1)
2699 gst_index_get_writer_id (parse->common.element_index,
2700 GST_OBJECT (parse), &parse->common.element_index_writer_id);
2701 GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
2702 G_GUINT64_FORMAT " for writer id %d",
2703 GST_TIME_ARGS (parse->cluster_time), parse->cluster_offset,
2704 parse->common.element_index_writer_id);
2705 gst_index_add_association (parse->common.element_index,
2706 parse->common.element_index_writer_id,
2707 GST_ASSOCIATION_FLAG_KEY_UNIT,
2708 GST_FORMAT_TIME, parse->cluster_time,
2709 GST_FORMAT_BYTES, parse->cluster_offset, NULL);
2712 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2715 case GST_MATROSKA_ID_BLOCKGROUP:
2716 if (!gst_matroska_parse_seek_block (parse))
2718 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2719 DEBUG_ELEMENT_START (parse, &ebml, "BlockGroup");
2720 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
2721 ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
2722 &ebml, parse->cluster_time, parse->cluster_offset, FALSE);
2724 DEBUG_ELEMENT_STOP (parse, &ebml, "BlockGroup", ret);
2725 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2727 case GST_MATROSKA_ID_SIMPLEBLOCK:
2728 if (!gst_matroska_parse_seek_block (parse))
2730 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2731 DEBUG_ELEMENT_START (parse, &ebml, "SimpleBlock");
2732 ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
2733 &ebml, parse->cluster_time, parse->cluster_offset, TRUE);
2734 DEBUG_ELEMENT_STOP (parse, &ebml, "SimpleBlock", ret);
2735 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2737 case GST_MATROSKA_ID_ATTACHMENTS:
2738 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2739 if (!parse->common.attachments_parsed) {
2740 ret = gst_matroska_read_common_parse_attachments (&parse->common,
2741 GST_ELEMENT_CAST (parse), &ebml);
2742 if (ret == GST_FLOW_OK)
2743 gst_matroska_parse_send_tags (parse);
2745 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2747 case GST_MATROSKA_ID_TAGS:
2748 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2749 ret = gst_matroska_read_common_parse_metadata (&parse->common,
2750 GST_ELEMENT_CAST (parse), &ebml);
2751 if (ret == GST_FLOW_OK)
2752 gst_matroska_parse_send_tags (parse);
2753 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2755 case GST_MATROSKA_ID_CHAPTERS:
2756 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2757 ret = gst_matroska_read_common_parse_chapters (&parse->common, &ebml);
2758 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2760 case GST_MATROSKA_ID_SEEKHEAD:
2761 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2762 ret = gst_matroska_parse_parse_contents (parse, &ebml);
2763 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2765 case GST_MATROSKA_ID_CUES:
2766 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2767 if (!parse->common.index_parsed) {
2768 ret = gst_matroska_read_common_parse_index (&parse->common, &ebml);
2769 /* only push based; delayed index building */
2770 if (ret == GST_FLOW_OK
2771 && parse->common.state == GST_MATROSKA_READ_STATE_SEEK) {
2774 GST_OBJECT_LOCK (parse);
2775 event = parse->seek_event;
2776 parse->seek_event = NULL;
2777 GST_OBJECT_UNLOCK (parse);
2780 /* unlikely to fail, since we managed to seek to this point */
2781 if (!gst_matroska_parse_handle_seek_event (parse, NULL, event))
2783 /* resume data handling, main thread clear to seek again */
2784 GST_OBJECT_LOCK (parse);
2785 parse->common.state = GST_MATROSKA_READ_STATE_DATA;
2786 GST_OBJECT_UNLOCK (parse);
2789 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2791 case GST_MATROSKA_ID_POSITION:
2792 case GST_MATROSKA_ID_PREVSIZE:
2793 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
2794 case GST_MATROSKA_ID_SILENTTRACKS:
2795 GST_DEBUG_OBJECT (parse,
2796 "Skipping Cluster subelement 0x%x - ignoring", id);
2800 GST_DEBUG_OBJECT (parse, "skipping Element 0x%x", id);
2801 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2802 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2808 if (ret == GST_FLOW_PARSE)
2812 gst_ebml_read_clear (&ebml);
2818 /* simply exit, maybe not enough data yet */
2819 /* no ebml to clear if read error */
2824 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2825 ("Failed to parse Element 0x%x", id));
2826 ret = GST_FLOW_ERROR;
2831 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2832 ("File layout does not permit streaming"));
2833 ret = GST_FLOW_ERROR;
2839 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2840 ("No Tracks element found"));
2841 ret = GST_FLOW_ERROR;
2847 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Invalid header"));
2848 ret = GST_FLOW_ERROR;
2853 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Failed to seek"));
2854 ret = GST_FLOW_ERROR;
2861 gst_matroska_parse_loop (GstPad * pad)
2863 GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
2869 /* If we have to close a segment, send a new segment to do this now */
2870 if (G_LIKELY (parse->common.state == GST_MATROSKA_READ_STATE_DATA)) {
2871 if (G_UNLIKELY (parse->close_segment)) {
2872 gst_matroska_parse_send_event (parse, parse->close_segment);
2873 parse->close_segment = NULL;
2875 if (G_UNLIKELY (parse->new_segment)) {
2876 gst_matroska_parse_send_event (parse, parse->new_segment);
2877 parse->new_segment = NULL;
2881 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2882 GST_ELEMENT_CAST (parse), &id, &length, &needed);
2883 if (ret == GST_FLOW_EOS)
2885 if (ret != GST_FLOW_OK) {
2886 if (gst_matroska_parse_check_parse_error (parse))
2892 GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2893 "size %" G_GUINT64_FORMAT ", needed %d", parse->offset, id,
2896 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2897 if (ret == GST_FLOW_EOS)
2899 if (ret != GST_FLOW_OK)
2902 /* check if we're at the end of a configured segment */
2903 if (G_LIKELY (parse->src->len)) {
2906 g_assert (parse->num_streams == parse->src->len);
2907 for (i = 0; i < parse->src->len; i++) {
2908 GstMatroskaTrackContext *context = g_ptr_array_index (parse->src, i);
2909 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
2910 GST_TIME_ARGS (context->pos));
2911 if (context->eos == FALSE)
2915 GST_INFO_OBJECT (parse, "All streams are EOS");
2921 if (G_UNLIKELY (parse->offset ==
2922 gst_matroska_read_common_get_length (&parse->common))) {
2923 GST_LOG_OBJECT (parse, "Reached end of stream");
2933 if (parse->segment.rate < 0.0) {
2934 ret = gst_matroska_parse_seek_to_previous_keyframe (parse);
2935 if (ret == GST_FLOW_OK)
2942 const gchar *reason = gst_flow_get_name (ret);
2943 gboolean push_eos = FALSE;
2945 GST_LOG_OBJECT (parse, "pausing task, reason %s", reason);
2946 parse->segment_running = FALSE;
2947 gst_pad_pause_task (parse->common.sinkpad);
2949 if (ret == GST_FLOW_EOS) {
2950 /* perform EOS logic */
2952 /* Close the segment, i.e. update segment stop with the duration
2953 * if no stop was set */
2954 if (GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) &&
2955 !GST_CLOCK_TIME_IS_VALID (parse->segment.stop)) {
2957 gst_event_new_new_segment_full (TRUE, parse->segment.rate,
2958 parse->segment.applied_rate, parse->segment.format,
2959 parse->segment.start,
2960 MAX (parse->last_stop_end, parse->segment.start),
2961 parse->segment.time);
2962 gst_matroska_parse_send_event (parse, event);
2965 if (parse->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2968 /* for segment playback we need to post when (in stream time)
2969 * we stopped, this is either stop (when set) or the duration. */
2970 if ((stop = parse->segment.stop) == -1)
2971 stop = parse->last_stop_end;
2973 GST_LOG_OBJECT (parse, "Sending segment done, at end of segment");
2974 gst_element_post_message (GST_ELEMENT (parse),
2975 gst_message_new_segment_done (GST_OBJECT (parse), GST_FORMAT_TIME,
2977 gst_matroska_parse_send_event (parse,
2978 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
2982 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
2983 /* for fatal errors we post an error message */
2984 GST_ELEMENT_FLOW_ERROR (parse, ret);
2988 /* send EOS, and prevent hanging if no streams yet */
2989 GST_LOG_OBJECT (parse, "Sending EOS, at end of stream");
2990 if (!gst_matroska_parse_send_event (parse, gst_event_new_eos ()) &&
2991 (ret == GST_FLOW_EOS)) {
2992 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
2993 (NULL), ("got eos but no streams (yet)"));
3002 * Create and push a flushing seek event upstream
3005 perform_seek_to_offset (GstMatroskaParse * parse, guint64 offset)
3010 GST_DEBUG_OBJECT (parse, "Seeking to %" G_GUINT64_FORMAT, offset);
3013 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
3014 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
3015 GST_SEEK_TYPE_NONE, -1);
3017 res = gst_pad_push_event (parse->common.sinkpad, event);
3019 /* newsegment event will update offset */
3024 * Forge empty default caps when all we know is the stream's EBML
3025 * type and whether it has video or not.
3027 * FIXME: Do something with video/x-matroska-3d if possible
3030 gst_matroska_parse_forge_caps (gboolean is_webm, gboolean has_video)
3036 caps = gst_caps_new_empty_simple ("video/webm");
3038 caps = gst_caps_new_empty_simple ("audio/webm");
3041 caps = gst_caps_new_empty_simple ("video/x-matroska");
3043 caps = gst_caps_new_empty_simple ("audio/x-matroska");
3048 static GstFlowReturn
3049 gst_matroska_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
3051 GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
3053 GstFlowReturn ret = GST_FLOW_OK;
3058 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
3059 GST_DEBUG_OBJECT (parse, "got DISCONT");
3060 gst_adapter_clear (parse->common.adapter);
3061 GST_OBJECT_LOCK (parse);
3062 gst_matroska_read_common_reset_streams (&parse->common,
3063 GST_CLOCK_TIME_NONE, FALSE);
3064 GST_OBJECT_UNLOCK (parse);
3067 gst_adapter_push (parse->common.adapter, buffer);
3071 available = gst_adapter_available (parse->common.adapter);
3073 ret = gst_matroska_read_common_peek_id_length_push (&parse->common,
3074 GST_ELEMENT_CAST (parse), &id, &length, &needed);
3075 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
3076 if (parse->common.ebml_segment_length != G_MAXUINT64
3077 && parse->common.offset >=
3078 parse->common.ebml_segment_start + parse->common.ebml_segment_length) {
3079 return GST_FLOW_EOS;
3082 * parsing error: we need to flush a byte from the adapter if the id is
3083 * not a cluster and so on until we found a new cluser or the
3084 * INVALID_DATA_THRESHOLD is exceeded, we reuse gst_matroska_parse_parse_id
3085 * setting the state to GST_MATROSKA_READ_STATE_SCANNING so the bytes
3086 * are skipped until a new cluster is found
3088 gint64 bytes_scanned;
3089 if (parse->common.start_resync_offset == -1) {
3090 parse->common.start_resync_offset = parse->common.offset;
3091 parse->common.state_to_restore = parse->common.state;
3093 bytes_scanned = parse->common.offset - parse->common.start_resync_offset;
3094 if (bytes_scanned <= INVALID_DATA_THRESHOLD) {
3095 GST_WARNING_OBJECT (parse,
3096 "parse error, looking for next cluster, actual offset %"
3097 G_GUINT64_FORMAT ", start resync offset %" G_GUINT64_FORMAT,
3098 parse->common.offset, parse->common.start_resync_offset);
3099 parse->common.state = GST_MATROSKA_READ_STATE_SCANNING;
3102 GST_WARNING_OBJECT (parse,
3103 "unrecoverable parse error, next cluster not found and threshold "
3104 "exceeded, bytes scanned %" G_GINT64_FORMAT, bytes_scanned);
3110 GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
3111 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
3112 parse->common.offset, id, length, needed, available);
3114 if (needed > available)
3117 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
3118 if (ret == GST_FLOW_EOS) {
3119 /* need more data */
3121 } else if (ret != GST_FLOW_OK) {
3128 gst_matroska_parse_handle_sink_event (GstPad * pad, GstObject * parent,
3131 gboolean res = TRUE;
3132 GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
3134 GST_DEBUG_OBJECT (parse,
3135 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
3137 switch (GST_EVENT_TYPE (event)) {
3138 case GST_EVENT_SEGMENT:
3140 const GstSegment *segment;
3142 /* some debug output */
3143 gst_event_parse_segment (event, &segment);
3144 GST_DEBUG_OBJECT (parse,
3145 "received format %d newsegment %" GST_SEGMENT_FORMAT,
3146 segment->format, segment);
3148 if (parse->common.state < GST_MATROSKA_READ_STATE_DATA) {
3149 GST_DEBUG_OBJECT (parse, "still starting");
3153 /* we only expect a BYTE segment, e.g. following a seek */
3154 if (segment->format != GST_FORMAT_BYTES) {
3155 GST_DEBUG_OBJECT (parse, "unsupported segment format, ignoring");
3159 GST_DEBUG_OBJECT (parse, "clearing segment state");
3160 /* clear current segment leftover */
3161 gst_adapter_clear (parse->common.adapter);
3162 /* and some streaming setup */
3163 parse->common.offset = segment->start;
3164 /* do not know where we are;
3165 * need to come across a cluster and generate newsegment */
3166 parse->common.segment.position = GST_CLOCK_TIME_NONE;
3167 parse->cluster_time = GST_CLOCK_TIME_NONE;
3168 parse->cluster_offset = 0;
3169 parse->need_newsegment = TRUE;
3170 /* but keep some of the upstream segment */
3171 parse->common.segment.rate = segment->rate;
3173 /* chain will send initial newsegment after pads have been added,
3174 * or otherwise come up with one */
3175 GST_DEBUG_OBJECT (parse, "eating event");
3176 gst_event_unref (event);
3182 if (parse->common.state != GST_MATROSKA_READ_STATE_DATA
3183 && parse->common.state != GST_MATROSKA_READ_STATE_SCANNING) {
3184 gst_event_unref (event);
3185 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3186 (NULL), ("got eos and didn't receive a complete header object"));
3187 } else if (parse->common.num_streams == 0) {
3188 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3189 (NULL), ("got eos but no streams (yet)"));
3191 gst_matroska_parse_send_event (parse, event);
3195 case GST_EVENT_FLUSH_STOP:
3197 gst_adapter_clear (parse->common.adapter);
3198 GST_OBJECT_LOCK (parse);
3199 gst_matroska_read_common_reset_streams (&parse->common,
3200 GST_CLOCK_TIME_NONE, TRUE);
3201 GST_OBJECT_UNLOCK (parse);
3202 parse->common.segment.position = GST_CLOCK_TIME_NONE;
3203 parse->cluster_time = GST_CLOCK_TIME_NONE;
3204 parse->cluster_offset = 0;
3208 res = gst_pad_event_default (pad, parent, event);
3217 gst_matroska_parse_set_index (GstElement * element, GstIndex * index)
3219 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3221 GST_OBJECT_LOCK (parse);
3222 if (parse->common.element_index)
3223 gst_object_unref (parse->common.element_index);
3224 parse->common.element_index = index ? gst_object_ref (index) : NULL;
3225 GST_OBJECT_UNLOCK (parse);
3226 GST_DEBUG_OBJECT (parse, "Set index %" GST_PTR_FORMAT,
3227 parse->common.element_index);
3231 gst_matroska_parse_get_index (GstElement * element)
3233 GstIndex *result = NULL;
3234 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3236 GST_OBJECT_LOCK (parse);
3237 if (parse->common.element_index)
3238 result = gst_object_ref (parse->common.element_index);
3239 GST_OBJECT_UNLOCK (parse);
3241 GST_DEBUG_OBJECT (parse, "Returning index %" GST_PTR_FORMAT, result);
3247 static GstStateChangeReturn
3248 gst_matroska_parse_change_state (GstElement * element,
3249 GstStateChange transition)
3251 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3252 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
3254 /* handle upwards state changes here */
3255 switch (transition) {
3260 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
3262 /* handle downwards state changes */
3263 switch (transition) {
3264 case GST_STATE_CHANGE_PAUSED_TO_READY:
3265 gst_matroska_parse_reset (GST_ELEMENT (parse));