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))
85 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
88 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
89 "video/x-matroska-3d; audio/webm; video/webm")
92 static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
95 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
96 "video/x-matroska-3d; audio/webm; video/webm")
99 static GstFlowReturn gst_matroska_parse_parse_id (GstMatroskaParse * parse,
100 guint32 id, guint64 length, guint needed);
102 /* element functions */
103 //static void gst_matroska_parse_loop (GstPad * pad);
105 static gboolean gst_matroska_parse_element_send_event (GstElement * element,
107 static gboolean gst_matroska_parse_element_query (GstElement * element,
111 static gboolean gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
112 GstPad * pad, GstEvent * event);
113 static gboolean gst_matroska_parse_handle_src_event (GstPad * pad,
114 GstObject * parent, GstEvent * event);
115 static gboolean gst_matroska_parse_handle_src_query (GstPad * pad,
116 GstObject * parent, GstQuery * query);
118 static gboolean gst_matroska_parse_handle_sink_event (GstPad * pad,
119 GstObject * parent, GstEvent * event);
120 static GstFlowReturn gst_matroska_parse_chain (GstPad * pad,
121 GstObject * parent, GstBuffer * buffer);
123 static GstStateChangeReturn
124 gst_matroska_parse_change_state (GstElement * element,
125 GstStateChange transition);
128 gst_matroska_parse_set_index (GstElement * element, GstIndex * index);
129 static GstIndex *gst_matroska_parse_get_index (GstElement * element);
133 static void gst_matroska_parse_reset (GstElement * element);
134 static gboolean perform_seek_to_offset (GstMatroskaParse * parse,
136 static GstCaps *gst_matroska_parse_forge_caps (gboolean is_webm,
139 GType gst_matroska_parse_get_type (void);
140 #define parent_class gst_matroska_parse_parent_class
141 G_DEFINE_TYPE (GstMatroskaParse, gst_matroska_parse, GST_TYPE_ELEMENT);
144 gst_matroska_parse_finalize (GObject * object)
146 GstMatroskaParse *parse = GST_MATROSKA_PARSE (object);
148 gst_matroska_read_common_finalize (&parse->common);
149 G_OBJECT_CLASS (parent_class)->finalize (object);
153 gst_matroska_parse_class_init (GstMatroskaParseClass * klass)
155 GObjectClass *gobject_class = (GObjectClass *) klass;
156 GstElementClass *gstelement_class = (GstElementClass *) klass;
158 GST_DEBUG_CATEGORY_INIT (matroskaparse_debug, "matroskaparse", 0,
161 gobject_class->finalize = gst_matroska_parse_finalize;
163 gstelement_class->change_state =
164 GST_DEBUG_FUNCPTR (gst_matroska_parse_change_state);
165 gstelement_class->send_event =
166 GST_DEBUG_FUNCPTR (gst_matroska_parse_element_send_event);
167 gstelement_class->query =
168 GST_DEBUG_FUNCPTR (gst_matroska_parse_element_query);
171 gstelement_class->set_index =
172 GST_DEBUG_FUNCPTR (gst_matroska_parse_set_index);
173 gstelement_class->get_index =
174 GST_DEBUG_FUNCPTR (gst_matroska_parse_get_index);
177 gst_element_class_add_static_pad_template (gstelement_class, &src_templ);
178 gst_element_class_add_static_pad_template (gstelement_class, &sink_templ);
180 gst_element_class_set_static_metadata (gstelement_class,
181 "Matroska parser", "Codec/Parser",
182 "Parses Matroska/WebM streams into video/audio/subtitles",
183 "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
187 gst_matroska_parse_init (GstMatroskaParse * parse)
189 parse->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
191 gst_pad_set_chain_function (parse->common.sinkpad,
192 GST_DEBUG_FUNCPTR (gst_matroska_parse_chain));
193 gst_pad_set_event_function (parse->common.sinkpad,
194 GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_sink_event));
195 gst_element_add_pad (GST_ELEMENT (parse), parse->common.sinkpad);
197 parse->srcpad = gst_pad_new_from_static_template (&src_templ, "src");
198 gst_pad_set_event_function (parse->srcpad,
199 GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_event));
200 gst_pad_set_query_function (parse->srcpad,
201 GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_query));
202 gst_pad_use_fixed_caps (parse->srcpad);
204 gst_element_add_pad (GST_ELEMENT (parse), parse->srcpad);
206 /* init defaults for common read context */
207 gst_matroska_read_common_init (&parse->common);
209 GST_OBJECT_FLAG_SET (parse, GST_ELEMENT_FLAG_INDEXABLE);
212 gst_matroska_parse_reset (GST_ELEMENT (parse));
216 gst_matroska_parse_reset (GstElement * element)
218 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
220 GST_DEBUG_OBJECT (parse, "Resetting state");
222 gst_matroska_read_common_reset (GST_ELEMENT (parse), &parse->common);
224 parse->num_a_streams = 0;
225 parse->num_t_streams = 0;
226 parse->num_v_streams = 0;
229 parse->tracks_parsed = FALSE;
231 g_list_foreach (parse->seek_parsed,
232 (GFunc) gst_matroska_read_common_free_parsed_el, NULL);
233 g_list_free (parse->seek_parsed);
234 parse->seek_parsed = NULL;
236 parse->last_stop_end = GST_CLOCK_TIME_NONE;
237 parse->seek_block = 0;
238 parse->cluster_time = GST_CLOCK_TIME_NONE;
239 parse->cluster_offset = 0;
240 parse->next_cluster_offset = 0;
241 parse->index_offset = 0;
242 parse->seekable = FALSE;
243 parse->need_newsegment = TRUE;
244 parse->building_index = FALSE;
245 if (parse->seek_event) {
246 gst_event_unref (parse->seek_event);
247 parse->seek_event = NULL;
250 parse->seek_index = NULL;
251 parse->seek_entry = 0;
253 if (parse->close_segment) {
254 gst_event_unref (parse->close_segment);
255 parse->close_segment = NULL;
258 if (parse->new_segment) {
259 gst_event_unref (parse->new_segment);
260 parse->new_segment = NULL;
263 if (parse->streamheader != NULL) {
264 gst_buffer_unref (parse->streamheader);
265 parse->streamheader = NULL;
270 gst_matroska_parse_add_stream (GstMatroskaParse * parse, GstEbmlRead * ebml)
272 GstMatroskaTrackContext *context;
276 DEBUG_ELEMENT_START (parse, ebml, "TrackEntry");
278 /* start with the master */
279 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
280 DEBUG_ELEMENT_STOP (parse, ebml, "TrackEntry", ret);
284 /* allocate generic... if we know the type, we'll g_renew()
285 * with the precise type */
286 context = g_new0 (GstMatroskaTrackContext, 1);
287 g_ptr_array_add (parse->common.src, context);
288 context->index = parse->common.num_streams;
289 context->index_writer_id = -1;
290 context->type = 0; /* no type yet */
291 context->default_duration = 0;
293 context->set_discont = TRUE;
294 context->timecodescale = 1.0;
296 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
297 GST_MATROSKA_TRACK_LACING;
298 context->to_offset = G_MAXINT64;
299 context->alignment = 1;
300 parse->common.num_streams++;
301 g_assert (parse->common.src->len == parse->common.num_streams);
303 GST_DEBUG_OBJECT (parse, "Stream number %d", context->index);
305 /* try reading the trackentry headers */
306 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
307 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
311 /* track number (unique stream ID) */
312 case GST_MATROSKA_ID_TRACKNUMBER:{
315 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
319 GST_ERROR_OBJECT (parse, "Invalid TrackNumber 0");
320 ret = GST_FLOW_ERROR;
322 } else if (!gst_matroska_read_common_tracknumber_unique (&parse->common,
324 GST_ERROR_OBJECT (parse, "TrackNumber %" G_GUINT64_FORMAT
325 " is not unique", num);
326 ret = GST_FLOW_ERROR;
330 GST_DEBUG_OBJECT (parse, "TrackNumber: %" G_GUINT64_FORMAT, num);
334 /* track UID (unique identifier) */
335 case GST_MATROSKA_ID_TRACKUID:{
338 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
342 GST_ERROR_OBJECT (parse, "Invalid TrackUID 0");
343 ret = GST_FLOW_ERROR;
347 GST_DEBUG_OBJECT (parse, "TrackUID: %" G_GUINT64_FORMAT, num);
352 /* track type (video, audio, combined, subtitle, etc.) */
353 case GST_MATROSKA_ID_TRACKTYPE:{
356 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
360 if (context->type != 0 && context->type != track_type) {
361 GST_WARNING_OBJECT (parse,
362 "More than one tracktype defined in a TrackEntry - skipping");
364 } else if (track_type < 1 || track_type > 254) {
365 GST_WARNING_OBJECT (parse, "Invalid TrackType %" G_GUINT64_FORMAT,
370 GST_DEBUG_OBJECT (parse, "TrackType: %" G_GUINT64_FORMAT, track_type);
372 /* ok, so we're actually going to reallocate this thing */
373 switch (track_type) {
374 case GST_MATROSKA_TRACK_TYPE_VIDEO:
375 gst_matroska_track_init_video_context (&context);
376 parse->common.has_video = TRUE;
378 case GST_MATROSKA_TRACK_TYPE_AUDIO:
379 gst_matroska_track_init_audio_context (&context);
381 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
382 gst_matroska_track_init_subtitle_context (&context);
384 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
385 case GST_MATROSKA_TRACK_TYPE_LOGO:
386 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
387 case GST_MATROSKA_TRACK_TYPE_CONTROL:
389 GST_WARNING_OBJECT (parse,
390 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
395 g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
400 /* tracktype specific stuff for video */
401 case GST_MATROSKA_ID_TRACKVIDEO:{
402 GstMatroskaTrackVideoContext *videocontext;
404 DEBUG_ELEMENT_START (parse, ebml, "TrackVideo");
406 if (!gst_matroska_track_init_video_context (&context)) {
407 GST_WARNING_OBJECT (parse,
408 "TrackVideo element in non-video track - ignoring track");
409 ret = GST_FLOW_ERROR;
411 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
414 videocontext = (GstMatroskaTrackVideoContext *) context;
415 g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
418 while (ret == GST_FLOW_OK &&
419 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
420 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
424 /* Should be one level up but some broken muxers write it here. */
425 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
428 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
432 GST_WARNING_OBJECT (parse, "Invalid TrackDefaultDuration 0");
436 GST_DEBUG_OBJECT (parse,
437 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
438 context->default_duration = num;
442 /* video framerate */
443 /* NOTE: This one is here only for backward compatibility.
444 * Use _TRACKDEFAULDURATION one level up. */
445 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
448 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
452 GST_WARNING_OBJECT (parse, "Invalid TrackVideoFPS %lf", num);
456 GST_DEBUG_OBJECT (parse, "TrackVideoFrameRate: %lf", num);
457 if (context->default_duration == 0)
458 context->default_duration =
459 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
460 videocontext->default_fps = num;
464 /* width of the size to display the video at */
465 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
468 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
472 GST_WARNING_OBJECT (parse, "Invalid TrackVideoDisplayWidth 0");
476 GST_DEBUG_OBJECT (parse,
477 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
478 videocontext->display_width = num;
482 /* height of the size to display the video at */
483 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
486 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
490 GST_WARNING_OBJECT (parse, "Invalid TrackVideoDisplayHeight 0");
494 GST_DEBUG_OBJECT (parse,
495 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
496 videocontext->display_height = num;
500 /* width of the video in the file */
501 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
504 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
508 GST_WARNING_OBJECT (parse, "Invalid TrackVideoPixelWidth 0");
512 GST_DEBUG_OBJECT (parse,
513 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
514 videocontext->pixel_width = num;
518 /* height of the video in the file */
519 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
522 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
526 GST_WARNING_OBJECT (parse, "Invalid TrackVideoPixelHeight 0");
530 GST_DEBUG_OBJECT (parse,
531 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
532 videocontext->pixel_height = num;
536 /* whether the video is interlaced */
537 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
540 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
544 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
546 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
547 GST_DEBUG_OBJECT (parse, "TrackVideoInterlaced: %d",
548 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
553 /* aspect ratio behaviour */
554 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
557 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
560 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
561 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
562 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
563 GST_WARNING_OBJECT (parse,
564 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
567 GST_DEBUG_OBJECT (parse,
568 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
569 videocontext->asr_mode = num;
573 /* colourspace (only matters for raw video) fourcc */
574 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
579 gst_ebml_read_binary (ebml, &id, &data,
580 &datalen)) != GST_FLOW_OK)
585 GST_WARNING_OBJECT (parse,
586 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
591 memcpy (&videocontext->fourcc, data, 4);
592 GST_DEBUG_OBJECT (parse,
593 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
594 GST_FOURCC_ARGS (videocontext->fourcc));
600 GST_WARNING_OBJECT (parse,
601 "Unknown TrackVideo subelement 0x%x - ignoring", id);
603 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
604 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
605 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
606 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
607 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
608 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
609 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
610 ret = gst_ebml_read_skip (ebml);
615 DEBUG_ELEMENT_STOP (parse, ebml, "TrackVideo", ret);
619 /* tracktype specific stuff for audio */
620 case GST_MATROSKA_ID_TRACKAUDIO:{
621 GstMatroskaTrackAudioContext *audiocontext;
623 DEBUG_ELEMENT_START (parse, ebml, "TrackAudio");
625 if (!gst_matroska_track_init_audio_context (&context)) {
626 GST_WARNING_OBJECT (parse,
627 "TrackAudio element in non-audio track - ignoring track");
628 ret = GST_FLOW_ERROR;
632 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
635 audiocontext = (GstMatroskaTrackAudioContext *) context;
636 g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
639 while (ret == GST_FLOW_OK &&
640 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
641 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
646 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
649 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
654 GST_WARNING_OBJECT (parse,
655 "Invalid TrackAudioSamplingFrequency %lf", num);
659 GST_DEBUG_OBJECT (parse, "TrackAudioSamplingFrequency: %lf", num);
660 audiocontext->samplerate = num;
665 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
668 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
672 GST_WARNING_OBJECT (parse, "Invalid TrackAudioBitDepth 0");
676 GST_DEBUG_OBJECT (parse, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
678 audiocontext->bitdepth = num;
683 case GST_MATROSKA_ID_AUDIOCHANNELS:{
686 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
690 GST_WARNING_OBJECT (parse, "Invalid TrackAudioChannels 0");
694 GST_DEBUG_OBJECT (parse, "TrackAudioChannels: %" G_GUINT64_FORMAT,
696 audiocontext->channels = num;
701 GST_WARNING_OBJECT (parse,
702 "Unknown TrackAudio subelement 0x%x - ignoring", id);
704 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
705 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
706 ret = gst_ebml_read_skip (ebml);
711 DEBUG_ELEMENT_STOP (parse, ebml, "TrackAudio", ret);
716 /* codec identifier */
717 case GST_MATROSKA_ID_CODECID:{
720 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
723 GST_DEBUG_OBJECT (parse, "CodecID: %s", GST_STR_NULL (text));
724 context->codec_id = text;
728 /* codec private data */
729 case GST_MATROSKA_ID_CODECPRIVATE:{
734 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
737 context->codec_priv = data;
738 context->codec_priv_size = size;
740 GST_DEBUG_OBJECT (parse, "CodecPrivate of size %" G_GUINT64_FORMAT,
745 /* name of the codec */
746 case GST_MATROSKA_ID_CODECNAME:{
749 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
752 GST_DEBUG_OBJECT (parse, "CodecName: %s", GST_STR_NULL (text));
753 context->codec_name = text;
757 /* name of this track */
758 case GST_MATROSKA_ID_TRACKNAME:{
761 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
764 context->name = text;
765 GST_DEBUG_OBJECT (parse, "TrackName: %s", GST_STR_NULL (text));
769 /* language (matters for audio/subtitles, mostly) */
770 case GST_MATROSKA_ID_TRACKLANGUAGE:{
773 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
777 context->language = text;
780 if (strlen (context->language) >= 4 && context->language[3] == '-')
781 context->language[3] = '\0';
783 GST_DEBUG_OBJECT (parse, "TrackLanguage: %s",
784 GST_STR_NULL (context->language));
788 /* whether this is actually used */
789 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
792 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
796 context->flags |= GST_MATROSKA_TRACK_ENABLED;
798 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
800 GST_DEBUG_OBJECT (parse, "TrackEnabled: %d",
801 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
805 /* whether it's the default for this track type */
806 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
809 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
813 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
815 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
817 GST_DEBUG_OBJECT (parse, "TrackDefault: %d",
818 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
822 /* whether the track must be used during playback */
823 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
826 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
830 context->flags |= GST_MATROSKA_TRACK_FORCED;
832 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
834 GST_DEBUG_OBJECT (parse, "TrackForced: %d",
835 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
839 /* lacing (like MPEG, where blocks don't end/start on frame
841 case GST_MATROSKA_ID_TRACKFLAGLACING:{
844 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
848 context->flags |= GST_MATROSKA_TRACK_LACING;
850 context->flags &= ~GST_MATROSKA_TRACK_LACING;
852 GST_DEBUG_OBJECT (parse, "TrackLacing: %d",
853 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
857 /* default length (in time) of one data block in this track */
858 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
861 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
866 GST_WARNING_OBJECT (parse, "Invalid TrackDefaultDuration 0");
870 GST_DEBUG_OBJECT (parse, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
872 context->default_duration = num;
876 case GST_MATROSKA_ID_CONTENTENCODINGS:{
877 ret = gst_matroska_read_common_read_track_encodings (&parse->common,
882 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
885 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
889 GST_WARNING_OBJECT (parse, "Invalid TrackTimeCodeScale %lf", num);
893 GST_DEBUG_OBJECT (parse, "TrackTimeCodeScale: %lf", num);
894 context->timecodescale = num;
899 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
902 /* we ignore these because they're nothing useful (i.e. crap)
903 * or simply not implemented yet. */
904 case GST_MATROSKA_ID_TRACKMINCACHE:
905 case GST_MATROSKA_ID_TRACKMAXCACHE:
906 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
907 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
908 case GST_MATROSKA_ID_TRACKOVERLAY:
909 case GST_MATROSKA_ID_TRACKTRANSLATE:
910 case GST_MATROSKA_ID_TRACKOFFSET:
911 case GST_MATROSKA_ID_CODECSETTINGS:
912 case GST_MATROSKA_ID_CODECINFOURL:
913 case GST_MATROSKA_ID_CODECDOWNLOADURL:
914 case GST_MATROSKA_ID_CODECDECODEALL:
915 ret = gst_ebml_read_skip (ebml);
920 DEBUG_ELEMENT_STOP (parse, ebml, "TrackEntry", ret);
922 /* Decode codec private data if necessary */
923 if (context->encodings && context->encodings->len > 0 && context->codec_priv
924 && context->codec_priv_size > 0) {
925 if (!gst_matroska_decode_data (context->encodings,
926 &context->codec_priv, &context->codec_priv_size,
927 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
928 GST_WARNING_OBJECT (parse, "Decoding codec private data failed");
929 ret = GST_FLOW_ERROR;
933 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
934 && ret != GST_FLOW_EOS)) {
935 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
936 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
938 parse->common.num_streams--;
939 g_ptr_array_remove_index (parse->common.src, parse->common.num_streams);
940 g_assert (parse->common.src->len == parse->common.num_streams);
941 gst_matroska_track_free (context);
946 if ((context->language == NULL || *context->language == '\0') &&
947 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
948 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
949 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
950 context->language = g_strdup ("eng");
959 gst_matroska_parse_query (GstMatroskaParse * parse, GstPad * pad,
962 gboolean res = FALSE;
963 GstMatroskaTrackContext *context = NULL;
966 context = gst_pad_get_element_private (pad);
969 switch (GST_QUERY_TYPE (query)) {
970 case GST_QUERY_POSITION:
974 gst_query_parse_position (query, &format, NULL);
976 if (format == GST_FORMAT_TIME) {
977 GST_OBJECT_LOCK (parse);
979 gst_query_set_position (query, GST_FORMAT_TIME, context->pos);
981 gst_query_set_position (query, GST_FORMAT_TIME,
982 parse->common.segment.position);
983 GST_OBJECT_UNLOCK (parse);
984 } else if (format == GST_FORMAT_DEFAULT && context
985 && context->default_duration) {
986 GST_OBJECT_LOCK (parse);
987 gst_query_set_position (query, GST_FORMAT_DEFAULT,
988 context->pos / context->default_duration);
989 GST_OBJECT_UNLOCK (parse);
991 GST_DEBUG_OBJECT (parse,
992 "only position query in TIME and DEFAULT format is supported");
998 case GST_QUERY_DURATION:
1002 gst_query_parse_duration (query, &format, NULL);
1004 if (format == GST_FORMAT_TIME) {
1005 GST_OBJECT_LOCK (parse);
1006 gst_query_set_duration (query, GST_FORMAT_TIME,
1007 parse->common.segment.duration);
1008 GST_OBJECT_UNLOCK (parse);
1009 } else if (format == GST_FORMAT_DEFAULT && context
1010 && context->default_duration) {
1011 GST_OBJECT_LOCK (parse);
1012 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1013 parse->common.segment.duration / context->default_duration);
1014 GST_OBJECT_UNLOCK (parse);
1016 GST_DEBUG_OBJECT (parse,
1017 "only duration query in TIME and DEFAULT format is supported");
1024 case GST_QUERY_SEEKING:
1028 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1029 if (fmt == GST_FORMAT_TIME) {
1032 /* assuming we'll be able to get an index ... */
1033 seekable = parse->seekable;
1035 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1036 0, parse->common.segment.duration);
1043 res = gst_pad_query_default (pad, (GstObject *) parse, query);
1051 gst_matroska_parse_element_query (GstElement * element, GstQuery * query)
1053 return gst_matroska_parse_query (GST_MATROSKA_PARSE (element), NULL, query);
1057 gst_matroska_parse_handle_src_query (GstPad * pad, GstObject * parent,
1061 GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
1063 ret = gst_matroska_parse_query (parse, pad, query);
1069 gst_matroska_parse_send_tags (GstMatroskaParse * parse)
1071 if (G_UNLIKELY (parse->common.global_tags_changed)) {
1072 GstEvent *tag_event;
1073 gst_tag_list_add (parse->common.global_tags, GST_TAG_MERGE_REPLACE,
1074 GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
1075 GST_DEBUG_OBJECT (parse, "Sending global_tags %p : %" GST_PTR_FORMAT,
1076 parse->common.global_tags, parse->common.global_tags);
1078 /* Send a copy as we want to keep our local ref writable to add more tags
1079 * if any are found */
1081 gst_event_new_tag (gst_tag_list_copy (parse->common.global_tags));
1083 gst_pad_push_event (parse->srcpad, tag_event);
1085 parse->common.global_tags_changed = FALSE;
1089 /* returns FALSE if there are no pads to deliver event to,
1090 * otherwise TRUE (whatever the outcome of event sending),
1091 * takes ownership of the passed event! */
1093 gst_matroska_parse_send_event (GstMatroskaParse * parse, GstEvent * event)
1095 gboolean ret = FALSE;
1097 g_return_val_if_fail (event != NULL, FALSE);
1099 GST_DEBUG_OBJECT (parse, "Sending event of type %s to all source pads",
1100 GST_EVENT_TYPE_NAME (event));
1102 gst_pad_push_event (parse->srcpad, event);
1108 gst_matroska_parse_element_send_event (GstElement * element, GstEvent * event)
1110 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
1113 g_return_val_if_fail (event != NULL, FALSE);
1115 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1116 res = gst_matroska_parse_handle_seek_event (parse, NULL, event);
1118 GST_WARNING_OBJECT (parse, "Unhandled event of type %s",
1119 GST_EVENT_TYPE_NAME (event));
1122 gst_event_unref (event);
1127 /* searches for a cluster start from @pos,
1128 * return GST_FLOW_OK and cluster position in @pos if found */
1129 static GstFlowReturn
1130 gst_matroska_parse_search_cluster (GstMatroskaParse * parse, gint64 * pos)
1132 gint64 newpos = *pos;
1134 GstFlowReturn ret = GST_FLOW_OK;
1135 const guint chunk = 64 * 1024;
1144 orig_offset = parse->common.offset;
1146 /* read in at newpos and scan for ebml cluster id */
1148 GstByteReader reader;
1152 ret = gst_pad_pull_range (parse->common.sinkpad, newpos, chunk, &buf);
1153 if (ret != GST_FLOW_OK)
1155 GST_DEBUG_OBJECT (parse,
1156 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1157 gst_buffer_get_size (buf), newpos);
1158 gst_buffer_map (buf, &map, GST_MAP_READ);
1161 gst_byte_reader_init (&reader, data, size);
1164 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1165 GST_MATROSKA_ID_CLUSTER, cluster_pos, size - cluster_pos);
1166 if (cluster_pos >= 0) {
1167 newpos += cluster_pos;
1168 GST_DEBUG_OBJECT (parse,
1169 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1170 /* extra checks whether we really sync'ed to a cluster:
1171 * - either it is the first and only cluster
1172 * - either there is a cluster after this one
1173 * - either cluster length is undefined
1175 /* ok if first cluster (there may not a subsequent one) */
1176 if (newpos == parse->first_cluster_offset) {
1177 GST_DEBUG_OBJECT (parse, "cluster is first cluster -> OK");
1180 parse->common.offset = newpos;
1181 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1182 GST_ELEMENT_CAST (parse), &id, &length, &needed);
1183 if (ret != GST_FLOW_OK)
1185 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1186 GST_DEBUG_OBJECT (parse, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1188 /* ok if undefined length or first cluster */
1189 if (length == G_MAXUINT64) {
1190 GST_DEBUG_OBJECT (parse, "cluster has undefined length -> OK");
1194 parse->common.offset += length + needed;
1195 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1196 GST_ELEMENT_CAST (parse), &id, &length, &needed);
1197 if (ret != GST_FLOW_OK)
1199 GST_DEBUG_OBJECT (parse, "next element is %scluster",
1200 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1201 if (id == GST_MATROSKA_ID_CLUSTER)
1203 /* not ok, resume */
1206 /* partial cluster id may have been in tail of buffer */
1207 newpos += MAX (size, 4) - 3;
1208 gst_buffer_unmap (buf, &map);
1209 gst_buffer_unref (buf);
1215 gst_buffer_unmap (buf, &map);
1216 gst_buffer_unref (buf);
1220 parse->common.offset = orig_offset;
1227 gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
1228 GstPad * pad, GstEvent * event)
1230 GstMatroskaIndex *entry = NULL;
1232 GstSeekType cur_type, stop_type;
1236 GstMatroskaTrackContext *track = NULL;
1237 GstSegment seeksegment = { 0, };
1239 GstSearchMode snap_dir;
1242 track = gst_pad_get_element_private (pad);
1244 track = gst_matroska_read_common_get_seek_track (&parse->common, track);
1246 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1249 /* we can only seek on time */
1250 if (format != GST_FORMAT_TIME) {
1251 GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1255 /* copy segment, we need this because we still need the old
1256 * segment when we close the current segment. */
1257 memcpy (&seeksegment, &parse->common.segment, sizeof (GstSegment));
1260 GST_DEBUG_OBJECT (parse, "configuring seek");
1261 gst_segment_do_seek (&seeksegment, rate, format, flags,
1262 cur_type, cur, stop_type, stop, &update);
1265 GST_DEBUG_OBJECT (parse, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1267 if (seeksegment.rate < 0)
1268 snap_dir = GST_SEARCH_MODE_AFTER;
1270 snap_dir = GST_SEARCH_MODE_BEFORE;
1272 /* check sanity before we start flushing and all that */
1273 GST_OBJECT_LOCK (parse);
1274 if ((entry = gst_matroska_read_common_do_index_seek (&parse->common, track,
1275 seeksegment.position, &parse->seek_index, &parse->seek_entry,
1276 snap_dir)) == NULL) {
1277 /* pull mode without index can scan later on */
1278 GST_DEBUG_OBJECT (parse, "No matching seek entry in index");
1279 GST_OBJECT_UNLOCK (parse);
1282 GST_DEBUG_OBJECT (parse, "Seek position looks sane");
1283 GST_OBJECT_UNLOCK (parse);
1285 /* need to seek to cluster start to pick up cluster time */
1286 /* upstream takes care of flushing and all that
1287 * ... and newsegment event handling takes care of the rest */
1288 return perform_seek_to_offset (parse, entry->pos
1289 + parse->common.ebml_segment_start);
1293 * Handle whether we can perform the seek event or if we have to let the chain
1294 * function handle seeks to build the seek indexes first.
1297 gst_matroska_parse_handle_seek_push (GstMatroskaParse * parse, GstPad * pad,
1301 GstSeekType cur_type, stop_type;
1306 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1311 /* we can only seek on time */
1312 if (format != GST_FORMAT_TIME) {
1313 GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1317 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
1318 GST_DEBUG_OBJECT (parse, "Seek end-time not supported in streaming mode");
1322 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
1323 GST_DEBUG_OBJECT (parse,
1324 "Non-flushing seek not supported in streaming mode");
1328 if (flags & GST_SEEK_FLAG_SEGMENT) {
1329 GST_DEBUG_OBJECT (parse, "Segment seek not supported in streaming mode");
1333 /* check for having parsed index already */
1334 if (!parse->common.index_parsed) {
1335 gboolean building_index;
1338 if (!parse->index_offset) {
1339 GST_DEBUG_OBJECT (parse, "no index (location); no seek in push mode");
1343 GST_OBJECT_LOCK (parse);
1344 /* handle the seek event in the chain function */
1345 parse->common.state = GST_MATROSKA_READ_STATE_SEEK;
1346 /* no more seek can be issued until state reset to _DATA */
1348 /* copy the event */
1349 if (parse->seek_event)
1350 gst_event_unref (parse->seek_event);
1351 parse->seek_event = gst_event_ref (event);
1353 /* set the building_index flag so that only one thread can setup the
1354 * structures for index seeking. */
1355 building_index = parse->building_index;
1356 if (!building_index) {
1357 parse->building_index = TRUE;
1358 offset = parse->index_offset;
1360 GST_OBJECT_UNLOCK (parse);
1362 if (!building_index) {
1363 /* seek to the first subindex or legacy index */
1364 GST_INFO_OBJECT (parse, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
1365 return perform_seek_to_offset (parse, offset);
1368 /* well, we are handling it already */
1372 /* delegate to tweaked regular seek */
1373 return gst_matroska_parse_handle_seek_event (parse, pad, event);
1377 gst_matroska_parse_handle_src_event (GstPad * pad, GstObject * parent,
1380 GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
1381 gboolean res = TRUE;
1383 switch (GST_EVENT_TYPE (event)) {
1384 case GST_EVENT_SEEK:
1385 /* no seeking until we are (safely) ready */
1386 if (parse->common.state != GST_MATROSKA_READ_STATE_DATA) {
1387 GST_DEBUG_OBJECT (parse, "not ready for seeking yet");
1390 res = gst_matroska_parse_handle_seek_push (parse, pad, event);
1391 gst_event_unref (event);
1396 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
1397 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
1398 GstMatroskaTrackVideoContext *videocontext =
1399 (GstMatroskaTrackVideoContext *) context;
1401 GstClockTimeDiff diff;
1402 GstClockTime timestamp;
1404 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
1406 GST_OBJECT_LOCK (parse);
1407 videocontext->earliest_time = timestamp + diff;
1408 GST_OBJECT_UNLOCK (parse);
1411 gst_event_unref (event);
1415 /* events we don't need to handle */
1416 case GST_EVENT_NAVIGATION:
1417 gst_event_unref (event);
1421 case GST_EVENT_LATENCY:
1423 res = gst_pad_push_event (parse->common.sinkpad, event);
1430 static GstFlowReturn
1431 gst_matroska_parse_parse_tracks (GstMatroskaParse * parse, GstEbmlRead * ebml)
1433 GstFlowReturn ret = GST_FLOW_OK;
1436 DEBUG_ELEMENT_START (parse, ebml, "Tracks");
1438 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1439 DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1443 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1444 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1448 /* one track within the "all-tracks" header */
1449 case GST_MATROSKA_ID_TRACKENTRY:
1450 ret = gst_matroska_parse_add_stream (parse, ebml);
1454 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1459 DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1461 parse->tracks_parsed = TRUE;
1467 * Read signed/unsigned "EBML" numbers.
1468 * Return: number of bytes processed.
1472 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
1474 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
1482 while (read <= 8 && !(total & len_mask)) {
1489 if ((total &= (len_mask - 1)) == len_mask - 1)
1494 if (data[n] == 0xff)
1496 total = (total << 8) | data[n];
1500 if (read == num_ffs && total != 0)
1509 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
1514 /* read as unsigned number first */
1515 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
1519 if (unum == G_MAXUINT64)
1522 *num = unum - ((1 << ((7 * res) - 1)) - 1);
1527 static GstFlowReturn
1528 gst_matroska_parse_parse_blockgroup_or_simpleblock (GstMatroskaParse * parse,
1529 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
1530 gboolean is_simpleblock)
1532 GstMatroskaTrackContext *stream = NULL;
1533 GstFlowReturn ret = GST_FLOW_OK;
1534 gboolean readblock = FALSE;
1536 guint64 block_duration = 0;
1537 GstBuffer *buf = NULL;
1539 gint stream_num = -1, n, laces = 0;
1541 gint *lace_size = NULL;
1544 gint64 referenceblock = 0;
1546 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1547 if (!is_simpleblock) {
1548 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
1552 id = GST_MATROSKA_ID_SIMPLEBLOCK;
1556 /* one block inside the group. Note, block parsing is one
1557 * of the harder things, so this code is a bit complicated.
1558 * See http://www.matroska.org/ for documentation. */
1559 case GST_MATROSKA_ID_SIMPLEBLOCK:
1560 case GST_MATROSKA_ID_BLOCK:
1566 gst_buffer_unref (buf);
1569 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
1572 gst_buffer_map (buf, &map, GST_MAP_READ);
1576 /* first byte(s): blocknum */
1577 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1582 /* fetch stream from num */
1583 stream_num = gst_matroska_read_common_stream_from_num (&parse->common,
1585 if (G_UNLIKELY (size < 3)) {
1586 GST_WARNING_OBJECT (parse, "Invalid size %u", size);
1587 /* non-fatal, try next block(group) */
1590 } else if (G_UNLIKELY (stream_num < 0 ||
1591 stream_num >= parse->common.num_streams)) {
1592 /* let's not give up on a stray invalid track number */
1593 GST_WARNING_OBJECT (parse,
1594 "Invalid stream %d for track number %" G_GUINT64_FORMAT
1595 "; ignoring block", stream_num, num);
1599 stream = g_ptr_array_index (parse->common.src, stream_num);
1601 /* time (relative to cluster time) */
1602 time = ((gint16) GST_READ_UINT16_BE (data));
1605 flags = GST_READ_UINT8 (data);
1609 GST_LOG_OBJECT (parse, "time %" G_GUINT64_FORMAT ", flags %d", time,
1612 switch ((flags & 0x06) >> 1) {
1613 case 0x0: /* no lacing */
1615 lace_size = g_new (gint, 1);
1616 lace_size[0] = size;
1619 case 0x1: /* xiph lacing */
1620 case 0x2: /* fixed-size lacing */
1621 case 0x3: /* EBML lacing */
1623 goto invalid_lacing;
1624 laces = GST_READ_UINT8 (data) + 1;
1627 lace_size = g_new0 (gint, laces);
1629 switch ((flags & 0x06) >> 1) {
1630 case 0x1: /* xiph lacing */ {
1631 guint temp, total = 0;
1633 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
1636 goto invalid_lacing;
1637 temp = GST_READ_UINT8 (data);
1638 lace_size[n] += temp;
1644 total += lace_size[n];
1646 lace_size[n] = size - total;
1650 case 0x2: /* fixed-size lacing */
1651 for (n = 0; n < laces; n++)
1652 lace_size[n] = size / laces;
1655 case 0x3: /* EBML lacing */ {
1658 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1662 total = lace_size[0] = num;
1663 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
1667 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
1671 lace_size[n] = lace_size[n - 1] + snum;
1672 total += lace_size[n];
1675 lace_size[n] = size - total;
1682 if (ret != GST_FLOW_OK)
1689 case GST_MATROSKA_ID_BLOCKDURATION:{
1690 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
1691 GST_DEBUG_OBJECT (parse, "BlockDuration: %" G_GUINT64_FORMAT,
1696 case GST_MATROSKA_ID_REFERENCEBLOCK:{
1697 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
1698 GST_DEBUG_OBJECT (parse, "ReferenceBlock: %" G_GINT64_FORMAT,
1703 case GST_MATROSKA_ID_CODECSTATE:{
1705 guint64 data_len = 0;
1708 gst_ebml_read_binary (ebml, &id, &data,
1709 &data_len)) != GST_FLOW_OK)
1712 if (G_UNLIKELY (stream == NULL)) {
1713 GST_WARNING_OBJECT (parse,
1714 "Unexpected CodecState subelement - ignoring");
1718 g_free (stream->codec_state);
1719 stream->codec_state = data;
1720 stream->codec_state_size = data_len;
1726 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1730 case GST_MATROSKA_ID_BLOCKVIRTUAL:
1731 case GST_MATROSKA_ID_BLOCKADDITIONS:
1732 case GST_MATROSKA_ID_REFERENCEPRIORITY:
1733 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
1734 case GST_MATROSKA_ID_SLICES:
1735 GST_DEBUG_OBJECT (parse,
1736 "Skipping BlockGroup subelement 0x%x - ignoring", id);
1737 ret = gst_ebml_read_skip (ebml);
1745 /* reading a number or so could have failed */
1746 if (ret != GST_FLOW_OK)
1749 if (ret == GST_FLOW_OK && readblock) {
1750 guint64 duration = 0;
1751 gint64 lace_time = 0;
1752 gboolean delta_unit;
1754 stream = g_ptr_array_index (parse->common.src, stream_num);
1756 if (cluster_time != GST_CLOCK_TIME_NONE) {
1757 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
1758 * Drop unless the lace contains timestamp 0? */
1759 if (time < 0 && (-time) > cluster_time) {
1762 if (stream->timecodescale == 1.0)
1763 lace_time = (cluster_time + time) * parse->common.time_scale;
1766 gst_util_guint64_to_gdouble ((cluster_time + time) *
1767 parse->common.time_scale) * stream->timecodescale;
1770 lace_time = GST_CLOCK_TIME_NONE;
1773 if (lace_time != GST_CLOCK_TIME_NONE) {
1774 parse->last_timestamp = lace_time;
1776 /* need to refresh segment info ASAP */
1777 if (GST_CLOCK_TIME_IS_VALID (lace_time) && parse->need_newsegment) {
1779 GST_DEBUG_OBJECT (parse,
1780 "generating segment starting at %" GST_TIME_FORMAT,
1781 GST_TIME_ARGS (lace_time));
1782 /* pretend we seeked here */
1783 gst_segment_do_seek (&parse->common.segment, parse->common.segment.rate,
1784 GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, lace_time,
1785 GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE, NULL);
1786 /* now convey our segment notion downstream */
1787 segment = parse->common.segment;
1788 segment.position = segment.start;
1789 gst_matroska_parse_send_event (parse, gst_event_new_segment (&segment));
1790 parse->need_newsegment = FALSE;
1793 if (block_duration) {
1794 if (stream->timecodescale == 1.0)
1795 duration = gst_util_uint64_scale (block_duration,
1796 parse->common.time_scale, 1);
1799 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
1800 (gst_util_uint64_scale (block_duration, parse->common.time_scale,
1801 1)) * stream->timecodescale);
1802 } else if (stream->default_duration) {
1803 duration = stream->default_duration * laces;
1805 /* else duration is diff between timecode of this and next block */
1807 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
1808 a ReferenceBlock implies that this is not a keyframe. In either
1809 case, it only makes sense for video streams. */
1810 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1811 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
1813 if (delta_unit && stream->set_discont) {
1814 /* When doing seeks or such, we need to restart on key frames or
1815 * decoders might choke. */
1816 GST_DEBUG_OBJECT (parse, "skipping delta unit");
1820 for (n = 0; n < laces; n++) {
1821 if (G_UNLIKELY (lace_size[n] > size)) {
1822 GST_WARNING_OBJECT (parse, "Invalid lace size");
1826 /* QoS for video track with an index. the assumption is that
1827 index entries point to keyframes, but if that is not true we
1828 will instad skip until the next keyframe. */
1829 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1830 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1831 stream->index_table && parse->common.segment.rate > 0.0) {
1832 GstMatroskaTrackVideoContext *videocontext =
1833 (GstMatroskaTrackVideoContext *) stream;
1834 GstClockTime earliest_time;
1835 GstClockTime earliest_stream_time;
1837 GST_OBJECT_LOCK (parse);
1838 earliest_time = videocontext->earliest_time;
1839 GST_OBJECT_UNLOCK (parse);
1840 earliest_stream_time =
1841 gst_segment_position_from_running_time (&parse->common.segment,
1842 GST_FORMAT_TIME, earliest_time);
1844 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1845 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
1846 lace_time <= earliest_stream_time) {
1847 /* find index entry (keyframe) <= earliest_stream_time */
1848 GstMatroskaIndex *entry =
1849 gst_util_array_binary_search (stream->index_table->data,
1850 stream->index_table->len, sizeof (GstMatroskaIndex),
1851 (GCompareDataFunc) gst_matroska_index_seek_find,
1852 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
1854 /* if that entry (keyframe) is after the current the current
1855 buffer, we can skip pushing (and thus decoding) all
1856 buffers until that keyframe. */
1857 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
1858 entry->time > lace_time) {
1859 GST_LOG_OBJECT (parse, "Skipping lace before late keyframe");
1860 stream->set_discont = TRUE;
1866 sub = gst_buffer_create_sub (buf,
1867 GST_BUFFER_SIZE (buf) - size, lace_size[n]);
1868 GST_DEBUG_OBJECT (parse, "created subbuffer %p", sub);
1871 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1873 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1875 if (stream->encodings != NULL && stream->encodings->len > 0)
1876 sub = gst_matroska_decode_buffer (stream, sub);
1879 GST_WARNING_OBJECT (parse, "Decoding buffer failed");
1883 GST_BUFFER_TIMESTAMP (sub) = lace_time;
1885 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
1886 GstClockTime last_stop_end;
1888 /* Check if this stream is after segment stop */
1889 if (GST_CLOCK_TIME_IS_VALID (parse->common.segment.stop) &&
1890 lace_time >= parse->common.segment.stop) {
1891 GST_DEBUG_OBJECT (parse,
1892 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
1893 GST_TIME_ARGS (parse->common.segment.stop));
1894 gst_buffer_unref (sub);
1897 if (offset >= stream->to_offset) {
1898 GST_DEBUG_OBJECT (parse, "Stream %d after playback section",
1900 gst_buffer_unref (sub);
1904 /* handle gaps, e.g. non-zero start-time, or an cue index entry
1905 * that landed us with timestamps not quite intended */
1906 if (GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop) &&
1907 parse->segment.rate > 0.0) {
1908 GstClockTimeDiff diff;
1910 /* only send newsegments with increasing start times,
1911 * otherwise if these go back and forth downstream (sinks) increase
1912 * accumulated time and running_time */
1913 diff = GST_CLOCK_DIFF (parse->segment.last_stop, lace_time);
1914 if (diff > 2 * GST_SECOND && lace_time > parse->segment.start &&
1915 (!GST_CLOCK_TIME_IS_VALID (parse->segment.stop) ||
1916 lace_time < parse->segment.stop)) {
1917 GST_DEBUG_OBJECT (parse,
1918 "Gap of %" G_GINT64_FORMAT " ns detected in"
1919 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
1920 "Sending updated NEWSEGMENT events", diff,
1921 stream->index, GST_TIME_ARGS (stream->pos),
1922 GST_TIME_ARGS (lace_time));
1923 /* send newsegment events such that the gap is not accounted in
1924 * accum time, hence running_time */
1925 /* close ahead of gap */
1926 gst_matroska_parse_send_event (parse,
1927 gst_event_new_new_segment (TRUE, parse->segment.rate,
1928 parse->segment.format, parse->segment.last_stop,
1929 parse->segment.last_stop, parse->segment.last_stop));
1931 gst_matroska_parse_send_event (parse,
1932 gst_event_new_new_segment (FALSE, parse->segment.rate,
1933 parse->segment.format, lace_time, parse->segment.stop,
1935 /* align segment view with downstream,
1936 * prevents double-counting accum when closing segment */
1937 gst_segment_set_newsegment (&parse->segment, FALSE,
1938 parse->segment.rate, parse->segment.format, lace_time,
1939 parse->segment.stop, lace_time);
1940 parse->segment.last_stop = lace_time;
1944 if (!GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop)
1945 || parse->segment.last_stop < lace_time) {
1946 parse->segment.last_stop = lace_time;
1949 last_stop_end = lace_time;
1951 GST_BUFFER_DURATION (sub) = duration / laces;
1952 last_stop_end += GST_BUFFER_DURATION (sub);
1955 if (!GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) ||
1956 parse->last_stop_end < last_stop_end)
1957 parse->last_stop_end = last_stop_end;
1959 if (parse->segment.duration == -1 ||
1960 parse->segment.duration < lace_time) {
1961 gst_segment_set_duration (&parse->segment, GST_FORMAT_TIME,
1963 gst_element_post_message (GST_ELEMENT_CAST (parse),
1964 gst_message_new_duration (GST_OBJECT_CAST (parse),
1965 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
1969 stream->pos = lace_time;
1971 gst_matroska_parse_sync_streams (parse);
1973 if (stream->set_discont) {
1974 GST_DEBUG_OBJECT (parse, "marking DISCONT");
1975 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
1976 stream->set_discont = FALSE;
1979 /* reverse playback book-keeping */
1980 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
1981 stream->from_time = lace_time;
1982 if (stream->from_offset == -1)
1983 stream->from_offset = offset;
1985 GST_DEBUG_OBJECT (parse,
1986 "Pushing lace %d, data of size %d for stream %d, time=%"
1987 GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
1988 GST_BUFFER_SIZE (sub), stream_num,
1989 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
1990 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
1992 if (parse->element_index) {
1993 if (stream->index_writer_id == -1)
1994 gst_index_get_writer_id (parse->element_index,
1995 GST_OBJECT (stream->pad), &stream->index_writer_id);
1997 GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
1998 G_GUINT64_FORMAT " for writer id %d",
1999 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
2000 stream->index_writer_id);
2001 gst_index_add_association (parse->element_index,
2002 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
2003 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
2004 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
2005 cluster_offset, NULL);
2008 gst_buffer_set_caps (sub, GST_PAD_CAPS (parse->srcpad));
2010 /* Postprocess the buffers depending on the codec used */
2011 if (stream->postprocess_frame) {
2012 GST_LOG_OBJECT (parse, "running post process");
2013 ret = stream->postprocess_frame (GST_ELEMENT (parse), stream, &sub);
2016 ret = gst_pad_push (stream->pad, sub);
2017 if (parse->segment.rate < 0) {
2018 if (lace_time > parse->segment.stop && ret == GST_FLOW_EOS) {
2019 /* In reverse playback we can get a GST_FLOW_EOS when
2020 * we are at the end of the segment, so we just need to jump
2021 * back to the previous section. */
2022 GST_DEBUG_OBJECT (parse, "downstream has reached end of segment");
2027 ret = gst_matroska_parse_combine_flows (parse, stream, ret);
2031 size -= lace_size[n];
2032 if (lace_time != GST_CLOCK_TIME_NONE && duration)
2033 lace_time += duration / laces;
2035 lace_time = GST_CLOCK_TIME_NONE;
2041 gst_buffer_unmap (buf, &map);
2042 gst_buffer_unref (buf);
2051 GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
2052 /* non-fatal, try next block(group) */
2058 GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Data error"));
2059 /* non-fatal, try next block(group) */
2065 /* return FALSE if block(group) should be skipped (due to a seek) */
2066 static inline gboolean
2067 gst_matroska_parse_seek_block (GstMatroskaParse * parse)
2069 if (G_UNLIKELY (parse->seek_block)) {
2070 if (!(--parse->seek_block)) {
2073 GST_LOG_OBJECT (parse, "should skip block due to seek");
2081 static GstFlowReturn
2082 gst_matroska_parse_parse_contents_seekentry (GstMatroskaParse * parse,
2086 guint64 seek_pos = (guint64) - 1;
2087 guint32 seek_id = 0;
2090 DEBUG_ELEMENT_START (parse, ebml, "Seek");
2092 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2093 DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2097 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2098 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2102 case GST_MATROSKA_ID_SEEKID:
2106 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2109 GST_DEBUG_OBJECT (parse, "SeekID: %" G_GUINT64_FORMAT, t);
2114 case GST_MATROSKA_ID_SEEKPOSITION:
2118 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2121 if (t > G_MAXINT64) {
2122 GST_WARNING_OBJECT (parse,
2123 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
2127 GST_DEBUG_OBJECT (parse, "SeekPosition: %" G_GUINT64_FORMAT, t);
2133 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2139 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
2142 if (!seek_id || seek_pos == (guint64) - 1) {
2143 GST_WARNING_OBJECT (parse, "Incomplete seekhead entry (0x%x/%"
2144 G_GUINT64_FORMAT ")", seek_id, seek_pos);
2149 case GST_MATROSKA_ID_SEEKHEAD:
2152 case GST_MATROSKA_ID_CUES:
2153 case GST_MATROSKA_ID_TAGS:
2154 case GST_MATROSKA_ID_TRACKS:
2155 case GST_MATROSKA_ID_SEGMENTINFO:
2156 case GST_MATROSKA_ID_ATTACHMENTS:
2157 case GST_MATROSKA_ID_CHAPTERS:
2162 length = gst_matroska_read_common_get_length (&parse->common);
2164 if (length == (guint64) - 1) {
2165 GST_DEBUG_OBJECT (parse, "no upstream length, skipping SeakHead entry");
2169 /* check for validity */
2170 if (seek_pos + parse->common.ebml_segment_start + 12 >= length) {
2171 GST_WARNING_OBJECT (parse,
2172 "SeekHead reference lies outside file!" " (%"
2173 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
2174 G_GUINT64_FORMAT ")", seek_pos, parse->common.ebml_segment_start,
2179 /* only pick up index location when streaming */
2180 if (seek_id == GST_MATROSKA_ID_CUES) {
2181 parse->index_offset = seek_pos + parse->common.ebml_segment_start;
2182 GST_DEBUG_OBJECT (parse, "Cues located at offset %" G_GUINT64_FORMAT,
2183 parse->index_offset);
2189 GST_DEBUG_OBJECT (parse, "Ignoring Seek entry for ID=0x%x", seek_id);
2192 DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2197 static GstFlowReturn
2198 gst_matroska_parse_parse_contents (GstMatroskaParse * parse, GstEbmlRead * ebml)
2200 GstFlowReturn ret = GST_FLOW_OK;
2203 DEBUG_ELEMENT_START (parse, ebml, "SeekHead");
2205 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2206 DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2210 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2211 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2215 case GST_MATROSKA_ID_SEEKENTRY:
2217 ret = gst_matroska_parse_parse_contents_seekentry (parse, ebml);
2218 /* Ignore EOS and errors here */
2219 if (ret != GST_FLOW_OK) {
2220 GST_DEBUG_OBJECT (parse, "Ignoring %s", gst_flow_get_name (ret));
2227 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2233 DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2238 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
2240 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
2242 static inline GstFlowReturn
2243 gst_matroska_parse_check_read_size (GstMatroskaParse * parse, guint64 bytes)
2245 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
2246 /* only a few blocks are expected/allowed to be large,
2247 * and will be recursed into, whereas others will be read and must fit */
2248 /* fatal in streaming case, as we can't step over easily */
2249 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2250 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
2251 "file might be corrupt.", bytes));
2252 return GST_FLOW_ERROR;
2259 /* returns TRUE if we truely are in error state, and should give up */
2260 static inline gboolean
2261 gst_matroska_parse_check_parse_error (GstMatroskaParse * parse)
2265 /* sigh, one last attempt above and beyond call of duty ...;
2266 * search for cluster mark following current pos */
2267 pos = parse->common.offset;
2268 GST_WARNING_OBJECT (parse, "parse error, looking for next cluster");
2269 if (gst_matroska_parse_search_cluster (parse, &pos) != GST_FLOW_OK) {
2270 /* did not work, give up */
2273 GST_DEBUG_OBJECT (parse, "... found at %" G_GUINT64_FORMAT, pos);
2274 /* try that position */
2275 parse->common.offset = pos;
2281 /* initializes @ebml with @bytes from input stream at current offset.
2282 * Returns EOS if insufficient available,
2283 * ERROR if too much was attempted to read. */
2284 static inline GstFlowReturn
2285 gst_matroska_parse_take (GstMatroskaParse * parse, guint64 bytes,
2288 GstBuffer *buffer = NULL;
2289 GstFlowReturn ret = GST_FLOW_OK;
2291 GST_LOG_OBJECT (parse, "taking %" G_GUINT64_FORMAT " bytes for parsing",
2293 ret = gst_matroska_parse_check_read_size (parse, bytes);
2294 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
2295 /* otherwise fatal */
2296 ret = GST_FLOW_ERROR;
2299 if (gst_adapter_available (parse->common.adapter) < bytes)
2300 return GST_FLOW_EOS;
2302 buffer = gst_adapter_take_buffer (parse->common.adapter, bytes);
2303 if (G_LIKELY (buffer)) {
2304 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (parse), buffer,
2305 parse->common.offset);
2306 parse->common.offset += bytes;
2308 ret = GST_FLOW_ERROR;
2316 gst_matroska_parse_check_seekability (GstMatroskaParse * parse)
2319 gboolean seekable = FALSE;
2320 gint64 start = -1, stop = -1;
2322 query = gst_query_new_seeking (GST_FORMAT_BYTES);
2323 if (!gst_pad_peer_query (parse->common.sinkpad, query)) {
2324 GST_DEBUG_OBJECT (parse, "seeking query failed");
2328 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
2330 /* try harder to query upstream size if we didn't get it the first time */
2331 if (seekable && stop == -1) {
2332 GST_DEBUG_OBJECT (parse, "doing duration query to fix up unset stop");
2333 gst_pad_peer_query_duration (parse->common.sinkpad, GST_FORMAT_BYTES,
2337 /* if upstream doesn't know the size, it's likely that it's not seekable in
2338 * practice even if it technically may be seekable */
2339 if (seekable && (start != 0 || stop <= start)) {
2340 GST_DEBUG_OBJECT (parse, "seekable but unknown start/stop -> disable");
2345 GST_INFO_OBJECT (parse, "seekable: %d (%" G_GUINT64_FORMAT " - %"
2346 G_GUINT64_FORMAT ")", seekable, start, stop);
2347 parse->seekable = seekable;
2349 gst_query_unref (query);
2353 static GstFlowReturn
2354 gst_matroska_parse_find_tracks (GstMatroskaParse * parse)
2360 GstFlowReturn ret = GST_FLOW_OK;
2362 GST_WARNING_OBJECT (parse,
2363 "Found Cluster element before Tracks, searching Tracks");
2366 before_pos = parse->common.offset;
2368 /* Search Tracks element */
2370 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2371 GST_ELEMENT_CAST (parse), &id, &length, &needed);
2372 if (ret != GST_FLOW_OK)
2375 if (id != GST_MATROSKA_ID_TRACKS) {
2376 /* we may be skipping large cluster here, so forego size check etc */
2377 /* ... but we can't skip undefined size; force error */
2378 if (length == G_MAXUINT64) {
2379 ret = gst_matroska_parse_check_read_size (parse, length);
2382 parse->common.offset += needed;
2383 parse->offset += length;
2388 /* will lead to track parsing ... */
2389 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2394 parse->offset = before_pos;
2400 #define GST_READ_CHECK(stmt) \
2402 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
2403 if (ret == GST_FLOW_OVERFLOW) { \
2404 ret = GST_FLOW_OK; \
2411 gst_matroska_parse_accumulate_streamheader (GstMatroskaParse * parse,
2414 if (parse->pushed_headers) {
2415 GST_WARNING_OBJECT (parse,
2416 "Accumulating headers, but headers are already pushed");
2419 if (parse->streamheader) {
2420 parse->streamheader = gst_buffer_append (parse->streamheader,
2421 gst_buffer_ref (buffer));
2423 parse->streamheader = gst_buffer_ref (buffer);
2426 GST_DEBUG ("%" G_GSIZE_FORMAT, gst_buffer_get_size (parse->streamheader));
2429 static GstFlowReturn
2430 gst_matroska_parse_output (GstMatroskaParse * parse, GstBuffer * buffer,
2435 if (!parse->pushed_headers) {
2438 GValue streamheader = { 0 };
2439 GValue bufval = { 0 };
2442 caps = gst_pad_get_current_caps (parse->common.sinkpad);
2444 caps = gst_matroska_parse_forge_caps (parse->common.is_webm,
2445 parse->common.has_video);
2447 caps = gst_caps_make_writable (caps);
2449 s = gst_caps_get_structure (caps, 0);
2450 g_value_init (&streamheader, GST_TYPE_ARRAY);
2451 g_value_init (&bufval, GST_TYPE_BUFFER);
2452 buf = gst_buffer_copy (parse->streamheader);
2453 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2454 gst_value_set_buffer (&bufval, buf);
2455 gst_buffer_unref (buf);
2456 gst_value_array_append_value (&streamheader, &bufval);
2457 g_value_unset (&bufval);
2458 gst_structure_set_value (s, "streamheader", &streamheader);
2459 g_value_unset (&streamheader);
2460 //gst_caps_replace (parse->caps, caps);
2461 gst_pad_set_caps (parse->srcpad, caps);
2463 if (parse->need_newsegment) {
2464 gst_pad_push_event (parse->srcpad,
2465 gst_event_new_segment (&parse->common.segment));
2466 parse->need_newsegment = FALSE;
2469 buf = gst_buffer_copy (parse->streamheader);
2470 gst_caps_unref (caps);
2472 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2473 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2474 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
2476 ret = gst_pad_push (parse->srcpad, buf);
2477 if (ret != GST_FLOW_OK) {
2478 GST_WARNING_OBJECT (parse, "Failed to push buffer");
2482 parse->pushed_headers = TRUE;
2486 GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2488 GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2490 if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE) {
2491 parse->last_timestamp = GST_BUFFER_TIMESTAMP (buffer);
2493 GST_BUFFER_TIMESTAMP (buffer) = parse->last_timestamp;
2496 return gst_pad_push (parse->srcpad, gst_buffer_ref (buffer));
2499 static GstFlowReturn
2500 gst_matroska_parse_parse_id (GstMatroskaParse * parse, guint32 id,
2501 guint64 length, guint needed)
2503 GstEbmlRead ebml = { 0, };
2504 GstFlowReturn ret = GST_FLOW_OK;
2506 //GstBuffer *buffer;
2508 GST_DEBUG_OBJECT (parse, "Parsing Element id 0x%x, "
2509 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
2512 if (gst_adapter_available (parse->adapter) >= length + needed) {
2513 buffer = gst_adapter_take_buffer (parse->adapter, length + needed);
2514 gst_pad_push (parse->srcpad, buffer);
2518 //GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2525 /* if we plan to read and parse this element, we need prefix (id + length)
2526 * and the contents */
2527 /* mind about overflow wrap-around when dealing with undefined size */
2529 if (G_LIKELY (length != G_MAXUINT64))
2532 switch (parse->common.state) {
2533 case GST_MATROSKA_READ_STATE_START:
2535 case GST_EBML_ID_HEADER:
2536 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2537 ret = gst_matroska_read_common_parse_header (&parse->common, &ebml);
2538 if (ret != GST_FLOW_OK)
2540 parse->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
2541 gst_matroska_parse_check_seekability (parse);
2542 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2545 goto invalid_header;
2549 case GST_MATROSKA_READ_STATE_SEGMENT:
2551 case GST_MATROSKA_ID_SEGMENT:
2552 /* eat segment prefix */
2553 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2554 GST_DEBUG_OBJECT (parse,
2555 "Found Segment start at offset %" G_GUINT64_FORMAT,
2556 parse->common.offset);
2557 /* seeks are from the beginning of the segment,
2558 * after the segment ID/length */
2559 parse->common.ebml_segment_start = parse->common.offset;
2560 parse->common.state = GST_MATROSKA_READ_STATE_HEADER;
2561 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2564 GST_WARNING_OBJECT (parse,
2565 "Expected a Segment ID (0x%x), but received 0x%x!",
2566 GST_MATROSKA_ID_SEGMENT, id);
2567 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2568 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2572 case GST_MATROSKA_READ_STATE_SCANNING:
2573 if (id != GST_MATROSKA_ID_CLUSTER &&
2574 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
2577 case GST_MATROSKA_READ_STATE_HEADER:
2578 case GST_MATROSKA_READ_STATE_DATA:
2579 case GST_MATROSKA_READ_STATE_SEEK:
2581 case GST_MATROSKA_ID_SEGMENTINFO:
2582 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2583 if (!parse->common.segmentinfo_parsed) {
2584 ret = gst_matroska_read_common_parse_info (&parse->common,
2585 GST_ELEMENT_CAST (parse), &ebml);
2586 if (ret == GST_FLOW_OK)
2587 gst_matroska_parse_send_tags (parse);
2589 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2591 case GST_MATROSKA_ID_TRACKS:
2592 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2593 if (!parse->tracks_parsed) {
2594 ret = gst_matroska_parse_parse_tracks (parse, &ebml);
2596 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2598 case GST_MATROSKA_ID_CLUSTER:
2599 if (G_UNLIKELY (!parse->tracks_parsed)) {
2600 GST_DEBUG_OBJECT (parse, "Cluster before Track");
2601 goto not_streamable;
2603 if (G_UNLIKELY (parse->common.state
2604 == GST_MATROSKA_READ_STATE_HEADER)) {
2605 parse->common.state = GST_MATROSKA_READ_STATE_DATA;
2606 parse->first_cluster_offset = parse->common.offset;
2607 GST_DEBUG_OBJECT (parse, "signaling no more pads");
2609 parse->cluster_time = GST_CLOCK_TIME_NONE;
2610 parse->cluster_offset = parse->common.offset;
2611 if (G_UNLIKELY (!parse->seek_first && parse->seek_block)) {
2612 GST_DEBUG_OBJECT (parse, "seek target block %" G_GUINT64_FORMAT
2613 " not found in Cluster, trying next Cluster's first block instead",
2615 parse->seek_block = 0;
2617 parse->seek_first = FALSE;
2618 /* record next cluster for recovery */
2619 if (read != G_MAXUINT64)
2620 parse->next_cluster_offset = parse->cluster_offset + read;
2621 /* eat cluster prefix */
2622 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2623 ret = gst_matroska_parse_output (parse, ebml.buf, TRUE);
2624 //gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2626 case GST_MATROSKA_ID_CLUSTERTIMECODE:
2630 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2631 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
2633 GST_DEBUG_OBJECT (parse, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
2634 parse->cluster_time = num;
2636 if (parse->common.element_index) {
2637 if (parse->common.element_index_writer_id == -1)
2638 gst_index_get_writer_id (parse->common.element_index,
2639 GST_OBJECT (parse), &parse->common.element_index_writer_id);
2640 GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
2641 G_GUINT64_FORMAT " for writer id %d",
2642 GST_TIME_ARGS (parse->cluster_time), parse->cluster_offset,
2643 parse->common.element_index_writer_id);
2644 gst_index_add_association (parse->common.element_index,
2645 parse->common.element_index_writer_id,
2646 GST_ASSOCIATION_FLAG_KEY_UNIT,
2647 GST_FORMAT_TIME, parse->cluster_time,
2648 GST_FORMAT_BYTES, parse->cluster_offset, NULL);
2651 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2654 case GST_MATROSKA_ID_BLOCKGROUP:
2655 if (!gst_matroska_parse_seek_block (parse))
2657 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2658 DEBUG_ELEMENT_START (parse, &ebml, "BlockGroup");
2659 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
2660 ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
2661 &ebml, parse->cluster_time, parse->cluster_offset, FALSE);
2663 DEBUG_ELEMENT_STOP (parse, &ebml, "BlockGroup", ret);
2664 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2666 case GST_MATROSKA_ID_SIMPLEBLOCK:
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, "SimpleBlock");
2671 ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
2672 &ebml, parse->cluster_time, parse->cluster_offset, TRUE);
2673 DEBUG_ELEMENT_STOP (parse, &ebml, "SimpleBlock", ret);
2674 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2676 case GST_MATROSKA_ID_ATTACHMENTS:
2677 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2678 if (!parse->common.attachments_parsed) {
2679 ret = gst_matroska_read_common_parse_attachments (&parse->common,
2680 GST_ELEMENT_CAST (parse), &ebml);
2681 if (ret == GST_FLOW_OK)
2682 gst_matroska_parse_send_tags (parse);
2684 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2686 case GST_MATROSKA_ID_TAGS:
2687 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2688 ret = gst_matroska_read_common_parse_metadata (&parse->common,
2689 GST_ELEMENT_CAST (parse), &ebml);
2690 if (ret == GST_FLOW_OK)
2691 gst_matroska_parse_send_tags (parse);
2692 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2694 case GST_MATROSKA_ID_CHAPTERS:
2695 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2696 ret = gst_matroska_read_common_parse_chapters (&parse->common, &ebml);
2697 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2699 case GST_MATROSKA_ID_SEEKHEAD:
2700 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2701 ret = gst_matroska_parse_parse_contents (parse, &ebml);
2702 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2704 case GST_MATROSKA_ID_CUES:
2705 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2706 if (!parse->common.index_parsed) {
2707 ret = gst_matroska_read_common_parse_index (&parse->common, &ebml);
2708 /* only push based; delayed index building */
2709 if (ret == GST_FLOW_OK
2710 && parse->common.state == GST_MATROSKA_READ_STATE_SEEK) {
2713 GST_OBJECT_LOCK (parse);
2714 event = parse->seek_event;
2715 parse->seek_event = NULL;
2716 GST_OBJECT_UNLOCK (parse);
2719 /* unlikely to fail, since we managed to seek to this point */
2720 if (!gst_matroska_parse_handle_seek_event (parse, NULL, event))
2722 /* resume data handling, main thread clear to seek again */
2723 GST_OBJECT_LOCK (parse);
2724 parse->common.state = GST_MATROSKA_READ_STATE_DATA;
2725 GST_OBJECT_UNLOCK (parse);
2728 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2730 case GST_MATROSKA_ID_POSITION:
2731 case GST_MATROSKA_ID_PREVSIZE:
2732 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
2733 case GST_MATROSKA_ID_SILENTTRACKS:
2734 GST_DEBUG_OBJECT (parse,
2735 "Skipping Cluster subelement 0x%x - ignoring", id);
2739 GST_DEBUG_OBJECT (parse, "skipping Element 0x%x", id);
2740 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2741 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2747 if (ret == GST_FLOW_PARSE)
2751 gst_ebml_read_clear (&ebml);
2757 /* simply exit, maybe not enough data yet */
2758 /* no ebml to clear if read error */
2763 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2764 ("Failed to parse Element 0x%x", id));
2765 ret = GST_FLOW_ERROR;
2770 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2771 ("File layout does not permit streaming"));
2772 ret = GST_FLOW_ERROR;
2778 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2779 ("No Tracks element found"));
2780 ret = GST_FLOW_ERROR;
2786 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Invalid header"));
2787 ret = GST_FLOW_ERROR;
2792 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Failed to seek"));
2793 ret = GST_FLOW_ERROR;
2800 gst_matroska_parse_loop (GstPad * pad)
2802 GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
2808 /* If we have to close a segment, send a new segment to do this now */
2809 if (G_LIKELY (parse->common.state == GST_MATROSKA_READ_STATE_DATA)) {
2810 if (G_UNLIKELY (parse->close_segment)) {
2811 gst_matroska_parse_send_event (parse, parse->close_segment);
2812 parse->close_segment = NULL;
2814 if (G_UNLIKELY (parse->new_segment)) {
2815 gst_matroska_parse_send_event (parse, parse->new_segment);
2816 parse->new_segment = NULL;
2820 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2821 GST_ELEMENT_CAST (parse), &id, &length, &needed);
2822 if (ret == GST_FLOW_EOS)
2824 if (ret != GST_FLOW_OK) {
2825 if (gst_matroska_parse_check_parse_error (parse))
2831 GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2832 "size %" G_GUINT64_FORMAT ", needed %d", parse->offset, id,
2835 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2836 if (ret == GST_FLOW_EOS)
2838 if (ret != GST_FLOW_OK)
2841 /* check if we're at the end of a configured segment */
2842 if (G_LIKELY (parse->src->len)) {
2845 g_assert (parse->num_streams == parse->src->len);
2846 for (i = 0; i < parse->src->len; i++) {
2847 GstMatroskaTrackContext *context = g_ptr_array_index (parse->src, i);
2848 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
2849 GST_TIME_ARGS (context->pos));
2850 if (context->eos == FALSE)
2854 GST_INFO_OBJECT (parse, "All streams are EOS");
2860 if (G_UNLIKELY (parse->offset ==
2861 gst_matroska_read_common_get_length (&parse->common))) {
2862 GST_LOG_OBJECT (parse, "Reached end of stream");
2872 if (parse->segment.rate < 0.0) {
2873 ret = gst_matroska_parse_seek_to_previous_keyframe (parse);
2874 if (ret == GST_FLOW_OK)
2881 const gchar *reason = gst_flow_get_name (ret);
2882 gboolean push_eos = FALSE;
2884 GST_LOG_OBJECT (parse, "pausing task, reason %s", reason);
2885 parse->segment_running = FALSE;
2886 gst_pad_pause_task (parse->common.sinkpad);
2888 if (ret == GST_FLOW_EOS) {
2889 /* perform EOS logic */
2891 /* Close the segment, i.e. update segment stop with the duration
2892 * if no stop was set */
2893 if (GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) &&
2894 !GST_CLOCK_TIME_IS_VALID (parse->segment.stop)) {
2896 gst_event_new_new_segment_full (TRUE, parse->segment.rate,
2897 parse->segment.applied_rate, parse->segment.format,
2898 parse->segment.start,
2899 MAX (parse->last_stop_end, parse->segment.start),
2900 parse->segment.time);
2901 gst_matroska_parse_send_event (parse, event);
2904 if (parse->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2907 /* for segment playback we need to post when (in stream time)
2908 * we stopped, this is either stop (when set) or the duration. */
2909 if ((stop = parse->segment.stop) == -1)
2910 stop = parse->last_stop_end;
2912 GST_LOG_OBJECT (parse, "Sending segment done, at end of segment");
2913 gst_element_post_message (GST_ELEMENT (parse),
2914 gst_message_new_segment_done (GST_OBJECT (parse), GST_FORMAT_TIME,
2916 gst_matroska_parse_send_event (parse,
2917 gst_event_new_segment_done (GST_FORMAT_TIME, stop));
2921 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
2922 /* for fatal errors we post an error message */
2923 GST_ELEMENT_ERROR (parse, STREAM, FAILED, (NULL),
2924 ("stream stopped, reason %s", reason));
2928 /* send EOS, and prevent hanging if no streams yet */
2929 GST_LOG_OBJECT (parse, "Sending EOS, at end of stream");
2930 if (!gst_matroska_parse_send_event (parse, gst_event_new_eos ()) &&
2931 (ret == GST_FLOW_EOS)) {
2932 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
2933 (NULL), ("got eos but no streams (yet)"));
2942 * Create and push a flushing seek event upstream
2945 perform_seek_to_offset (GstMatroskaParse * parse, guint64 offset)
2950 GST_DEBUG_OBJECT (parse, "Seeking to %" G_GUINT64_FORMAT, offset);
2953 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
2954 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
2955 GST_SEEK_TYPE_NONE, -1);
2957 res = gst_pad_push_event (parse->common.sinkpad, event);
2959 /* newsegment event will update offset */
2964 * Forge empty default caps when all we know is the stream's EBML
2965 * type and whether it has video or not.
2967 * FIXME: Do something with video/x-matroska-3d if possible
2970 gst_matroska_parse_forge_caps (gboolean is_webm, gboolean has_video)
2976 caps = gst_caps_new_empty_simple ("video/webm");
2978 caps = gst_caps_new_empty_simple ("audio/webm");
2981 caps = gst_caps_new_empty_simple ("video/x-matroska");
2983 caps = gst_caps_new_empty_simple ("audio/x-matroska");
2988 static GstFlowReturn
2989 gst_matroska_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
2991 GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
2993 GstFlowReturn ret = GST_FLOW_OK;
2998 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
2999 GST_DEBUG_OBJECT (parse, "got DISCONT");
3000 gst_adapter_clear (parse->common.adapter);
3001 GST_OBJECT_LOCK (parse);
3002 gst_matroska_read_common_reset_streams (&parse->common,
3003 GST_CLOCK_TIME_NONE, FALSE);
3004 GST_OBJECT_UNLOCK (parse);
3007 gst_adapter_push (parse->common.adapter, buffer);
3011 available = gst_adapter_available (parse->common.adapter);
3013 ret = gst_matroska_read_common_peek_id_length_push (&parse->common,
3014 GST_ELEMENT_CAST (parse), &id, &length, &needed);
3015 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS))
3018 GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
3019 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
3020 parse->common.offset, id, length, needed, available);
3022 if (needed > available)
3025 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
3026 if (ret == GST_FLOW_EOS) {
3027 /* need more data */
3029 } else if (ret != GST_FLOW_OK) {
3036 gst_matroska_parse_handle_sink_event (GstPad * pad, GstObject * parent,
3039 gboolean res = TRUE;
3040 GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
3042 GST_DEBUG_OBJECT (parse,
3043 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
3045 switch (GST_EVENT_TYPE (event)) {
3046 case GST_EVENT_SEGMENT:
3048 const GstSegment *segment;
3050 /* some debug output */
3051 gst_event_parse_segment (event, &segment);
3052 GST_DEBUG_OBJECT (parse,
3053 "received format %d newsegment %" GST_SEGMENT_FORMAT,
3054 segment->format, segment);
3056 if (parse->common.state < GST_MATROSKA_READ_STATE_DATA) {
3057 GST_DEBUG_OBJECT (parse, "still starting");
3061 /* we only expect a BYTE segment, e.g. following a seek */
3062 if (segment->format != GST_FORMAT_BYTES) {
3063 GST_DEBUG_OBJECT (parse, "unsupported segment format, ignoring");
3067 GST_DEBUG_OBJECT (parse, "clearing segment state");
3068 /* clear current segment leftover */
3069 gst_adapter_clear (parse->common.adapter);
3070 /* and some streaming setup */
3071 parse->common.offset = segment->start;
3072 /* do not know where we are;
3073 * need to come across a cluster and generate newsegment */
3074 parse->common.segment.position = GST_CLOCK_TIME_NONE;
3075 parse->cluster_time = GST_CLOCK_TIME_NONE;
3076 parse->cluster_offset = 0;
3077 parse->need_newsegment = TRUE;
3078 /* but keep some of the upstream segment */
3079 parse->common.segment.rate = segment->rate;
3081 /* chain will send initial newsegment after pads have been added,
3082 * or otherwise come up with one */
3083 GST_DEBUG_OBJECT (parse, "eating event");
3084 gst_event_unref (event);
3090 if (parse->common.state != GST_MATROSKA_READ_STATE_DATA) {
3091 gst_event_unref (event);
3092 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3093 (NULL), ("got eos and didn't receive a complete header object"));
3094 } else if (parse->common.num_streams == 0) {
3095 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3096 (NULL), ("got eos but no streams (yet)"));
3098 gst_matroska_parse_send_event (parse, event);
3102 case GST_EVENT_FLUSH_STOP:
3104 gst_adapter_clear (parse->common.adapter);
3105 GST_OBJECT_LOCK (parse);
3106 gst_matroska_read_common_reset_streams (&parse->common,
3107 GST_CLOCK_TIME_NONE, TRUE);
3108 GST_OBJECT_UNLOCK (parse);
3109 parse->common.segment.position = GST_CLOCK_TIME_NONE;
3110 parse->cluster_time = GST_CLOCK_TIME_NONE;
3111 parse->cluster_offset = 0;
3115 res = gst_pad_event_default (pad, parent, event);
3124 gst_matroska_parse_set_index (GstElement * element, GstIndex * index)
3126 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3128 GST_OBJECT_LOCK (parse);
3129 if (parse->common.element_index)
3130 gst_object_unref (parse->common.element_index);
3131 parse->common.element_index = index ? gst_object_ref (index) : NULL;
3132 GST_OBJECT_UNLOCK (parse);
3133 GST_DEBUG_OBJECT (parse, "Set index %" GST_PTR_FORMAT,
3134 parse->common.element_index);
3138 gst_matroska_parse_get_index (GstElement * element)
3140 GstIndex *result = NULL;
3141 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3143 GST_OBJECT_LOCK (parse);
3144 if (parse->common.element_index)
3145 result = gst_object_ref (parse->common.element_index);
3146 GST_OBJECT_UNLOCK (parse);
3148 GST_DEBUG_OBJECT (parse, "Returning index %" GST_PTR_FORMAT, result);
3154 static GstStateChangeReturn
3155 gst_matroska_parse_change_state (GstElement * element,
3156 GstStateChange transition)
3158 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3159 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
3161 /* handle upwards state changes here */
3162 switch (transition) {
3167 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
3169 /* handle downwards state changes */
3170 switch (transition) {
3171 case GST_STATE_CHANGE_PAUSED_TO_READY:
3172 gst_matroska_parse_reset (GST_ELEMENT (parse));
3182 gst_matroska_parse_plugin_init (GstPlugin * plugin)
3186 /* create an elementfactory for the matroska_parse element */
3187 if (!gst_element_register (plugin, "matroskaparse",
3188 GST_RANK_NONE, GST_TYPE_MATROSKA_PARSE))