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., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, 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 -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))
87 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
90 GST_STATIC_CAPS ("video/x-matroska; video/webm")
93 static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
96 GST_STATIC_CAPS ("video/x-matroska; 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,
115 static const GstQueryType *gst_matroska_parse_get_src_query_types (GstPad *
117 static gboolean gst_matroska_parse_handle_src_query (GstPad * pad,
120 static gboolean gst_matroska_parse_handle_sink_event (GstPad * pad,
122 static GstFlowReturn gst_matroska_parse_chain (GstPad * pad,
125 static GstStateChangeReturn
126 gst_matroska_parse_change_state (GstElement * element,
127 GstStateChange transition);
129 gst_matroska_parse_set_index (GstElement * element, GstIndex * index);
130 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,
137 GType gst_matroska_parse_get_type (void);
138 GST_BOILERPLATE (GstMatroskaParse, gst_matroska_parse, GstElement,
142 gst_matroska_parse_base_init (gpointer klass)
144 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
146 gst_element_class_add_static_pad_template (element_class, &src_templ);
147 gst_element_class_add_static_pad_template (element_class, &sink_templ);
149 gst_element_class_set_details_simple (element_class, "Matroska parser",
151 "Parses Matroska/WebM streams into video/audio/subtitles",
152 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
156 gst_matroska_parse_finalize (GObject * object)
158 GstMatroskaParse *parse = GST_MATROSKA_PARSE (object);
160 if (parse->common.src) {
161 g_ptr_array_free (parse->common.src, TRUE);
162 parse->common.src = NULL;
165 if (parse->common.global_tags) {
166 gst_tag_list_free (parse->common.global_tags);
167 parse->common.global_tags = NULL;
170 g_object_unref (parse->common.adapter);
172 G_OBJECT_CLASS (parent_class)->finalize (object);
176 gst_matroska_parse_class_init (GstMatroskaParseClass * klass)
178 GObjectClass *gobject_class = (GObjectClass *) klass;
179 GstElementClass *gstelement_class = (GstElementClass *) klass;
181 GST_DEBUG_CATEGORY_INIT (matroskaparse_debug, "matroskaparse", 0,
184 gobject_class->finalize = gst_matroska_parse_finalize;
186 gstelement_class->change_state =
187 GST_DEBUG_FUNCPTR (gst_matroska_parse_change_state);
188 gstelement_class->send_event =
189 GST_DEBUG_FUNCPTR (gst_matroska_parse_element_send_event);
190 gstelement_class->query =
191 GST_DEBUG_FUNCPTR (gst_matroska_parse_element_query);
193 gstelement_class->set_index =
194 GST_DEBUG_FUNCPTR (gst_matroska_parse_set_index);
195 gstelement_class->get_index =
196 GST_DEBUG_FUNCPTR (gst_matroska_parse_get_index);
200 gst_matroska_parse_init (GstMatroskaParse * parse,
201 GstMatroskaParseClass * klass)
203 parse->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
205 gst_pad_set_chain_function (parse->common.sinkpad,
206 GST_DEBUG_FUNCPTR (gst_matroska_parse_chain));
207 gst_pad_set_event_function (parse->common.sinkpad,
208 GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_sink_event));
209 gst_element_add_pad (GST_ELEMENT (parse), parse->common.sinkpad);
211 parse->srcpad = gst_pad_new_from_static_template (&src_templ, "src");
212 gst_pad_set_event_function (parse->srcpad,
213 GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_event));
214 gst_pad_set_query_type_function (parse->srcpad,
215 GST_DEBUG_FUNCPTR (gst_matroska_parse_get_src_query_types));
216 gst_pad_set_query_function (parse->srcpad,
217 GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_query));
218 gst_pad_use_fixed_caps (parse->srcpad);
220 gst_element_add_pad (GST_ELEMENT (parse), parse->srcpad);
222 /* initial stream no. */
223 parse->common.src = NULL;
225 parse->common.writing_app = NULL;
226 parse->common.muxing_app = NULL;
227 parse->common.index = NULL;
228 parse->common.global_tags = NULL;
230 parse->common.adapter = gst_adapter_new ();
233 gst_matroska_parse_reset (GST_ELEMENT (parse));
237 gst_matroska_track_free (GstMatroskaTrackContext * track)
239 g_free (track->codec_id);
240 g_free (track->codec_name);
241 g_free (track->name);
242 g_free (track->language);
243 g_free (track->codec_priv);
244 g_free (track->codec_state);
246 if (track->encodings != NULL) {
249 for (i = 0; i < track->encodings->len; ++i) {
250 GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
251 GstMatroskaTrackEncoding,
254 g_free (enc->comp_settings);
256 g_array_free (track->encodings, TRUE);
259 if (track->pending_tags)
260 gst_tag_list_free (track->pending_tags);
262 if (track->index_table)
263 g_array_free (track->index_table, TRUE);
269 gst_matroska_parse_free_parsed_el (gpointer mem, gpointer user_data)
271 g_slice_free (guint64, mem);
275 gst_matroska_parse_reset (GstElement * element)
277 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
280 GST_DEBUG_OBJECT (parse, "Resetting state");
283 parse->common.state = GST_MATROSKA_READ_STATE_START;
285 /* clean up existing streams */
286 if (parse->common.src) {
287 g_assert (parse->common.src->len == parse->common.num_streams);
288 for (i = 0; i < parse->common.src->len; i++) {
289 GstMatroskaTrackContext *context = g_ptr_array_index (parse->common.src,
292 gst_caps_replace (&context->caps, NULL);
293 gst_matroska_track_free (context);
295 g_ptr_array_free (parse->common.src, TRUE);
297 parse->common.src = g_ptr_array_new ();
299 parse->common.num_streams = 0;
300 parse->num_a_streams = 0;
301 parse->num_t_streams = 0;
302 parse->num_v_streams = 0;
304 /* reset media info */
305 g_free (parse->common.writing_app);
306 parse->common.writing_app = NULL;
307 g_free (parse->common.muxing_app);
308 parse->common.muxing_app = NULL;
311 if (parse->common.index) {
312 g_array_free (parse->common.index, TRUE);
313 parse->common.index = NULL;
318 parse->common.time_scale = 1000000;
319 parse->common.created = G_MININT64;
321 parse->common.index_parsed = FALSE;
322 parse->tracks_parsed = FALSE;
323 parse->common.segmentinfo_parsed = FALSE;
324 parse->common.attachments_parsed = FALSE;
326 g_list_foreach (parse->common.tags_parsed,
327 (GFunc) gst_matroska_parse_free_parsed_el, NULL);
328 g_list_free (parse->common.tags_parsed);
329 parse->common.tags_parsed = NULL;
331 g_list_foreach (parse->seek_parsed,
332 (GFunc) gst_matroska_parse_free_parsed_el, NULL);
333 g_list_free (parse->seek_parsed);
334 parse->seek_parsed = NULL;
336 gst_segment_init (&parse->common.segment, GST_FORMAT_TIME);
337 parse->last_stop_end = GST_CLOCK_TIME_NONE;
338 parse->seek_block = 0;
340 parse->common.offset = 0;
341 parse->cluster_time = GST_CLOCK_TIME_NONE;
342 parse->cluster_offset = 0;
343 parse->next_cluster_offset = 0;
344 parse->index_offset = 0;
345 parse->seekable = FALSE;
346 parse->need_newsegment = FALSE;
347 parse->building_index = FALSE;
348 if (parse->seek_event) {
349 gst_event_unref (parse->seek_event);
350 parse->seek_event = NULL;
353 parse->seek_index = NULL;
354 parse->seek_entry = 0;
356 if (parse->close_segment) {
357 gst_event_unref (parse->close_segment);
358 parse->close_segment = NULL;
361 if (parse->new_segment) {
362 gst_event_unref (parse->new_segment);
363 parse->new_segment = NULL;
366 if (parse->common.element_index) {
367 gst_object_unref (parse->common.element_index);
368 parse->common.element_index = NULL;
370 parse->common.element_index_writer_id = -1;
372 if (parse->common.global_tags) {
373 gst_tag_list_free (parse->common.global_tags);
375 parse->common.global_tags = gst_tag_list_new ();
377 if (parse->common.cached_buffer) {
378 gst_buffer_unref (parse->common.cached_buffer);
379 parse->common.cached_buffer = NULL;
382 if (parse->streamheader != NULL) {
383 gst_buffer_unref (parse->streamheader);
384 parse->streamheader = NULL;
389 gst_matroska_parse_add_stream (GstMatroskaParse * parse, GstEbmlRead * ebml)
391 GstMatroskaTrackContext *context;
395 DEBUG_ELEMENT_START (parse, ebml, "TrackEntry");
397 /* start with the master */
398 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
399 DEBUG_ELEMENT_STOP (parse, ebml, "TrackEntry", ret);
403 /* allocate generic... if we know the type, we'll g_renew()
404 * with the precise type */
405 context = g_new0 (GstMatroskaTrackContext, 1);
406 g_ptr_array_add (parse->common.src, context);
407 context->index = parse->common.num_streams;
408 context->index_writer_id = -1;
409 context->type = 0; /* no type yet */
410 context->default_duration = 0;
412 context->set_discont = TRUE;
413 context->timecodescale = 1.0;
415 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
416 GST_MATROSKA_TRACK_LACING;
417 context->last_flow = GST_FLOW_OK;
418 context->to_offset = G_MAXINT64;
419 context->alignment = 1;
420 parse->common.num_streams++;
421 g_assert (parse->common.src->len == parse->common.num_streams);
423 GST_DEBUG_OBJECT (parse, "Stream number %d", context->index);
425 /* try reading the trackentry headers */
426 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
427 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
431 /* track number (unique stream ID) */
432 case GST_MATROSKA_ID_TRACKNUMBER:{
435 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
439 GST_ERROR_OBJECT (parse, "Invalid TrackNumber 0");
440 ret = GST_FLOW_ERROR;
442 } else if (!gst_matroska_read_common_tracknumber_unique (&parse->common,
444 GST_ERROR_OBJECT (parse, "TrackNumber %" G_GUINT64_FORMAT
445 " is not unique", num);
446 ret = GST_FLOW_ERROR;
450 GST_DEBUG_OBJECT (parse, "TrackNumber: %" G_GUINT64_FORMAT, num);
454 /* track UID (unique identifier) */
455 case GST_MATROSKA_ID_TRACKUID:{
458 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
462 GST_ERROR_OBJECT (parse, "Invalid TrackUID 0");
463 ret = GST_FLOW_ERROR;
467 GST_DEBUG_OBJECT (parse, "TrackUID: %" G_GUINT64_FORMAT, num);
472 /* track type (video, audio, combined, subtitle, etc.) */
473 case GST_MATROSKA_ID_TRACKTYPE:{
476 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
480 if (context->type != 0 && context->type != track_type) {
481 GST_WARNING_OBJECT (parse,
482 "More than one tracktype defined in a TrackEntry - skipping");
484 } else if (track_type < 1 || track_type > 254) {
485 GST_WARNING_OBJECT (parse, "Invalid TrackType %" G_GUINT64_FORMAT,
490 GST_DEBUG_OBJECT (parse, "TrackType: %" G_GUINT64_FORMAT, track_type);
492 /* ok, so we're actually going to reallocate this thing */
493 switch (track_type) {
494 case GST_MATROSKA_TRACK_TYPE_VIDEO:
495 gst_matroska_track_init_video_context (&context);
497 case GST_MATROSKA_TRACK_TYPE_AUDIO:
498 gst_matroska_track_init_audio_context (&context);
500 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
501 gst_matroska_track_init_subtitle_context (&context);
503 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
504 case GST_MATROSKA_TRACK_TYPE_LOGO:
505 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
506 case GST_MATROSKA_TRACK_TYPE_CONTROL:
508 GST_WARNING_OBJECT (parse,
509 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
514 g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
519 /* tracktype specific stuff for video */
520 case GST_MATROSKA_ID_TRACKVIDEO:{
521 GstMatroskaTrackVideoContext *videocontext;
523 DEBUG_ELEMENT_START (parse, ebml, "TrackVideo");
525 if (!gst_matroska_track_init_video_context (&context)) {
526 GST_WARNING_OBJECT (parse,
527 "TrackVideo element in non-video track - ignoring track");
528 ret = GST_FLOW_ERROR;
530 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
533 videocontext = (GstMatroskaTrackVideoContext *) context;
534 g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
537 while (ret == GST_FLOW_OK &&
538 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
539 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
543 /* Should be one level up but some broken muxers write it here. */
544 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
547 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
551 GST_WARNING_OBJECT (parse, "Invalid TrackDefaultDuration 0");
555 GST_DEBUG_OBJECT (parse,
556 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
557 context->default_duration = num;
561 /* video framerate */
562 /* NOTE: This one is here only for backward compatibility.
563 * Use _TRACKDEFAULDURATION one level up. */
564 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
567 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
571 GST_WARNING_OBJECT (parse, "Invalid TrackVideoFPS %lf", num);
575 GST_DEBUG_OBJECT (parse, "TrackVideoFrameRate: %lf", num);
576 if (context->default_duration == 0)
577 context->default_duration =
578 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
579 videocontext->default_fps = num;
583 /* width of the size to display the video at */
584 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
587 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
591 GST_WARNING_OBJECT (parse, "Invalid TrackVideoDisplayWidth 0");
595 GST_DEBUG_OBJECT (parse,
596 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
597 videocontext->display_width = num;
601 /* height of the size to display the video at */
602 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
605 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
609 GST_WARNING_OBJECT (parse, "Invalid TrackVideoDisplayHeight 0");
613 GST_DEBUG_OBJECT (parse,
614 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
615 videocontext->display_height = num;
619 /* width of the video in the file */
620 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
623 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
627 GST_WARNING_OBJECT (parse, "Invalid TrackVideoPixelWidth 0");
631 GST_DEBUG_OBJECT (parse,
632 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
633 videocontext->pixel_width = num;
637 /* height of the video in the file */
638 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
641 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
645 GST_WARNING_OBJECT (parse, "Invalid TrackVideoPixelHeight 0");
649 GST_DEBUG_OBJECT (parse,
650 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
651 videocontext->pixel_height = num;
655 /* whether the video is interlaced */
656 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
659 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
663 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
665 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
666 GST_DEBUG_OBJECT (parse, "TrackVideoInterlaced: %d",
667 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
672 /* aspect ratio behaviour */
673 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
676 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
679 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
680 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
681 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
682 GST_WARNING_OBJECT (parse,
683 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
686 GST_DEBUG_OBJECT (parse,
687 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
688 videocontext->asr_mode = num;
692 /* colourspace (only matters for raw video) fourcc */
693 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
698 gst_ebml_read_binary (ebml, &id, &data,
699 &datalen)) != GST_FLOW_OK)
704 GST_WARNING_OBJECT (parse,
705 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
710 memcpy (&videocontext->fourcc, data, 4);
711 GST_DEBUG_OBJECT (parse,
712 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
713 GST_FOURCC_ARGS (videocontext->fourcc));
719 GST_WARNING_OBJECT (parse,
720 "Unknown TrackVideo subelement 0x%x - ignoring", id);
722 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
723 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
724 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
725 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
726 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
727 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
728 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
729 ret = gst_ebml_read_skip (ebml);
734 DEBUG_ELEMENT_STOP (parse, ebml, "TrackVideo", ret);
738 /* tracktype specific stuff for audio */
739 case GST_MATROSKA_ID_TRACKAUDIO:{
740 GstMatroskaTrackAudioContext *audiocontext;
742 DEBUG_ELEMENT_START (parse, ebml, "TrackAudio");
744 if (!gst_matroska_track_init_audio_context (&context)) {
745 GST_WARNING_OBJECT (parse,
746 "TrackAudio element in non-audio track - ignoring track");
747 ret = GST_FLOW_ERROR;
751 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
754 audiocontext = (GstMatroskaTrackAudioContext *) context;
755 g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
758 while (ret == GST_FLOW_OK &&
759 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
760 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
765 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
768 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
773 GST_WARNING_OBJECT (parse,
774 "Invalid TrackAudioSamplingFrequency %lf", num);
778 GST_DEBUG_OBJECT (parse, "TrackAudioSamplingFrequency: %lf", num);
779 audiocontext->samplerate = num;
784 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
787 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
791 GST_WARNING_OBJECT (parse, "Invalid TrackAudioBitDepth 0");
795 GST_DEBUG_OBJECT (parse, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
797 audiocontext->bitdepth = num;
802 case GST_MATROSKA_ID_AUDIOCHANNELS:{
805 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
809 GST_WARNING_OBJECT (parse, "Invalid TrackAudioChannels 0");
813 GST_DEBUG_OBJECT (parse, "TrackAudioChannels: %" G_GUINT64_FORMAT,
815 audiocontext->channels = num;
820 GST_WARNING_OBJECT (parse,
821 "Unknown TrackAudio subelement 0x%x - ignoring", id);
823 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
824 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
825 ret = gst_ebml_read_skip (ebml);
830 DEBUG_ELEMENT_STOP (parse, ebml, "TrackAudio", ret);
835 /* codec identifier */
836 case GST_MATROSKA_ID_CODECID:{
839 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
842 GST_DEBUG_OBJECT (parse, "CodecID: %s", GST_STR_NULL (text));
843 context->codec_id = text;
847 /* codec private data */
848 case GST_MATROSKA_ID_CODECPRIVATE:{
853 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
856 context->codec_priv = data;
857 context->codec_priv_size = size;
859 GST_DEBUG_OBJECT (parse, "CodecPrivate of size %" G_GUINT64_FORMAT,
864 /* name of the codec */
865 case GST_MATROSKA_ID_CODECNAME:{
868 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
871 GST_DEBUG_OBJECT (parse, "CodecName: %s", GST_STR_NULL (text));
872 context->codec_name = text;
876 /* name of this track */
877 case GST_MATROSKA_ID_TRACKNAME:{
880 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
883 context->name = text;
884 GST_DEBUG_OBJECT (parse, "TrackName: %s", GST_STR_NULL (text));
888 /* language (matters for audio/subtitles, mostly) */
889 case GST_MATROSKA_ID_TRACKLANGUAGE:{
892 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
896 context->language = text;
899 if (strlen (context->language) >= 4 && context->language[3] == '-')
900 context->language[3] = '\0';
902 GST_DEBUG_OBJECT (parse, "TrackLanguage: %s",
903 GST_STR_NULL (context->language));
907 /* whether this is actually used */
908 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
911 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
915 context->flags |= GST_MATROSKA_TRACK_ENABLED;
917 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
919 GST_DEBUG_OBJECT (parse, "TrackEnabled: %d",
920 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
924 /* whether it's the default for this track type */
925 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
928 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
932 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
934 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
936 GST_DEBUG_OBJECT (parse, "TrackDefault: %d",
937 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
941 /* whether the track must be used during playback */
942 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
945 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
949 context->flags |= GST_MATROSKA_TRACK_FORCED;
951 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
953 GST_DEBUG_OBJECT (parse, "TrackForced: %d",
954 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
958 /* lacing (like MPEG, where blocks don't end/start on frame
960 case GST_MATROSKA_ID_TRACKFLAGLACING:{
963 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
967 context->flags |= GST_MATROSKA_TRACK_LACING;
969 context->flags &= ~GST_MATROSKA_TRACK_LACING;
971 GST_DEBUG_OBJECT (parse, "TrackLacing: %d",
972 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
976 /* default length (in time) of one data block in this track */
977 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
980 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
985 GST_WARNING_OBJECT (parse, "Invalid TrackDefaultDuration 0");
989 GST_DEBUG_OBJECT (parse, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
991 context->default_duration = num;
995 case GST_MATROSKA_ID_CONTENTENCODINGS:{
996 ret = gst_matroska_read_common_read_track_encodings (&parse->common,
1001 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1004 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1008 GST_WARNING_OBJECT (parse, "Invalid TrackTimeCodeScale %lf", num);
1012 GST_DEBUG_OBJECT (parse, "TrackTimeCodeScale: %lf", num);
1013 context->timecodescale = num;
1018 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1021 /* we ignore these because they're nothing useful (i.e. crap)
1022 * or simply not implemented yet. */
1023 case GST_MATROSKA_ID_TRACKMINCACHE:
1024 case GST_MATROSKA_ID_TRACKMAXCACHE:
1025 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1026 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1027 case GST_MATROSKA_ID_TRACKOVERLAY:
1028 case GST_MATROSKA_ID_TRACKTRANSLATE:
1029 case GST_MATROSKA_ID_TRACKOFFSET:
1030 case GST_MATROSKA_ID_CODECSETTINGS:
1031 case GST_MATROSKA_ID_CODECINFOURL:
1032 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1033 case GST_MATROSKA_ID_CODECDECODEALL:
1034 ret = gst_ebml_read_skip (ebml);
1039 DEBUG_ELEMENT_STOP (parse, ebml, "TrackEntry", ret);
1041 /* Decode codec private data if necessary */
1042 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1043 && context->codec_priv_size > 0) {
1044 if (!gst_matroska_decode_data (context->encodings,
1045 &context->codec_priv, &context->codec_priv_size,
1046 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1047 GST_WARNING_OBJECT (parse, "Decoding codec private data failed");
1048 ret = GST_FLOW_ERROR;
1052 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1053 && ret != GST_FLOW_UNEXPECTED)) {
1054 if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
1055 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1057 parse->common.num_streams--;
1058 g_ptr_array_remove_index (parse->common.src, parse->common.num_streams);
1059 g_assert (parse->common.src->len == parse->common.num_streams);
1061 gst_matroska_track_free (context);
1067 if ((context->language == NULL || *context->language == '\0') &&
1068 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1069 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1070 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1071 context->language = g_strdup ("eng");
1079 static const GstQueryType *
1080 gst_matroska_parse_get_src_query_types (GstPad * pad)
1082 static const GstQueryType query_types[] = {
1093 gst_matroska_parse_query (GstMatroskaParse * parse, GstPad * pad,
1096 gboolean res = FALSE;
1097 GstMatroskaTrackContext *context = NULL;
1100 context = gst_pad_get_element_private (pad);
1103 switch (GST_QUERY_TYPE (query)) {
1104 case GST_QUERY_POSITION:
1108 gst_query_parse_position (query, &format, NULL);
1110 if (format == GST_FORMAT_TIME) {
1111 GST_OBJECT_LOCK (parse);
1113 gst_query_set_position (query, GST_FORMAT_TIME, context->pos);
1115 gst_query_set_position (query, GST_FORMAT_TIME,
1116 parse->common.segment.last_stop);
1117 GST_OBJECT_UNLOCK (parse);
1118 } else if (format == GST_FORMAT_DEFAULT && context
1119 && context->default_duration) {
1120 GST_OBJECT_LOCK (parse);
1121 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1122 context->pos / context->default_duration);
1123 GST_OBJECT_UNLOCK (parse);
1125 GST_DEBUG_OBJECT (parse,
1126 "only position query in TIME and DEFAULT format is supported");
1132 case GST_QUERY_DURATION:
1136 gst_query_parse_duration (query, &format, NULL);
1138 if (format == GST_FORMAT_TIME) {
1139 GST_OBJECT_LOCK (parse);
1140 gst_query_set_duration (query, GST_FORMAT_TIME,
1141 parse->common.segment.duration);
1142 GST_OBJECT_UNLOCK (parse);
1143 } else if (format == GST_FORMAT_DEFAULT && context
1144 && context->default_duration) {
1145 GST_OBJECT_LOCK (parse);
1146 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1147 parse->common.segment.duration / context->default_duration);
1148 GST_OBJECT_UNLOCK (parse);
1150 GST_DEBUG_OBJECT (parse,
1151 "only duration query in TIME and DEFAULT format is supported");
1158 case GST_QUERY_SEEKING:
1162 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1163 if (fmt == GST_FORMAT_TIME) {
1166 /* assuming we'll be able to get an index ... */
1167 seekable = parse->seekable;
1169 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1170 0, parse->common.segment.duration);
1176 res = gst_pad_query_default (pad, query);
1184 gst_matroska_parse_element_query (GstElement * element, GstQuery * query)
1186 return gst_matroska_parse_query (GST_MATROSKA_PARSE (element), NULL, query);
1190 gst_matroska_parse_handle_src_query (GstPad * pad, GstQuery * query)
1193 GstMatroskaParse *parse = GST_MATROSKA_PARSE (gst_pad_get_parent (pad));
1195 ret = gst_matroska_parse_query (parse, pad, query);
1197 gst_object_unref (parse);
1202 /* returns FALSE if there are no pads to deliver event to,
1203 * otherwise TRUE (whatever the outcome of event sending),
1204 * takes ownership of the passed event! */
1206 gst_matroska_parse_send_event (GstMatroskaParse * parse, GstEvent * event)
1208 gboolean ret = FALSE;
1210 g_return_val_if_fail (event != NULL, FALSE);
1212 GST_DEBUG_OBJECT (parse, "Sending event of type %s to all source pads",
1213 GST_EVENT_TYPE_NAME (event));
1215 gst_pad_push_event (parse->srcpad, event);
1221 gst_matroska_parse_element_send_event (GstElement * element, GstEvent * event)
1223 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
1226 g_return_val_if_fail (event != NULL, FALSE);
1228 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1229 res = gst_matroska_parse_handle_seek_event (parse, NULL, event);
1231 GST_WARNING_OBJECT (parse, "Unhandled event of type %s",
1232 GST_EVENT_TYPE_NAME (event));
1235 gst_event_unref (event);
1239 /* searches for a cluster start from @pos,
1240 * return GST_FLOW_OK and cluster position in @pos if found */
1241 static GstFlowReturn
1242 gst_matroska_parse_search_cluster (GstMatroskaParse * parse, gint64 * pos)
1244 gint64 newpos = *pos;
1246 GstFlowReturn ret = GST_FLOW_OK;
1247 const guint chunk = 64 * 1024;
1248 GstBuffer *buf = NULL;
1253 orig_offset = parse->common.offset;
1255 /* read in at newpos and scan for ebml cluster id */
1257 GstByteReader reader;
1260 ret = gst_pad_pull_range (parse->common.sinkpad, newpos, chunk, &buf);
1261 if (ret != GST_FLOW_OK)
1263 GST_DEBUG_OBJECT (parse, "read buffer size %d at offset %" G_GINT64_FORMAT,
1264 GST_BUFFER_SIZE (buf), newpos);
1265 gst_byte_reader_init_from_buffer (&reader, buf);
1268 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1269 GST_MATROSKA_ID_CLUSTER, cluster_pos,
1270 GST_BUFFER_SIZE (buf) - cluster_pos);
1271 if (cluster_pos >= 0) {
1272 newpos += cluster_pos;
1273 GST_DEBUG_OBJECT (parse,
1274 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1275 /* extra checks whether we really sync'ed to a cluster:
1276 * - either it is the first and only cluster
1277 * - either there is a cluster after this one
1278 * - either cluster length is undefined
1280 /* ok if first cluster (there may not a subsequent one) */
1281 if (newpos == parse->first_cluster_offset) {
1282 GST_DEBUG_OBJECT (parse, "cluster is first cluster -> OK");
1285 parse->common.offset = newpos;
1286 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1287 GST_ELEMENT_CAST (parse), &id, &length, &needed);
1288 if (ret != GST_FLOW_OK)
1290 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1291 GST_DEBUG_OBJECT (parse, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1293 /* ok if undefined length or first cluster */
1294 if (length == G_MAXUINT64) {
1295 GST_DEBUG_OBJECT (parse, "cluster has undefined length -> OK");
1299 parse->common.offset += length + needed;
1300 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1301 GST_ELEMENT_CAST (parse), &id, &length, &needed);
1302 if (ret != GST_FLOW_OK)
1304 GST_DEBUG_OBJECT (parse, "next element is %scluster",
1305 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1306 if (id == GST_MATROSKA_ID_CLUSTER)
1308 /* not ok, resume */
1311 /* partial cluster id may have been in tail of buffer */
1312 newpos += MAX (GST_BUFFER_SIZE (buf), 4) - 3;
1313 gst_buffer_unref (buf);
1319 gst_buffer_unref (buf);
1323 parse->common.offset = orig_offset;
1330 gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
1331 GstPad * pad, GstEvent * event)
1333 GstMatroskaIndex *entry = NULL;
1335 GstSeekType cur_type, stop_type;
1339 GstMatroskaTrackContext *track = NULL;
1340 GstSegment seeksegment = { 0, };
1344 track = gst_pad_get_element_private (pad);
1346 track = gst_matroska_read_common_get_seek_track (&parse->common, track);
1348 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1351 /* we can only seek on time */
1352 if (format != GST_FORMAT_TIME) {
1353 GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1357 /* copy segment, we need this because we still need the old
1358 * segment when we close the current segment. */
1359 memcpy (&seeksegment, &parse->common.segment, sizeof (GstSegment));
1362 GST_DEBUG_OBJECT (parse, "configuring seek");
1363 gst_segment_set_seek (&seeksegment, rate, format, flags,
1364 cur_type, cur, stop_type, stop, &update);
1367 GST_DEBUG_OBJECT (parse, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1369 /* check sanity before we start flushing and all that */
1370 GST_OBJECT_LOCK (parse);
1371 if ((entry = gst_matroska_read_common_do_index_seek (&parse->common, track,
1372 seeksegment.last_stop, &parse->seek_index, &parse->seek_entry)) ==
1374 /* pull mode without index can scan later on */
1375 GST_DEBUG_OBJECT (parse, "No matching seek entry in index");
1376 GST_OBJECT_UNLOCK (parse);
1379 GST_DEBUG_OBJECT (parse, "Seek position looks sane");
1380 GST_OBJECT_UNLOCK (parse);
1382 /* need to seek to cluster start to pick up cluster time */
1383 /* upstream takes care of flushing and all that
1384 * ... and newsegment event handling takes care of the rest */
1385 return perform_seek_to_offset (parse, entry->pos
1386 + parse->common.ebml_segment_start);
1390 * Handle whether we can perform the seek event or if we have to let the chain
1391 * function handle seeks to build the seek indexes first.
1394 gst_matroska_parse_handle_seek_push (GstMatroskaParse * parse, GstPad * pad,
1398 GstSeekType cur_type, stop_type;
1403 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1408 /* we can only seek on time */
1409 if (format != GST_FORMAT_TIME) {
1410 GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1414 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
1415 GST_DEBUG_OBJECT (parse, "Seek end-time not supported in streaming mode");
1419 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
1420 GST_DEBUG_OBJECT (parse,
1421 "Non-flushing seek not supported in streaming mode");
1425 if (flags & GST_SEEK_FLAG_SEGMENT) {
1426 GST_DEBUG_OBJECT (parse, "Segment seek not supported in streaming mode");
1430 /* check for having parsed index already */
1431 if (!parse->common.index_parsed) {
1432 gboolean building_index;
1435 if (!parse->index_offset) {
1436 GST_DEBUG_OBJECT (parse, "no index (location); no seek in push mode");
1440 GST_OBJECT_LOCK (parse);
1441 /* handle the seek event in the chain function */
1442 parse->common.state = GST_MATROSKA_READ_STATE_SEEK;
1443 /* no more seek can be issued until state reset to _DATA */
1445 /* copy the event */
1446 if (parse->seek_event)
1447 gst_event_unref (parse->seek_event);
1448 parse->seek_event = gst_event_ref (event);
1450 /* set the building_index flag so that only one thread can setup the
1451 * structures for index seeking. */
1452 building_index = parse->building_index;
1453 if (!building_index) {
1454 parse->building_index = TRUE;
1455 offset = parse->index_offset;
1457 GST_OBJECT_UNLOCK (parse);
1459 if (!building_index) {
1460 /* seek to the first subindex or legacy index */
1461 GST_INFO_OBJECT (parse, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
1462 return perform_seek_to_offset (parse, offset);
1465 /* well, we are handling it already */
1469 /* delegate to tweaked regular seek */
1470 return gst_matroska_parse_handle_seek_event (parse, pad, event);
1474 gst_matroska_parse_handle_src_event (GstPad * pad, GstEvent * event)
1476 GstMatroskaParse *parse = GST_MATROSKA_PARSE (gst_pad_get_parent (pad));
1477 gboolean res = TRUE;
1479 switch (GST_EVENT_TYPE (event)) {
1480 case GST_EVENT_SEEK:
1481 /* no seeking until we are (safely) ready */
1482 if (parse->common.state != GST_MATROSKA_READ_STATE_DATA) {
1483 GST_DEBUG_OBJECT (parse, "not ready for seeking yet");
1486 res = gst_matroska_parse_handle_seek_push (parse, pad, event);
1487 gst_event_unref (event);
1492 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
1493 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
1494 GstMatroskaTrackVideoContext *videocontext =
1495 (GstMatroskaTrackVideoContext *) context;
1497 GstClockTimeDiff diff;
1498 GstClockTime timestamp;
1500 gst_event_parse_qos (event, &proportion, &diff, ×tamp);
1502 GST_OBJECT_LOCK (parse);
1503 videocontext->earliest_time = timestamp + diff;
1504 GST_OBJECT_UNLOCK (parse);
1507 gst_event_unref (event);
1511 /* events we don't need to handle */
1512 case GST_EVENT_NAVIGATION:
1513 gst_event_unref (event);
1517 case GST_EVENT_LATENCY:
1519 res = gst_pad_push_event (parse->common.sinkpad, event);
1523 gst_object_unref (parse);
1528 static GstFlowReturn
1529 gst_matroska_parse_parse_tracks (GstMatroskaParse * parse, GstEbmlRead * ebml)
1531 GstFlowReturn ret = GST_FLOW_OK;
1534 DEBUG_ELEMENT_START (parse, ebml, "Tracks");
1536 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1537 DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1541 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1542 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1546 /* one track within the "all-tracks" header */
1547 case GST_MATROSKA_ID_TRACKENTRY:
1548 ret = gst_matroska_parse_add_stream (parse, ebml);
1552 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1557 DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1559 parse->tracks_parsed = TRUE;
1565 * Read signed/unsigned "EBML" numbers.
1566 * Return: number of bytes processed.
1570 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
1572 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
1580 while (read <= 8 && !(total & len_mask)) {
1587 if ((total &= (len_mask - 1)) == len_mask - 1)
1592 if (data[n] == 0xff)
1594 total = (total << 8) | data[n];
1598 if (read == num_ffs && total != 0)
1607 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
1612 /* read as unsigned number first */
1613 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
1617 if (unum == G_MAXUINT64)
1620 *num = unum - ((1 << ((7 * res) - 1)) - 1);
1625 static GstFlowReturn
1626 gst_matroska_parse_parse_blockgroup_or_simpleblock (GstMatroskaParse * parse,
1627 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
1628 gboolean is_simpleblock)
1630 GstMatroskaTrackContext *stream = NULL;
1631 GstFlowReturn ret = GST_FLOW_OK;
1632 gboolean readblock = FALSE;
1634 guint64 block_duration = 0;
1635 GstBuffer *buf = NULL;
1636 gint stream_num = -1, n, laces = 0;
1638 gint *lace_size = NULL;
1641 gint64 referenceblock = 0;
1643 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1644 if (!is_simpleblock) {
1645 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
1649 id = GST_MATROSKA_ID_SIMPLEBLOCK;
1653 /* one block inside the group. Note, block parsing is one
1654 * of the harder things, so this code is a bit complicated.
1655 * See http://www.matroska.org/ for documentation. */
1656 case GST_MATROSKA_ID_SIMPLEBLOCK:
1657 case GST_MATROSKA_ID_BLOCK:
1663 gst_buffer_unref (buf);
1666 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
1669 data = GST_BUFFER_DATA (buf);
1670 size = GST_BUFFER_SIZE (buf);
1672 /* first byte(s): blocknum */
1673 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1678 /* fetch stream from num */
1679 stream_num = gst_matroska_read_common_stream_from_num (&parse->common,
1681 if (G_UNLIKELY (size < 3)) {
1682 GST_WARNING_OBJECT (parse, "Invalid size %u", size);
1683 /* non-fatal, try next block(group) */
1686 } else if (G_UNLIKELY (stream_num < 0 ||
1687 stream_num >= parse->common.num_streams)) {
1688 /* let's not give up on a stray invalid track number */
1689 GST_WARNING_OBJECT (parse,
1690 "Invalid stream %d for track number %" G_GUINT64_FORMAT
1691 "; ignoring block", stream_num, num);
1695 stream = g_ptr_array_index (parse->common.src, stream_num);
1697 /* time (relative to cluster time) */
1698 time = ((gint16) GST_READ_UINT16_BE (data));
1701 flags = GST_READ_UINT8 (data);
1705 GST_LOG_OBJECT (parse, "time %" G_GUINT64_FORMAT ", flags %d", time,
1708 switch ((flags & 0x06) >> 1) {
1709 case 0x0: /* no lacing */
1711 lace_size = g_new (gint, 1);
1712 lace_size[0] = size;
1715 case 0x1: /* xiph lacing */
1716 case 0x2: /* fixed-size lacing */
1717 case 0x3: /* EBML lacing */
1719 goto invalid_lacing;
1720 laces = GST_READ_UINT8 (data) + 1;
1723 lace_size = g_new0 (gint, laces);
1725 switch ((flags & 0x06) >> 1) {
1726 case 0x1: /* xiph lacing */ {
1727 guint temp, total = 0;
1729 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
1732 goto invalid_lacing;
1733 temp = GST_READ_UINT8 (data);
1734 lace_size[n] += temp;
1740 total += lace_size[n];
1742 lace_size[n] = size - total;
1746 case 0x2: /* fixed-size lacing */
1747 for (n = 0; n < laces; n++)
1748 lace_size[n] = size / laces;
1751 case 0x3: /* EBML lacing */ {
1754 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1758 total = lace_size[0] = num;
1759 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
1763 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
1767 lace_size[n] = lace_size[n - 1] + snum;
1768 total += lace_size[n];
1771 lace_size[n] = size - total;
1778 if (ret != GST_FLOW_OK)
1785 case GST_MATROSKA_ID_BLOCKDURATION:{
1786 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
1787 GST_DEBUG_OBJECT (parse, "BlockDuration: %" G_GUINT64_FORMAT,
1792 case GST_MATROSKA_ID_REFERENCEBLOCK:{
1793 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
1794 GST_DEBUG_OBJECT (parse, "ReferenceBlock: %" G_GINT64_FORMAT,
1799 case GST_MATROSKA_ID_CODECSTATE:{
1801 guint64 data_len = 0;
1804 gst_ebml_read_binary (ebml, &id, &data,
1805 &data_len)) != GST_FLOW_OK)
1808 if (G_UNLIKELY (stream == NULL)) {
1809 GST_WARNING_OBJECT (parse,
1810 "Unexpected CodecState subelement - ignoring");
1814 g_free (stream->codec_state);
1815 stream->codec_state = data;
1816 stream->codec_state_size = data_len;
1822 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1826 case GST_MATROSKA_ID_BLOCKVIRTUAL:
1827 case GST_MATROSKA_ID_BLOCKADDITIONS:
1828 case GST_MATROSKA_ID_REFERENCEPRIORITY:
1829 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
1830 case GST_MATROSKA_ID_SLICES:
1831 GST_DEBUG_OBJECT (parse,
1832 "Skipping BlockGroup subelement 0x%x - ignoring", id);
1833 ret = gst_ebml_read_skip (ebml);
1841 /* reading a number or so could have failed */
1842 if (ret != GST_FLOW_OK)
1845 if (ret == GST_FLOW_OK && readblock) {
1846 guint64 duration = 0;
1847 gint64 lace_time = 0;
1848 gboolean delta_unit;
1850 stream = g_ptr_array_index (parse->common.src, stream_num);
1852 if (cluster_time != GST_CLOCK_TIME_NONE) {
1853 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
1854 * Drop unless the lace contains timestamp 0? */
1855 if (time < 0 && (-time) > cluster_time) {
1858 if (stream->timecodescale == 1.0)
1859 lace_time = (cluster_time + time) * parse->common.time_scale;
1862 gst_util_guint64_to_gdouble ((cluster_time + time) *
1863 parse->common.time_scale) * stream->timecodescale;
1866 lace_time = GST_CLOCK_TIME_NONE;
1869 if (lace_time != GST_CLOCK_TIME_NONE) {
1870 parse->last_timestamp = lace_time;
1872 /* need to refresh segment info ASAP */
1873 if (GST_CLOCK_TIME_IS_VALID (lace_time) && parse->need_newsegment) {
1874 GST_DEBUG_OBJECT (parse,
1875 "generating segment starting at %" GST_TIME_FORMAT,
1876 GST_TIME_ARGS (lace_time));
1877 /* pretend we seeked here */
1878 gst_segment_set_seek (&parse->common.segment, parse->common.segment.rate,
1879 GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, lace_time,
1880 GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE, NULL);
1881 /* now convey our segment notion downstream */
1882 gst_matroska_parse_send_event (parse, gst_event_new_new_segment (FALSE,
1883 parse->common.segment.rate, parse->common.segment.format,
1884 parse->common.segment.start, parse->common.segment.stop,
1885 parse->common.segment.start));
1886 parse->need_newsegment = FALSE;
1889 if (block_duration) {
1890 if (stream->timecodescale == 1.0)
1891 duration = gst_util_uint64_scale (block_duration,
1892 parse->common.time_scale, 1);
1895 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
1896 (gst_util_uint64_scale (block_duration, parse->common.time_scale,
1897 1)) * stream->timecodescale);
1898 } else if (stream->default_duration) {
1899 duration = stream->default_duration * laces;
1901 /* else duration is diff between timecode of this and next block */
1903 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
1904 a ReferenceBlock implies that this is not a keyframe. In either
1905 case, it only makes sense for video streams. */
1906 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1907 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
1909 if (delta_unit && stream->set_discont) {
1910 /* When doing seeks or such, we need to restart on key frames or
1911 * decoders might choke. */
1912 GST_DEBUG_OBJECT (parse, "skipping delta unit");
1916 for (n = 0; n < laces; n++) {
1917 if (G_UNLIKELY (lace_size[n] > size)) {
1918 GST_WARNING_OBJECT (parse, "Invalid lace size");
1922 /* QoS for video track with an index. the assumption is that
1923 index entries point to keyframes, but if that is not true we
1924 will instad skip until the next keyframe. */
1925 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1926 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1927 stream->index_table && parse->common.segment.rate > 0.0) {
1928 GstMatroskaTrackVideoContext *videocontext =
1929 (GstMatroskaTrackVideoContext *) stream;
1930 GstClockTime earliest_time;
1931 GstClockTime earliest_stream_time;
1933 GST_OBJECT_LOCK (parse);
1934 earliest_time = videocontext->earliest_time;
1935 GST_OBJECT_UNLOCK (parse);
1936 earliest_stream_time = gst_segment_to_position (&parse->common.segment,
1937 GST_FORMAT_TIME, earliest_time);
1939 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1940 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
1941 lace_time <= earliest_stream_time) {
1942 /* find index entry (keyframe) <= earliest_stream_time */
1943 GstMatroskaIndex *entry =
1944 gst_util_array_binary_search (stream->index_table->data,
1945 stream->index_table->len, sizeof (GstMatroskaIndex),
1946 (GCompareDataFunc) gst_matroska_index_seek_find,
1947 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
1949 /* if that entry (keyframe) is after the current the current
1950 buffer, we can skip pushing (and thus decoding) all
1951 buffers until that keyframe. */
1952 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
1953 entry->time > lace_time) {
1954 GST_LOG_OBJECT (parse, "Skipping lace before late keyframe");
1955 stream->set_discont = TRUE;
1961 sub = gst_buffer_create_sub (buf,
1962 GST_BUFFER_SIZE (buf) - size, lace_size[n]);
1963 GST_DEBUG_OBJECT (parse, "created subbuffer %p", sub);
1966 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1968 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1970 if (stream->encodings != NULL && stream->encodings->len > 0)
1971 sub = gst_matroska_decode_buffer (stream, sub);
1974 GST_WARNING_OBJECT (parse, "Decoding buffer failed");
1978 GST_BUFFER_TIMESTAMP (sub) = lace_time;
1980 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
1981 GstClockTime last_stop_end;
1983 /* Check if this stream is after segment stop */
1984 if (GST_CLOCK_TIME_IS_VALID (parse->common.segment.stop) &&
1985 lace_time >= parse->common.segment.stop) {
1986 GST_DEBUG_OBJECT (parse,
1987 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
1988 GST_TIME_ARGS (parse->common.segment.stop));
1989 gst_buffer_unref (sub);
1992 if (offset >= stream->to_offset) {
1993 GST_DEBUG_OBJECT (parse, "Stream %d after playback section",
1995 gst_buffer_unref (sub);
1999 /* handle gaps, e.g. non-zero start-time, or an cue index entry
2000 * that landed us with timestamps not quite intended */
2001 if (GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop) &&
2002 parse->segment.rate > 0.0) {
2003 GstClockTimeDiff diff;
2005 /* only send newsegments with increasing start times,
2006 * otherwise if these go back and forth downstream (sinks) increase
2007 * accumulated time and running_time */
2008 diff = GST_CLOCK_DIFF (parse->segment.last_stop, lace_time);
2009 if (diff > 2 * GST_SECOND && lace_time > parse->segment.start &&
2010 (!GST_CLOCK_TIME_IS_VALID (parse->segment.stop) ||
2011 lace_time < parse->segment.stop)) {
2012 GST_DEBUG_OBJECT (parse,
2013 "Gap of %" G_GINT64_FORMAT " ns detected in"
2014 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
2015 "Sending updated NEWSEGMENT events", diff,
2016 stream->index, GST_TIME_ARGS (stream->pos),
2017 GST_TIME_ARGS (lace_time));
2018 /* send newsegment events such that the gap is not accounted in
2019 * accum time, hence running_time */
2020 /* close ahead of gap */
2021 gst_matroska_parse_send_event (parse,
2022 gst_event_new_new_segment (TRUE, parse->segment.rate,
2023 parse->segment.format, parse->segment.last_stop,
2024 parse->segment.last_stop, parse->segment.last_stop));
2026 gst_matroska_parse_send_event (parse,
2027 gst_event_new_new_segment (FALSE, parse->segment.rate,
2028 parse->segment.format, lace_time, parse->segment.stop,
2030 /* align segment view with downstream,
2031 * prevents double-counting accum when closing segment */
2032 gst_segment_set_newsegment (&parse->segment, FALSE,
2033 parse->segment.rate, parse->segment.format, lace_time,
2034 parse->segment.stop, lace_time);
2035 parse->segment.last_stop = lace_time;
2039 if (!GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop)
2040 || parse->segment.last_stop < lace_time) {
2041 parse->segment.last_stop = lace_time;
2044 last_stop_end = lace_time;
2046 GST_BUFFER_DURATION (sub) = duration / laces;
2047 last_stop_end += GST_BUFFER_DURATION (sub);
2050 if (!GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) ||
2051 parse->last_stop_end < last_stop_end)
2052 parse->last_stop_end = last_stop_end;
2054 if (parse->segment.duration == -1 ||
2055 parse->segment.duration < lace_time) {
2056 gst_segment_set_duration (&parse->segment, GST_FORMAT_TIME,
2058 gst_element_post_message (GST_ELEMENT_CAST (parse),
2059 gst_message_new_duration (GST_OBJECT_CAST (parse),
2060 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
2064 stream->pos = lace_time;
2066 gst_matroska_parse_sync_streams (parse);
2068 if (stream->set_discont) {
2069 GST_DEBUG_OBJECT (parse, "marking DISCONT");
2070 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
2071 stream->set_discont = FALSE;
2074 /* reverse playback book-keeping */
2075 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
2076 stream->from_time = lace_time;
2077 if (stream->from_offset == -1)
2078 stream->from_offset = offset;
2080 GST_DEBUG_OBJECT (parse,
2081 "Pushing lace %d, data of size %d for stream %d, time=%"
2082 GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
2083 GST_BUFFER_SIZE (sub), stream_num,
2084 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
2085 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
2087 if (parse->element_index) {
2088 if (stream->index_writer_id == -1)
2089 gst_index_get_writer_id (parse->element_index,
2090 GST_OBJECT (stream->pad), &stream->index_writer_id);
2092 GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
2093 G_GUINT64_FORMAT " for writer id %d",
2094 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
2095 stream->index_writer_id);
2096 gst_index_add_association (parse->element_index,
2097 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
2098 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
2099 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
2100 cluster_offset, NULL);
2103 gst_buffer_set_caps (sub, GST_PAD_CAPS (parse->srcpad));
2105 /* Postprocess the buffers depending on the codec used */
2106 if (stream->postprocess_frame) {
2107 GST_LOG_OBJECT (parse, "running post process");
2108 ret = stream->postprocess_frame (GST_ELEMENT (parse), stream, &sub);
2111 ret = gst_pad_push (stream->pad, sub);
2112 if (parse->segment.rate < 0) {
2113 if (lace_time > parse->segment.stop && ret == GST_FLOW_UNEXPECTED) {
2114 /* In reverse playback we can get a GST_FLOW_UNEXPECTED when
2115 * we are at the end of the segment, so we just need to jump
2116 * back to the previous section. */
2117 GST_DEBUG_OBJECT (parse, "downstream has reached end of segment");
2122 ret = gst_matroska_parse_combine_flows (parse, stream, ret);
2126 size -= lace_size[n];
2127 if (lace_time != GST_CLOCK_TIME_NONE && duration)
2128 lace_time += duration / laces;
2130 lace_time = GST_CLOCK_TIME_NONE;
2136 gst_buffer_unref (buf);
2144 GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
2145 /* non-fatal, try next block(group) */
2151 GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Data error"));
2152 /* non-fatal, try next block(group) */
2158 /* return FALSE if block(group) should be skipped (due to a seek) */
2159 static inline gboolean
2160 gst_matroska_parse_seek_block (GstMatroskaParse * parse)
2162 if (G_UNLIKELY (parse->seek_block)) {
2163 if (!(--parse->seek_block)) {
2166 GST_LOG_OBJECT (parse, "should skip block due to seek");
2174 static GstFlowReturn
2175 gst_matroska_parse_parse_contents_seekentry (GstMatroskaParse * parse,
2179 guint64 seek_pos = (guint64) - 1;
2180 guint32 seek_id = 0;
2183 DEBUG_ELEMENT_START (parse, ebml, "Seek");
2185 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2186 DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2190 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2191 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2195 case GST_MATROSKA_ID_SEEKID:
2199 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2202 GST_DEBUG_OBJECT (parse, "SeekID: %" G_GUINT64_FORMAT, t);
2207 case GST_MATROSKA_ID_SEEKPOSITION:
2211 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2214 if (t > G_MAXINT64) {
2215 GST_WARNING_OBJECT (parse,
2216 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
2220 GST_DEBUG_OBJECT (parse, "SeekPosition: %" G_GUINT64_FORMAT, t);
2226 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2232 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
2235 if (!seek_id || seek_pos == (guint64) - 1) {
2236 GST_WARNING_OBJECT (parse, "Incomplete seekhead entry (0x%x/%"
2237 G_GUINT64_FORMAT ")", seek_id, seek_pos);
2242 case GST_MATROSKA_ID_SEEKHEAD:
2245 case GST_MATROSKA_ID_CUES:
2246 case GST_MATROSKA_ID_TAGS:
2247 case GST_MATROSKA_ID_TRACKS:
2248 case GST_MATROSKA_ID_SEGMENTINFO:
2249 case GST_MATROSKA_ID_ATTACHMENTS:
2250 case GST_MATROSKA_ID_CHAPTERS:
2255 length = gst_matroska_read_common_get_length (&parse->common);
2257 if (length == (guint64) - 1) {
2258 GST_DEBUG_OBJECT (parse, "no upstream length, skipping SeakHead entry");
2262 /* check for validity */
2263 if (seek_pos + parse->common.ebml_segment_start + 12 >= length) {
2264 GST_WARNING_OBJECT (parse,
2265 "SeekHead reference lies outside file!" " (%"
2266 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
2267 G_GUINT64_FORMAT ")", seek_pos, parse->common.ebml_segment_start,
2272 /* only pick up index location when streaming */
2273 if (seek_id == GST_MATROSKA_ID_CUES) {
2274 parse->index_offset = seek_pos + parse->common.ebml_segment_start;
2275 GST_DEBUG_OBJECT (parse, "Cues located at offset %" G_GUINT64_FORMAT,
2276 parse->index_offset);
2282 GST_DEBUG_OBJECT (parse, "Ignoring Seek entry for ID=0x%x", seek_id);
2285 DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2290 static GstFlowReturn
2291 gst_matroska_parse_parse_contents (GstMatroskaParse * parse, GstEbmlRead * ebml)
2293 GstFlowReturn ret = GST_FLOW_OK;
2296 DEBUG_ELEMENT_START (parse, ebml, "SeekHead");
2298 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2299 DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2303 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2304 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2308 case GST_MATROSKA_ID_SEEKENTRY:
2310 ret = gst_matroska_parse_parse_contents_seekentry (parse, ebml);
2311 /* Ignore EOS and errors here */
2312 if (ret != GST_FLOW_OK) {
2313 GST_DEBUG_OBJECT (parse, "Ignoring %s", gst_flow_get_name (ret));
2320 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2326 DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2331 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
2333 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
2335 static inline GstFlowReturn
2336 gst_matroska_parse_check_read_size (GstMatroskaParse * parse, guint64 bytes)
2338 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
2339 /* only a few blocks are expected/allowed to be large,
2340 * and will be recursed into, whereas others will be read and must fit */
2341 /* fatal in streaming case, as we can't step over easily */
2342 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2343 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
2344 "file might be corrupt.", bytes));
2345 return GST_FLOW_ERROR;
2351 /* returns TRUE if we truely are in error state, and should give up */
2352 static inline gboolean
2353 gst_matroska_parse_check_parse_error (GstMatroskaParse * parse)
2357 /* sigh, one last attempt above and beyond call of duty ...;
2358 * search for cluster mark following current pos */
2359 pos = parse->common.offset;
2360 GST_WARNING_OBJECT (parse, "parse error, looking for next cluster");
2361 if (gst_matroska_parse_search_cluster (parse, &pos) != GST_FLOW_OK) {
2362 /* did not work, give up */
2365 GST_DEBUG_OBJECT (parse, "... found at %" G_GUINT64_FORMAT, pos);
2366 /* try that position */
2367 parse->common.offset = pos;
2372 /* initializes @ebml with @bytes from input stream at current offset.
2373 * Returns UNEXPECTED if insufficient available,
2374 * ERROR if too much was attempted to read. */
2375 static inline GstFlowReturn
2376 gst_matroska_parse_take (GstMatroskaParse * parse, guint64 bytes,
2379 GstBuffer *buffer = NULL;
2380 GstFlowReturn ret = GST_FLOW_OK;
2382 GST_LOG_OBJECT (parse, "taking %" G_GUINT64_FORMAT " bytes for parsing",
2384 ret = gst_matroska_parse_check_read_size (parse, bytes);
2385 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
2386 /* otherwise fatal */
2387 ret = GST_FLOW_ERROR;
2390 if (gst_adapter_available (parse->common.adapter) >= bytes)
2391 buffer = gst_adapter_take_buffer (parse->common.adapter, bytes);
2393 ret = GST_FLOW_UNEXPECTED;
2394 if (G_LIKELY (buffer)) {
2395 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (parse), buffer,
2396 parse->common.offset);
2397 parse->common.offset += bytes;
2404 gst_matroska_parse_check_seekability (GstMatroskaParse * parse)
2407 gboolean seekable = FALSE;
2408 gint64 start = -1, stop = -1;
2410 query = gst_query_new_seeking (GST_FORMAT_BYTES);
2411 if (!gst_pad_peer_query (parse->common.sinkpad, query)) {
2412 GST_DEBUG_OBJECT (parse, "seeking query failed");
2416 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
2418 /* try harder to query upstream size if we didn't get it the first time */
2419 if (seekable && stop == -1) {
2420 GstFormat fmt = GST_FORMAT_BYTES;
2422 GST_DEBUG_OBJECT (parse, "doing duration query to fix up unset stop");
2423 gst_pad_query_peer_duration (parse->common.sinkpad, &fmt, &stop);
2426 /* if upstream doesn't know the size, it's likely that it's not seekable in
2427 * practice even if it technically may be seekable */
2428 if (seekable && (start != 0 || stop <= start)) {
2429 GST_DEBUG_OBJECT (parse, "seekable but unknown start/stop -> disable");
2434 GST_INFO_OBJECT (parse, "seekable: %d (%" G_GUINT64_FORMAT " - %"
2435 G_GUINT64_FORMAT ")", seekable, start, stop);
2436 parse->seekable = seekable;
2438 gst_query_unref (query);
2442 static GstFlowReturn
2443 gst_matroska_parse_find_tracks (GstMatroskaParse * parse)
2449 GstFlowReturn ret = GST_FLOW_OK;
2451 GST_WARNING_OBJECT (parse,
2452 "Found Cluster element before Tracks, searching Tracks");
2455 before_pos = parse->common.offset;
2457 /* Search Tracks element */
2459 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2460 GST_ELEMENT_CAST (parse), &id, &length, &needed);
2461 if (ret != GST_FLOW_OK)
2464 if (id != GST_MATROSKA_ID_TRACKS) {
2465 /* we may be skipping large cluster here, so forego size check etc */
2466 /* ... but we can't skip undefined size; force error */
2467 if (length == G_MAXUINT64) {
2468 ret = gst_matroska_parse_check_read_size (parse, length);
2471 parse->common.offset += needed;
2472 parse->offset += length;
2477 /* will lead to track parsing ... */
2478 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2483 parse->offset = before_pos;
2489 #define GST_READ_CHECK(stmt) \
2491 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
2492 if (ret == GST_FLOW_OVERFLOW) { \
2493 ret = GST_FLOW_OK; \
2500 gst_matroska_parse_accumulate_streamheader (GstMatroskaParse * parse,
2503 if (parse->pushed_headers) {
2504 GST_WARNING_OBJECT (parse,
2505 "Accumulating headers, but headers are already pushed");
2508 if (parse->streamheader) {
2511 buf = gst_buffer_span (parse->streamheader, 0, buffer,
2512 GST_BUFFER_SIZE (parse->streamheader) + GST_BUFFER_SIZE (buffer));
2513 gst_buffer_unref (parse->streamheader);
2514 parse->streamheader = buf;
2516 parse->streamheader = gst_buffer_ref (buffer);
2519 GST_DEBUG ("%d", GST_BUFFER_SIZE (parse->streamheader));
2522 static GstFlowReturn
2523 gst_matroska_parse_output (GstMatroskaParse * parse, GstBuffer * buffer,
2526 GstFlowReturn ret = GST_FLOW_OK;
2528 if (!parse->pushed_headers) {
2531 GValue streamheader = { 0 };
2532 GValue bufval = { 0 };
2535 caps = gst_caps_new_simple ("video/x-matroska", NULL);
2536 s = gst_caps_get_structure (caps, 0);
2537 g_value_init (&streamheader, GST_TYPE_ARRAY);
2538 g_value_init (&bufval, GST_TYPE_BUFFER);
2539 buf = gst_buffer_copy (parse->streamheader);
2540 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
2541 gst_value_set_buffer (&bufval, buf);
2542 gst_buffer_unref (buf);
2543 gst_value_array_append_value (&streamheader, &bufval);
2544 g_value_unset (&bufval);
2545 gst_structure_set_value (s, "streamheader", &streamheader);
2546 g_value_unset (&streamheader);
2547 //gst_caps_replace (parse->caps, caps);
2548 gst_pad_set_caps (parse->srcpad, caps);
2550 buf = gst_buffer_copy (parse->streamheader);
2551 gst_buffer_set_caps (buf, caps);
2552 gst_caps_unref (caps);
2554 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2555 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
2556 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
2558 ret = gst_pad_push (parse->srcpad, buf);
2560 parse->pushed_headers = TRUE;
2564 GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2566 GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2568 if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE) {
2569 parse->last_timestamp = GST_BUFFER_TIMESTAMP (buffer);
2571 GST_BUFFER_TIMESTAMP (buffer) = parse->last_timestamp;
2573 gst_buffer_set_caps (buffer, GST_PAD_CAPS (parse->srcpad));
2574 ret = gst_pad_push (parse->srcpad, gst_buffer_ref (buffer));
2579 static GstFlowReturn
2580 gst_matroska_parse_parse_id (GstMatroskaParse * parse, guint32 id,
2581 guint64 length, guint needed)
2583 GstEbmlRead ebml = { 0, };
2584 GstFlowReturn ret = GST_FLOW_OK;
2586 //GstBuffer *buffer;
2588 GST_DEBUG_OBJECT (parse, "Parsing Element id 0x%x, "
2589 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
2592 if (gst_adapter_available (parse->adapter) >= length + needed) {
2593 buffer = gst_adapter_take_buffer (parse->adapter, length + needed);
2594 gst_pad_push (parse->srcpad, buffer);
2596 ret = GST_FLOW_UNEXPECTED;
2598 //GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2605 /* if we plan to read and parse this element, we need prefix (id + length)
2606 * and the contents */
2607 /* mind about overflow wrap-around when dealing with undefined size */
2609 if (G_LIKELY (length != G_MAXUINT64))
2612 switch (parse->common.state) {
2613 case GST_MATROSKA_READ_STATE_START:
2615 case GST_EBML_ID_HEADER:
2616 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2617 ret = gst_matroska_read_common_parse_header (&parse->common, &ebml);
2618 if (ret != GST_FLOW_OK)
2620 parse->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
2621 gst_matroska_parse_check_seekability (parse);
2622 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2625 goto invalid_header;
2629 case GST_MATROSKA_READ_STATE_SEGMENT:
2631 case GST_MATROSKA_ID_SEGMENT:
2632 /* eat segment prefix */
2633 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2634 GST_DEBUG_OBJECT (parse,
2635 "Found Segment start at offset %" G_GUINT64_FORMAT,
2636 parse->common.offset);
2637 /* seeks are from the beginning of the segment,
2638 * after the segment ID/length */
2639 parse->common.ebml_segment_start = parse->common.offset;
2640 parse->common.state = GST_MATROSKA_READ_STATE_HEADER;
2641 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2644 GST_WARNING_OBJECT (parse,
2645 "Expected a Segment ID (0x%x), but received 0x%x!",
2646 GST_MATROSKA_ID_SEGMENT, id);
2647 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2648 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2652 case GST_MATROSKA_READ_STATE_SCANNING:
2653 if (id != GST_MATROSKA_ID_CLUSTER &&
2654 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
2657 case GST_MATROSKA_READ_STATE_HEADER:
2658 case GST_MATROSKA_READ_STATE_DATA:
2659 case GST_MATROSKA_READ_STATE_SEEK:
2661 case GST_MATROSKA_ID_SEGMENTINFO:
2662 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2663 if (!parse->common.segmentinfo_parsed) {
2664 ret = gst_matroska_read_common_parse_info (&parse->common,
2665 GST_ELEMENT_CAST (parse), &ebml);
2667 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2669 case GST_MATROSKA_ID_TRACKS:
2670 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2671 if (!parse->tracks_parsed) {
2672 ret = gst_matroska_parse_parse_tracks (parse, &ebml);
2674 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2676 case GST_MATROSKA_ID_CLUSTER:
2677 if (G_UNLIKELY (!parse->tracks_parsed)) {
2678 GST_DEBUG_OBJECT (parse, "Cluster before Track");
2679 goto not_streamable;
2681 if (G_UNLIKELY (parse->common.state
2682 == GST_MATROSKA_READ_STATE_HEADER)) {
2683 parse->common.state = GST_MATROSKA_READ_STATE_DATA;
2684 parse->first_cluster_offset = parse->common.offset;
2685 GST_DEBUG_OBJECT (parse, "signaling no more pads");
2687 parse->cluster_time = GST_CLOCK_TIME_NONE;
2688 parse->cluster_offset = parse->common.offset;
2689 if (G_UNLIKELY (!parse->seek_first && parse->seek_block)) {
2690 GST_DEBUG_OBJECT (parse, "seek target block %" G_GUINT64_FORMAT
2691 " not found in Cluster, trying next Cluster's first block instead",
2693 parse->seek_block = 0;
2695 parse->seek_first = FALSE;
2696 /* record next cluster for recovery */
2697 if (read != G_MAXUINT64)
2698 parse->next_cluster_offset = parse->cluster_offset + read;
2699 /* eat cluster prefix */
2700 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2701 ret = gst_matroska_parse_output (parse, ebml.buf, TRUE);
2702 //gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2704 case GST_MATROSKA_ID_CLUSTERTIMECODE:
2708 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2709 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
2711 GST_DEBUG_OBJECT (parse, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
2712 parse->cluster_time = num;
2713 if (parse->common.element_index) {
2714 if (parse->common.element_index_writer_id == -1)
2715 gst_index_get_writer_id (parse->common.element_index,
2716 GST_OBJECT (parse), &parse->common.element_index_writer_id);
2717 GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
2718 G_GUINT64_FORMAT " for writer id %d",
2719 GST_TIME_ARGS (parse->cluster_time), parse->cluster_offset,
2720 parse->common.element_index_writer_id);
2721 gst_index_add_association (parse->common.element_index,
2722 parse->common.element_index_writer_id,
2723 GST_ASSOCIATION_FLAG_KEY_UNIT,
2724 GST_FORMAT_TIME, parse->cluster_time,
2725 GST_FORMAT_BYTES, parse->cluster_offset, NULL);
2727 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2730 case GST_MATROSKA_ID_BLOCKGROUP:
2731 if (!gst_matroska_parse_seek_block (parse))
2733 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2734 DEBUG_ELEMENT_START (parse, &ebml, "BlockGroup");
2735 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
2736 ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
2737 &ebml, parse->cluster_time, parse->cluster_offset, FALSE);
2739 DEBUG_ELEMENT_STOP (parse, &ebml, "BlockGroup", ret);
2740 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2742 case GST_MATROSKA_ID_SIMPLEBLOCK:
2743 if (!gst_matroska_parse_seek_block (parse))
2745 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2746 DEBUG_ELEMENT_START (parse, &ebml, "SimpleBlock");
2747 ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
2748 &ebml, parse->cluster_time, parse->cluster_offset, TRUE);
2749 DEBUG_ELEMENT_STOP (parse, &ebml, "SimpleBlock", ret);
2750 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2752 case GST_MATROSKA_ID_ATTACHMENTS:
2753 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2754 if (!parse->common.attachments_parsed) {
2755 ret = gst_matroska_read_common_parse_attachments (&parse->common,
2756 GST_ELEMENT_CAST (parse), &ebml);
2758 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2760 case GST_MATROSKA_ID_TAGS:
2761 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2762 ret = gst_matroska_read_common_parse_metadata (&parse->common,
2763 GST_ELEMENT_CAST (parse), &ebml);
2764 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2766 case GST_MATROSKA_ID_CHAPTERS:
2767 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2768 ret = gst_matroska_read_common_parse_chapters (&parse->common, &ebml);
2769 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2771 case GST_MATROSKA_ID_SEEKHEAD:
2772 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2773 ret = gst_matroska_parse_parse_contents (parse, &ebml);
2774 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2776 case GST_MATROSKA_ID_CUES:
2777 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2778 if (!parse->common.index_parsed) {
2779 ret = gst_matroska_read_common_parse_index (&parse->common, &ebml);
2780 /* only push based; delayed index building */
2781 if (ret == GST_FLOW_OK
2782 && parse->common.state == GST_MATROSKA_READ_STATE_SEEK) {
2785 GST_OBJECT_LOCK (parse);
2786 event = parse->seek_event;
2787 parse->seek_event = NULL;
2788 GST_OBJECT_UNLOCK (parse);
2791 /* unlikely to fail, since we managed to seek to this point */
2792 if (!gst_matroska_parse_handle_seek_event (parse, NULL, event))
2794 /* resume data handling, main thread clear to seek again */
2795 GST_OBJECT_LOCK (parse);
2796 parse->common.state = GST_MATROSKA_READ_STATE_DATA;
2797 GST_OBJECT_UNLOCK (parse);
2800 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2802 case GST_MATROSKA_ID_POSITION:
2803 case GST_MATROSKA_ID_PREVSIZE:
2804 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
2805 case GST_MATROSKA_ID_SILENTTRACKS:
2806 GST_DEBUG_OBJECT (parse,
2807 "Skipping Cluster subelement 0x%x - ignoring", id);
2811 GST_DEBUG_OBJECT (parse, "skipping Element 0x%x", id);
2812 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2813 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2819 if (ret == GST_FLOW_PARSE)
2823 gst_ebml_read_clear (&ebml);
2829 /* simply exit, maybe not enough data yet */
2830 /* no ebml to clear if read error */
2835 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2836 ("Failed to parse Element 0x%x", id));
2837 ret = GST_FLOW_ERROR;
2842 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2843 ("File layout does not permit streaming"));
2844 ret = GST_FLOW_ERROR;
2850 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2851 ("No Tracks element found"));
2852 ret = GST_FLOW_ERROR;
2858 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Invalid header"));
2859 ret = GST_FLOW_ERROR;
2864 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Failed to seek"));
2865 ret = GST_FLOW_ERROR;
2872 gst_matroska_parse_loop (GstPad * pad)
2874 GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
2880 /* If we have to close a segment, send a new segment to do this now */
2881 if (G_LIKELY (parse->common.state == GST_MATROSKA_READ_STATE_DATA)) {
2882 if (G_UNLIKELY (parse->close_segment)) {
2883 gst_matroska_parse_send_event (parse, parse->close_segment);
2884 parse->close_segment = NULL;
2886 if (G_UNLIKELY (parse->new_segment)) {
2887 gst_matroska_parse_send_event (parse, parse->new_segment);
2888 parse->new_segment = NULL;
2892 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2893 GST_ELEMENT_CAST (parse), &id, &length, &needed);
2894 if (ret == GST_FLOW_UNEXPECTED)
2896 if (ret != GST_FLOW_OK) {
2897 if (gst_matroska_parse_check_parse_error (parse))
2903 GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2904 "size %" G_GUINT64_FORMAT ", needed %d", parse->offset, id,
2907 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2908 if (ret == GST_FLOW_UNEXPECTED)
2910 if (ret != GST_FLOW_OK)
2913 /* check if we're at the end of a configured segment */
2914 if (G_LIKELY (parse->src->len)) {
2917 g_assert (parse->num_streams == parse->src->len);
2918 for (i = 0; i < parse->src->len; i++) {
2919 GstMatroskaTrackContext *context = g_ptr_array_index (parse->src, i);
2920 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
2921 GST_TIME_ARGS (context->pos));
2922 if (context->eos == FALSE)
2926 GST_INFO_OBJECT (parse, "All streams are EOS");
2927 ret = GST_FLOW_UNEXPECTED;
2932 if (G_UNLIKELY (parse->offset ==
2933 gst_matroska_read_common_get_length (&parse->common))) {
2934 GST_LOG_OBJECT (parse, "Reached end of stream");
2935 ret = GST_FLOW_UNEXPECTED;
2944 if (parse->segment.rate < 0.0) {
2945 ret = gst_matroska_parse_seek_to_previous_keyframe (parse);
2946 if (ret == GST_FLOW_OK)
2953 const gchar *reason = gst_flow_get_name (ret);
2954 gboolean push_eos = FALSE;
2956 GST_LOG_OBJECT (parse, "pausing task, reason %s", reason);
2957 parse->segment_running = FALSE;
2958 gst_pad_pause_task (parse->common.sinkpad);
2960 if (ret == GST_FLOW_UNEXPECTED) {
2961 /* perform EOS logic */
2963 /* Close the segment, i.e. update segment stop with the duration
2964 * if no stop was set */
2965 if (GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) &&
2966 !GST_CLOCK_TIME_IS_VALID (parse->segment.stop)) {
2968 gst_event_new_new_segment_full (TRUE, parse->segment.rate,
2969 parse->segment.applied_rate, parse->segment.format,
2970 parse->segment.start,
2971 MAX (parse->last_stop_end, parse->segment.start),
2972 parse->segment.time);
2973 gst_matroska_parse_send_event (parse, event);
2976 if (parse->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2979 /* for segment playback we need to post when (in stream time)
2980 * we stopped, this is either stop (when set) or the duration. */
2981 if ((stop = parse->segment.stop) == -1)
2982 stop = parse->last_stop_end;
2984 GST_LOG_OBJECT (parse, "Sending segment done, at end of segment");
2985 gst_element_post_message (GST_ELEMENT (parse),
2986 gst_message_new_segment_done (GST_OBJECT (parse), GST_FORMAT_TIME,
2991 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_UNEXPECTED) {
2992 /* for fatal errors we post an error message */
2993 GST_ELEMENT_ERROR (parse, STREAM, FAILED, (NULL),
2994 ("stream stopped, reason %s", reason));
2998 /* send EOS, and prevent hanging if no streams yet */
2999 GST_LOG_OBJECT (parse, "Sending EOS, at end of stream");
3000 if (!gst_matroska_parse_send_event (parse, gst_event_new_eos ()) &&
3001 (ret == GST_FLOW_UNEXPECTED)) {
3002 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3003 (NULL), ("got eos but no streams (yet)"));
3012 * Create and push a flushing seek event upstream
3015 perform_seek_to_offset (GstMatroskaParse * parse, guint64 offset)
3020 GST_DEBUG_OBJECT (parse, "Seeking to %" G_GUINT64_FORMAT, offset);
3023 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
3024 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
3025 GST_SEEK_TYPE_NONE, -1);
3027 res = gst_pad_push_event (parse->common.sinkpad, event);
3029 /* newsegment event will update offset */
3033 static GstFlowReturn
3034 gst_matroska_parse_chain (GstPad * pad, GstBuffer * buffer)
3036 GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
3038 GstFlowReturn ret = GST_FLOW_OK;
3043 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
3044 GST_DEBUG_OBJECT (parse, "got DISCONT");
3045 gst_adapter_clear (parse->common.adapter);
3046 GST_OBJECT_LOCK (parse);
3047 gst_matroska_read_common_reset_streams (&parse->common,
3048 GST_CLOCK_TIME_NONE, FALSE);
3049 GST_OBJECT_UNLOCK (parse);
3052 gst_adapter_push (parse->common.adapter, buffer);
3056 available = gst_adapter_available (parse->common.adapter);
3058 ret = gst_matroska_read_common_peek_id_length_push (&parse->common,
3059 GST_ELEMENT_CAST (parse), &id, &length, &needed);
3060 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED))
3063 GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
3064 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
3065 parse->common.offset, id, length, needed, available);
3067 if (needed > available)
3070 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
3071 if (ret == GST_FLOW_UNEXPECTED) {
3072 /* need more data */
3074 } else if (ret != GST_FLOW_OK) {
3081 gst_matroska_parse_handle_sink_event (GstPad * pad, GstEvent * event)
3083 gboolean res = TRUE;
3084 GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
3086 GST_DEBUG_OBJECT (parse,
3087 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
3089 switch (GST_EVENT_TYPE (event)) {
3090 case GST_EVENT_NEWSEGMENT:
3093 gdouble rate, arate;
3094 gint64 start, stop, time = 0;
3098 /* some debug output */
3099 gst_segment_init (&segment, GST_FORMAT_UNDEFINED);
3100 gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
3101 &start, &stop, &time);
3102 gst_segment_set_newsegment_full (&segment, update, rate, arate, format,
3104 GST_DEBUG_OBJECT (parse,
3105 "received format %d newsegment %" GST_SEGMENT_FORMAT, format,
3108 if (parse->common.state < GST_MATROSKA_READ_STATE_DATA) {
3109 GST_DEBUG_OBJECT (parse, "still starting");
3113 /* we only expect a BYTE segment, e.g. following a seek */
3114 if (format != GST_FORMAT_BYTES) {
3115 GST_DEBUG_OBJECT (parse, "unsupported segment format, ignoring");
3119 GST_DEBUG_OBJECT (parse, "clearing segment state");
3120 /* clear current segment leftover */
3121 gst_adapter_clear (parse->common.adapter);
3122 /* and some streaming setup */
3123 parse->common.offset = start;
3124 /* do not know where we are;
3125 * need to come across a cluster and generate newsegment */
3126 parse->common.segment.last_stop = GST_CLOCK_TIME_NONE;
3127 parse->cluster_time = GST_CLOCK_TIME_NONE;
3128 parse->cluster_offset = 0;
3129 parse->need_newsegment = TRUE;
3130 /* but keep some of the upstream segment */
3131 parse->common.segment.rate = rate;
3133 /* chain will send initial newsegment after pads have been added,
3134 * or otherwise come up with one */
3135 GST_DEBUG_OBJECT (parse, "eating event");
3136 gst_event_unref (event);
3142 if (parse->common.state != GST_MATROSKA_READ_STATE_DATA) {
3143 gst_event_unref (event);
3144 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3145 (NULL), ("got eos and didn't receive a complete header object"));
3146 } else if (parse->common.num_streams == 0) {
3147 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3148 (NULL), ("got eos but no streams (yet)"));
3150 gst_matroska_parse_send_event (parse, event);
3154 case GST_EVENT_FLUSH_STOP:
3156 gst_adapter_clear (parse->common.adapter);
3157 GST_OBJECT_LOCK (parse);
3158 gst_matroska_read_common_reset_streams (&parse->common,
3159 GST_CLOCK_TIME_NONE, TRUE);
3160 GST_OBJECT_UNLOCK (parse);
3161 parse->common.segment.last_stop = GST_CLOCK_TIME_NONE;
3162 parse->cluster_time = GST_CLOCK_TIME_NONE;
3163 parse->cluster_offset = 0;
3167 res = gst_pad_event_default (pad, event);
3175 gst_matroska_parse_set_index (GstElement * element, GstIndex * index)
3177 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3179 GST_OBJECT_LOCK (parse);
3180 if (parse->common.element_index)
3181 gst_object_unref (parse->common.element_index);
3182 parse->common.element_index = index ? gst_object_ref (index) : NULL;
3183 GST_OBJECT_UNLOCK (parse);
3184 GST_DEBUG_OBJECT (parse, "Set index %" GST_PTR_FORMAT,
3185 parse->common.element_index);
3189 gst_matroska_parse_get_index (GstElement * element)
3191 GstIndex *result = NULL;
3192 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3194 GST_OBJECT_LOCK (parse);
3195 if (parse->common.element_index)
3196 result = gst_object_ref (parse->common.element_index);
3197 GST_OBJECT_UNLOCK (parse);
3199 GST_DEBUG_OBJECT (parse, "Returning index %" GST_PTR_FORMAT, result);
3204 static GstStateChangeReturn
3205 gst_matroska_parse_change_state (GstElement * element,
3206 GstStateChange transition)
3208 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3209 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
3211 /* handle upwards state changes here */
3212 switch (transition) {
3217 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
3219 /* handle downwards state changes */
3220 switch (transition) {
3221 case GST_STATE_CHANGE_PAUSED_TO_READY:
3222 gst_matroska_parse_reset (GST_ELEMENT (parse));
3232 gst_matroska_parse_plugin_init (GstPlugin * plugin)
3236 /* create an elementfactory for the matroska_parse element */
3237 if (!gst_element_register (plugin, "matroskaparse",
3238 GST_RANK_NONE, GST_TYPE_MATROSKA_PARSE))