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 ("audio/x-matroska; video/x-matroska; "
91 "video/x-matroska-3d; audio/webm; video/webm")
94 static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
97 GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
98 "video/x-matroska-3d; audio/webm; video/webm")
101 static GstFlowReturn gst_matroska_parse_parse_id (GstMatroskaParse * parse,
102 guint32 id, guint64 length, guint needed);
104 /* element functions */
105 //static void gst_matroska_parse_loop (GstPad * pad);
107 static gboolean gst_matroska_parse_element_send_event (GstElement * element,
109 static gboolean gst_matroska_parse_element_query (GstElement * element,
113 static gboolean gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
114 GstPad * pad, GstEvent * event);
115 static gboolean gst_matroska_parse_handle_src_event (GstPad * pad,
116 GstObject * parent, GstEvent * event);
117 static gboolean gst_matroska_parse_handle_src_query (GstPad * pad,
118 GstObject * parent, GstQuery * query);
120 static gboolean gst_matroska_parse_handle_sink_event (GstPad * pad,
121 GstObject * parent, GstEvent * event);
122 static GstFlowReturn gst_matroska_parse_chain (GstPad * pad,
123 GstObject * parent, GstBuffer * buffer);
125 static GstStateChangeReturn
126 gst_matroska_parse_change_state (GstElement * element,
127 GstStateChange transition);
130 gst_matroska_parse_set_index (GstElement * element, GstIndex * index);
131 static GstIndex *gst_matroska_parse_get_index (GstElement * element);
135 static void gst_matroska_parse_reset (GstElement * element);
136 static gboolean perform_seek_to_offset (GstMatroskaParse * parse,
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 if (parse->common.src) {
149 g_ptr_array_free (parse->common.src, TRUE);
150 parse->common.src = NULL;
153 if (parse->common.global_tags) {
154 gst_tag_list_free (parse->common.global_tags);
155 parse->common.global_tags = NULL;
158 g_object_unref (parse->common.adapter);
160 G_OBJECT_CLASS (parent_class)->finalize (object);
164 gst_matroska_parse_class_init (GstMatroskaParseClass * klass)
166 GObjectClass *gobject_class = (GObjectClass *) klass;
167 GstElementClass *gstelement_class = (GstElementClass *) klass;
169 GST_DEBUG_CATEGORY_INIT (matroskaparse_debug, "matroskaparse", 0,
172 gobject_class->finalize = gst_matroska_parse_finalize;
174 gstelement_class->change_state =
175 GST_DEBUG_FUNCPTR (gst_matroska_parse_change_state);
176 gstelement_class->send_event =
177 GST_DEBUG_FUNCPTR (gst_matroska_parse_element_send_event);
178 gstelement_class->query =
179 GST_DEBUG_FUNCPTR (gst_matroska_parse_element_query);
182 gstelement_class->set_index =
183 GST_DEBUG_FUNCPTR (gst_matroska_parse_set_index);
184 gstelement_class->get_index =
185 GST_DEBUG_FUNCPTR (gst_matroska_parse_get_index);
188 gst_element_class_add_pad_template (gstelement_class,
189 gst_static_pad_template_get (&src_templ));
190 gst_element_class_add_pad_template (gstelement_class,
191 gst_static_pad_template_get (&sink_templ));
193 gst_element_class_set_static_metadata (gstelement_class,
194 "Matroska parser", "Codec/Parser",
195 "Parses Matroska/WebM streams into video/audio/subtitles",
196 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
200 gst_matroska_parse_init (GstMatroskaParse * parse)
202 parse->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
204 gst_pad_set_chain_function (parse->common.sinkpad,
205 GST_DEBUG_FUNCPTR (gst_matroska_parse_chain));
206 gst_pad_set_event_function (parse->common.sinkpad,
207 GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_sink_event));
208 gst_element_add_pad (GST_ELEMENT (parse), parse->common.sinkpad);
210 parse->srcpad = gst_pad_new_from_static_template (&src_templ, "src");
211 gst_pad_set_event_function (parse->srcpad,
212 GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_event));
213 gst_pad_set_query_function (parse->srcpad,
214 GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_query));
215 gst_pad_use_fixed_caps (parse->srcpad);
217 gst_element_add_pad (GST_ELEMENT (parse), parse->srcpad);
219 /* initial stream no. */
220 parse->common.src = NULL;
222 parse->common.writing_app = NULL;
223 parse->common.muxing_app = NULL;
224 parse->common.index = NULL;
225 parse->common.global_tags = NULL;
227 parse->common.adapter = gst_adapter_new ();
229 GST_OBJECT_FLAG_SET (parse, GST_ELEMENT_FLAG_INDEXABLE);
232 gst_matroska_parse_reset (GST_ELEMENT (parse));
236 gst_matroska_track_free (GstMatroskaTrackContext * track)
238 g_free (track->codec_id);
239 g_free (track->codec_name);
240 g_free (track->name);
241 g_free (track->language);
242 g_free (track->codec_priv);
243 g_free (track->codec_state);
245 if (track->encodings != NULL) {
248 for (i = 0; i < track->encodings->len; ++i) {
249 GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
250 GstMatroskaTrackEncoding,
253 g_free (enc->comp_settings);
255 g_array_free (track->encodings, TRUE);
258 if (track->pending_tags)
259 gst_tag_list_free (track->pending_tags);
261 if (track->index_table)
262 g_array_free (track->index_table, TRUE);
268 gst_matroska_parse_free_parsed_el (gpointer mem, gpointer user_data)
270 g_slice_free (guint64, mem);
274 gst_matroska_parse_reset (GstElement * element)
276 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
279 GST_DEBUG_OBJECT (parse, "Resetting state");
282 parse->common.state = GST_MATROSKA_READ_STATE_START;
284 /* clean up existing streams */
285 if (parse->common.src) {
286 g_assert (parse->common.src->len == parse->common.num_streams);
287 for (i = 0; i < parse->common.src->len; i++) {
288 GstMatroskaTrackContext *context = g_ptr_array_index (parse->common.src,
291 gst_caps_replace (&context->caps, NULL);
292 gst_matroska_track_free (context);
294 g_ptr_array_free (parse->common.src, TRUE);
296 parse->common.src = g_ptr_array_new ();
298 parse->common.num_streams = 0;
299 parse->num_a_streams = 0;
300 parse->num_t_streams = 0;
301 parse->num_v_streams = 0;
303 /* reset media info */
304 g_free (parse->common.writing_app);
305 parse->common.writing_app = NULL;
306 g_free (parse->common.muxing_app);
307 parse->common.muxing_app = NULL;
310 if (parse->common.index) {
311 g_array_free (parse->common.index, TRUE);
312 parse->common.index = NULL;
317 parse->common.time_scale = 1000000;
318 parse->common.created = G_MININT64;
320 parse->common.index_parsed = FALSE;
321 parse->tracks_parsed = FALSE;
322 parse->common.segmentinfo_parsed = FALSE;
323 parse->common.attachments_parsed = FALSE;
325 g_list_foreach (parse->common.tags_parsed,
326 (GFunc) gst_matroska_parse_free_parsed_el, NULL);
327 g_list_free (parse->common.tags_parsed);
328 parse->common.tags_parsed = NULL;
330 g_list_foreach (parse->seek_parsed,
331 (GFunc) gst_matroska_parse_free_parsed_el, NULL);
332 g_list_free (parse->seek_parsed);
333 parse->seek_parsed = NULL;
335 gst_segment_init (&parse->common.segment, GST_FORMAT_TIME);
336 parse->last_stop_end = GST_CLOCK_TIME_NONE;
337 parse->seek_block = 0;
339 parse->common.offset = 0;
340 parse->cluster_time = GST_CLOCK_TIME_NONE;
341 parse->cluster_offset = 0;
342 parse->next_cluster_offset = 0;
343 parse->index_offset = 0;
344 parse->seekable = FALSE;
345 parse->need_newsegment = FALSE;
346 parse->building_index = FALSE;
347 if (parse->seek_event) {
348 gst_event_unref (parse->seek_event);
349 parse->seek_event = NULL;
352 parse->seek_index = NULL;
353 parse->seek_entry = 0;
355 if (parse->close_segment) {
356 gst_event_unref (parse->close_segment);
357 parse->close_segment = NULL;
360 if (parse->new_segment) {
361 gst_event_unref (parse->new_segment);
362 parse->new_segment = NULL;
365 if (parse->common.element_index) {
366 gst_object_unref (parse->common.element_index);
367 parse->common.element_index = NULL;
369 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_empty ();
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_EOS)) {
1054 if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
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");
1080 gst_matroska_parse_query (GstMatroskaParse * parse, GstPad * pad,
1083 gboolean res = FALSE;
1084 GstMatroskaTrackContext *context = NULL;
1087 context = gst_pad_get_element_private (pad);
1090 switch (GST_QUERY_TYPE (query)) {
1091 case GST_QUERY_POSITION:
1095 gst_query_parse_position (query, &format, NULL);
1097 if (format == GST_FORMAT_TIME) {
1098 GST_OBJECT_LOCK (parse);
1100 gst_query_set_position (query, GST_FORMAT_TIME, context->pos);
1102 gst_query_set_position (query, GST_FORMAT_TIME,
1103 parse->common.segment.position);
1104 GST_OBJECT_UNLOCK (parse);
1105 } else if (format == GST_FORMAT_DEFAULT && context
1106 && context->default_duration) {
1107 GST_OBJECT_LOCK (parse);
1108 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1109 context->pos / context->default_duration);
1110 GST_OBJECT_UNLOCK (parse);
1112 GST_DEBUG_OBJECT (parse,
1113 "only position query in TIME and DEFAULT format is supported");
1119 case GST_QUERY_DURATION:
1123 gst_query_parse_duration (query, &format, NULL);
1125 if (format == GST_FORMAT_TIME) {
1126 GST_OBJECT_LOCK (parse);
1127 gst_query_set_duration (query, GST_FORMAT_TIME,
1128 parse->common.segment.duration);
1129 GST_OBJECT_UNLOCK (parse);
1130 } else if (format == GST_FORMAT_DEFAULT && context
1131 && context->default_duration) {
1132 GST_OBJECT_LOCK (parse);
1133 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1134 parse->common.segment.duration / context->default_duration);
1135 GST_OBJECT_UNLOCK (parse);
1137 GST_DEBUG_OBJECT (parse,
1138 "only duration query in TIME and DEFAULT format is supported");
1145 case GST_QUERY_SEEKING:
1149 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1150 if (fmt == GST_FORMAT_TIME) {
1153 /* assuming we'll be able to get an index ... */
1154 seekable = parse->seekable;
1156 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1157 0, parse->common.segment.duration);
1163 res = gst_pad_query_default (pad, (GstObject *) parse, query);
1171 gst_matroska_parse_element_query (GstElement * element, GstQuery * query)
1173 return gst_matroska_parse_query (GST_MATROSKA_PARSE (element), NULL, query);
1177 gst_matroska_parse_handle_src_query (GstPad * pad, GstObject * parent,
1181 GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
1183 ret = gst_matroska_parse_query (parse, pad, query);
1188 /* returns FALSE if there are no pads to deliver event to,
1189 * otherwise TRUE (whatever the outcome of event sending),
1190 * takes ownership of the passed event! */
1192 gst_matroska_parse_send_event (GstMatroskaParse * parse, GstEvent * event)
1194 gboolean ret = FALSE;
1196 g_return_val_if_fail (event != NULL, FALSE);
1198 GST_DEBUG_OBJECT (parse, "Sending event of type %s to all source pads",
1199 GST_EVENT_TYPE_NAME (event));
1201 gst_pad_push_event (parse->srcpad, event);
1207 gst_matroska_parse_element_send_event (GstElement * element, GstEvent * event)
1209 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
1212 g_return_val_if_fail (event != NULL, FALSE);
1214 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1215 res = gst_matroska_parse_handle_seek_event (parse, NULL, event);
1217 GST_WARNING_OBJECT (parse, "Unhandled event of type %s",
1218 GST_EVENT_TYPE_NAME (event));
1221 gst_event_unref (event);
1225 /* searches for a cluster start from @pos,
1226 * return GST_FLOW_OK and cluster position in @pos if found */
1227 static GstFlowReturn
1228 gst_matroska_parse_search_cluster (GstMatroskaParse * parse, gint64 * pos)
1230 gint64 newpos = *pos;
1232 GstFlowReturn ret = GST_FLOW_OK;
1233 const guint chunk = 64 * 1024;
1242 orig_offset = parse->common.offset;
1244 /* read in at newpos and scan for ebml cluster id */
1246 GstByteReader reader;
1250 ret = gst_pad_pull_range (parse->common.sinkpad, newpos, chunk, &buf);
1251 if (ret != GST_FLOW_OK)
1253 GST_DEBUG_OBJECT (parse,
1254 "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1255 gst_buffer_get_size (buf), newpos);
1256 gst_buffer_map (buf, &map, GST_MAP_READ);
1259 gst_byte_reader_init (&reader, data, size);
1262 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1263 GST_MATROSKA_ID_CLUSTER, cluster_pos, size - cluster_pos);
1264 if (cluster_pos >= 0) {
1265 newpos += cluster_pos;
1266 GST_DEBUG_OBJECT (parse,
1267 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1268 /* extra checks whether we really sync'ed to a cluster:
1269 * - either it is the first and only cluster
1270 * - either there is a cluster after this one
1271 * - either cluster length is undefined
1273 /* ok if first cluster (there may not a subsequent one) */
1274 if (newpos == parse->first_cluster_offset) {
1275 GST_DEBUG_OBJECT (parse, "cluster is first cluster -> OK");
1278 parse->common.offset = newpos;
1279 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1280 GST_ELEMENT_CAST (parse), &id, &length, &needed);
1281 if (ret != GST_FLOW_OK)
1283 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1284 GST_DEBUG_OBJECT (parse, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1286 /* ok if undefined length or first cluster */
1287 if (length == G_MAXUINT64) {
1288 GST_DEBUG_OBJECT (parse, "cluster has undefined length -> OK");
1292 parse->common.offset += length + needed;
1293 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1294 GST_ELEMENT_CAST (parse), &id, &length, &needed);
1295 if (ret != GST_FLOW_OK)
1297 GST_DEBUG_OBJECT (parse, "next element is %scluster",
1298 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1299 if (id == GST_MATROSKA_ID_CLUSTER)
1301 /* not ok, resume */
1304 /* partial cluster id may have been in tail of buffer */
1305 newpos += MAX (size, 4) - 3;
1306 gst_buffer_unmap (buf, &map);
1307 gst_buffer_unref (buf);
1313 gst_buffer_unmap (buf, &map);
1314 gst_buffer_unref (buf);
1318 parse->common.offset = orig_offset;
1325 gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
1326 GstPad * pad, GstEvent * event)
1328 GstMatroskaIndex *entry = NULL;
1330 GstSeekType cur_type, stop_type;
1334 GstMatroskaTrackContext *track = NULL;
1335 GstSegment seeksegment = { 0, };
1339 track = gst_pad_get_element_private (pad);
1341 track = gst_matroska_read_common_get_seek_track (&parse->common, track);
1343 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1346 /* we can only seek on time */
1347 if (format != GST_FORMAT_TIME) {
1348 GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1352 /* copy segment, we need this because we still need the old
1353 * segment when we close the current segment. */
1354 memcpy (&seeksegment, &parse->common.segment, sizeof (GstSegment));
1357 GST_DEBUG_OBJECT (parse, "configuring seek");
1358 gst_segment_do_seek (&seeksegment, rate, format, flags,
1359 cur_type, cur, stop_type, stop, &update);
1362 GST_DEBUG_OBJECT (parse, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1364 /* check sanity before we start flushing and all that */
1365 GST_OBJECT_LOCK (parse);
1366 if ((entry = gst_matroska_read_common_do_index_seek (&parse->common, track,
1367 seeksegment.position, &parse->seek_index, &parse->seek_entry,
1369 /* pull mode without index can scan later on */
1370 GST_DEBUG_OBJECT (parse, "No matching seek entry in index");
1371 GST_OBJECT_UNLOCK (parse);
1374 GST_DEBUG_OBJECT (parse, "Seek position looks sane");
1375 GST_OBJECT_UNLOCK (parse);
1377 /* need to seek to cluster start to pick up cluster time */
1378 /* upstream takes care of flushing and all that
1379 * ... and newsegment event handling takes care of the rest */
1380 return perform_seek_to_offset (parse, entry->pos
1381 + parse->common.ebml_segment_start);
1385 * Handle whether we can perform the seek event or if we have to let the chain
1386 * function handle seeks to build the seek indexes first.
1389 gst_matroska_parse_handle_seek_push (GstMatroskaParse * parse, GstPad * pad,
1393 GstSeekType cur_type, stop_type;
1398 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1403 /* we can only seek on time */
1404 if (format != GST_FORMAT_TIME) {
1405 GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1409 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
1410 GST_DEBUG_OBJECT (parse, "Seek end-time not supported in streaming mode");
1414 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
1415 GST_DEBUG_OBJECT (parse,
1416 "Non-flushing seek not supported in streaming mode");
1420 if (flags & GST_SEEK_FLAG_SEGMENT) {
1421 GST_DEBUG_OBJECT (parse, "Segment seek not supported in streaming mode");
1425 /* check for having parsed index already */
1426 if (!parse->common.index_parsed) {
1427 gboolean building_index;
1430 if (!parse->index_offset) {
1431 GST_DEBUG_OBJECT (parse, "no index (location); no seek in push mode");
1435 GST_OBJECT_LOCK (parse);
1436 /* handle the seek event in the chain function */
1437 parse->common.state = GST_MATROSKA_READ_STATE_SEEK;
1438 /* no more seek can be issued until state reset to _DATA */
1440 /* copy the event */
1441 if (parse->seek_event)
1442 gst_event_unref (parse->seek_event);
1443 parse->seek_event = gst_event_ref (event);
1445 /* set the building_index flag so that only one thread can setup the
1446 * structures for index seeking. */
1447 building_index = parse->building_index;
1448 if (!building_index) {
1449 parse->building_index = TRUE;
1450 offset = parse->index_offset;
1452 GST_OBJECT_UNLOCK (parse);
1454 if (!building_index) {
1455 /* seek to the first subindex or legacy index */
1456 GST_INFO_OBJECT (parse, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
1457 return perform_seek_to_offset (parse, offset);
1460 /* well, we are handling it already */
1464 /* delegate to tweaked regular seek */
1465 return gst_matroska_parse_handle_seek_event (parse, pad, event);
1469 gst_matroska_parse_handle_src_event (GstPad * pad, GstObject * parent,
1472 GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
1473 gboolean res = TRUE;
1475 switch (GST_EVENT_TYPE (event)) {
1476 case GST_EVENT_SEEK:
1477 /* no seeking until we are (safely) ready */
1478 if (parse->common.state != GST_MATROSKA_READ_STATE_DATA) {
1479 GST_DEBUG_OBJECT (parse, "not ready for seeking yet");
1482 res = gst_matroska_parse_handle_seek_push (parse, pad, event);
1483 gst_event_unref (event);
1488 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
1489 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
1490 GstMatroskaTrackVideoContext *videocontext =
1491 (GstMatroskaTrackVideoContext *) context;
1493 GstClockTimeDiff diff;
1494 GstClockTime timestamp;
1496 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
1498 GST_OBJECT_LOCK (parse);
1499 videocontext->earliest_time = timestamp + diff;
1500 GST_OBJECT_UNLOCK (parse);
1503 gst_event_unref (event);
1507 /* events we don't need to handle */
1508 case GST_EVENT_NAVIGATION:
1509 gst_event_unref (event);
1513 case GST_EVENT_LATENCY:
1515 res = gst_pad_push_event (parse->common.sinkpad, event);
1522 static GstFlowReturn
1523 gst_matroska_parse_parse_tracks (GstMatroskaParse * parse, GstEbmlRead * ebml)
1525 GstFlowReturn ret = GST_FLOW_OK;
1528 DEBUG_ELEMENT_START (parse, ebml, "Tracks");
1530 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1531 DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1535 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1536 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1540 /* one track within the "all-tracks" header */
1541 case GST_MATROSKA_ID_TRACKENTRY:
1542 ret = gst_matroska_parse_add_stream (parse, ebml);
1546 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1551 DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1553 parse->tracks_parsed = TRUE;
1559 * Read signed/unsigned "EBML" numbers.
1560 * Return: number of bytes processed.
1564 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
1566 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
1574 while (read <= 8 && !(total & len_mask)) {
1581 if ((total &= (len_mask - 1)) == len_mask - 1)
1586 if (data[n] == 0xff)
1588 total = (total << 8) | data[n];
1592 if (read == num_ffs && total != 0)
1601 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
1606 /* read as unsigned number first */
1607 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
1611 if (unum == G_MAXUINT64)
1614 *num = unum - ((1 << ((7 * res) - 1)) - 1);
1619 static GstFlowReturn
1620 gst_matroska_parse_parse_blockgroup_or_simpleblock (GstMatroskaParse * parse,
1621 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
1622 gboolean is_simpleblock)
1624 GstMatroskaTrackContext *stream = NULL;
1625 GstFlowReturn ret = GST_FLOW_OK;
1626 gboolean readblock = FALSE;
1628 guint64 block_duration = 0;
1629 GstBuffer *buf = NULL;
1631 gint stream_num = -1, n, laces = 0;
1633 gint *lace_size = NULL;
1636 gint64 referenceblock = 0;
1638 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1639 if (!is_simpleblock) {
1640 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
1644 id = GST_MATROSKA_ID_SIMPLEBLOCK;
1648 /* one block inside the group. Note, block parsing is one
1649 * of the harder things, so this code is a bit complicated.
1650 * See http://www.matroska.org/ for documentation. */
1651 case GST_MATROSKA_ID_SIMPLEBLOCK:
1652 case GST_MATROSKA_ID_BLOCK:
1658 gst_buffer_unref (buf);
1661 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
1664 gst_buffer_map (buf, &map, GST_MAP_READ);
1668 /* first byte(s): blocknum */
1669 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1674 /* fetch stream from num */
1675 stream_num = gst_matroska_read_common_stream_from_num (&parse->common,
1677 if (G_UNLIKELY (size < 3)) {
1678 GST_WARNING_OBJECT (parse, "Invalid size %u", size);
1679 /* non-fatal, try next block(group) */
1682 } else if (G_UNLIKELY (stream_num < 0 ||
1683 stream_num >= parse->common.num_streams)) {
1684 /* let's not give up on a stray invalid track number */
1685 GST_WARNING_OBJECT (parse,
1686 "Invalid stream %d for track number %" G_GUINT64_FORMAT
1687 "; ignoring block", stream_num, num);
1691 stream = g_ptr_array_index (parse->common.src, stream_num);
1693 /* time (relative to cluster time) */
1694 time = ((gint16) GST_READ_UINT16_BE (data));
1697 flags = GST_READ_UINT8 (data);
1701 GST_LOG_OBJECT (parse, "time %" G_GUINT64_FORMAT ", flags %d", time,
1704 switch ((flags & 0x06) >> 1) {
1705 case 0x0: /* no lacing */
1707 lace_size = g_new (gint, 1);
1708 lace_size[0] = size;
1711 case 0x1: /* xiph lacing */
1712 case 0x2: /* fixed-size lacing */
1713 case 0x3: /* EBML lacing */
1715 goto invalid_lacing;
1716 laces = GST_READ_UINT8 (data) + 1;
1719 lace_size = g_new0 (gint, laces);
1721 switch ((flags & 0x06) >> 1) {
1722 case 0x1: /* xiph lacing */ {
1723 guint temp, total = 0;
1725 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
1728 goto invalid_lacing;
1729 temp = GST_READ_UINT8 (data);
1730 lace_size[n] += temp;
1736 total += lace_size[n];
1738 lace_size[n] = size - total;
1742 case 0x2: /* fixed-size lacing */
1743 for (n = 0; n < laces; n++)
1744 lace_size[n] = size / laces;
1747 case 0x3: /* EBML lacing */ {
1750 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1754 total = lace_size[0] = num;
1755 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
1759 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
1763 lace_size[n] = lace_size[n - 1] + snum;
1764 total += lace_size[n];
1767 lace_size[n] = size - total;
1774 if (ret != GST_FLOW_OK)
1781 case GST_MATROSKA_ID_BLOCKDURATION:{
1782 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
1783 GST_DEBUG_OBJECT (parse, "BlockDuration: %" G_GUINT64_FORMAT,
1788 case GST_MATROSKA_ID_REFERENCEBLOCK:{
1789 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
1790 GST_DEBUG_OBJECT (parse, "ReferenceBlock: %" G_GINT64_FORMAT,
1795 case GST_MATROSKA_ID_CODECSTATE:{
1797 guint64 data_len = 0;
1800 gst_ebml_read_binary (ebml, &id, &data,
1801 &data_len)) != GST_FLOW_OK)
1804 if (G_UNLIKELY (stream == NULL)) {
1805 GST_WARNING_OBJECT (parse,
1806 "Unexpected CodecState subelement - ignoring");
1810 g_free (stream->codec_state);
1811 stream->codec_state = data;
1812 stream->codec_state_size = data_len;
1818 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1822 case GST_MATROSKA_ID_BLOCKVIRTUAL:
1823 case GST_MATROSKA_ID_BLOCKADDITIONS:
1824 case GST_MATROSKA_ID_REFERENCEPRIORITY:
1825 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
1826 case GST_MATROSKA_ID_SLICES:
1827 GST_DEBUG_OBJECT (parse,
1828 "Skipping BlockGroup subelement 0x%x - ignoring", id);
1829 ret = gst_ebml_read_skip (ebml);
1837 /* reading a number or so could have failed */
1838 if (ret != GST_FLOW_OK)
1841 if (ret == GST_FLOW_OK && readblock) {
1842 guint64 duration = 0;
1843 gint64 lace_time = 0;
1844 gboolean delta_unit;
1846 stream = g_ptr_array_index (parse->common.src, stream_num);
1848 if (cluster_time != GST_CLOCK_TIME_NONE) {
1849 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
1850 * Drop unless the lace contains timestamp 0? */
1851 if (time < 0 && (-time) > cluster_time) {
1854 if (stream->timecodescale == 1.0)
1855 lace_time = (cluster_time + time) * parse->common.time_scale;
1858 gst_util_guint64_to_gdouble ((cluster_time + time) *
1859 parse->common.time_scale) * stream->timecodescale;
1862 lace_time = GST_CLOCK_TIME_NONE;
1865 if (lace_time != GST_CLOCK_TIME_NONE) {
1866 parse->last_timestamp = lace_time;
1868 /* need to refresh segment info ASAP */
1869 if (GST_CLOCK_TIME_IS_VALID (lace_time) && parse->need_newsegment) {
1871 GST_DEBUG_OBJECT (parse,
1872 "generating segment starting at %" GST_TIME_FORMAT,
1873 GST_TIME_ARGS (lace_time));
1874 /* pretend we seeked here */
1875 gst_segment_do_seek (&parse->common.segment, parse->common.segment.rate,
1876 GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, lace_time,
1877 GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE, NULL);
1878 /* now convey our segment notion downstream */
1879 segment = parse->common.segment;
1880 segment.position = segment.start;
1881 gst_matroska_parse_send_event (parse, gst_event_new_segment (&segment));
1882 parse->need_newsegment = FALSE;
1885 if (block_duration) {
1886 if (stream->timecodescale == 1.0)
1887 duration = gst_util_uint64_scale (block_duration,
1888 parse->common.time_scale, 1);
1891 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
1892 (gst_util_uint64_scale (block_duration, parse->common.time_scale,
1893 1)) * stream->timecodescale);
1894 } else if (stream->default_duration) {
1895 duration = stream->default_duration * laces;
1897 /* else duration is diff between timecode of this and next block */
1899 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
1900 a ReferenceBlock implies that this is not a keyframe. In either
1901 case, it only makes sense for video streams. */
1902 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1903 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
1905 if (delta_unit && stream->set_discont) {
1906 /* When doing seeks or such, we need to restart on key frames or
1907 * decoders might choke. */
1908 GST_DEBUG_OBJECT (parse, "skipping delta unit");
1912 for (n = 0; n < laces; n++) {
1913 if (G_UNLIKELY (lace_size[n] > size)) {
1914 GST_WARNING_OBJECT (parse, "Invalid lace size");
1918 /* QoS for video track with an index. the assumption is that
1919 index entries point to keyframes, but if that is not true we
1920 will instad skip until the next keyframe. */
1921 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1922 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1923 stream->index_table && parse->common.segment.rate > 0.0) {
1924 GstMatroskaTrackVideoContext *videocontext =
1925 (GstMatroskaTrackVideoContext *) stream;
1926 GstClockTime earliest_time;
1927 GstClockTime earliest_stream_time;
1929 GST_OBJECT_LOCK (parse);
1930 earliest_time = videocontext->earliest_time;
1931 GST_OBJECT_UNLOCK (parse);
1932 earliest_stream_time = gst_segment_to_position (&parse->common.segment,
1933 GST_FORMAT_TIME, earliest_time);
1935 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1936 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
1937 lace_time <= earliest_stream_time) {
1938 /* find index entry (keyframe) <= earliest_stream_time */
1939 GstMatroskaIndex *entry =
1940 gst_util_array_binary_search (stream->index_table->data,
1941 stream->index_table->len, sizeof (GstMatroskaIndex),
1942 (GCompareDataFunc) gst_matroska_index_seek_find,
1943 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
1945 /* if that entry (keyframe) is after the current the current
1946 buffer, we can skip pushing (and thus decoding) all
1947 buffers until that keyframe. */
1948 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
1949 entry->time > lace_time) {
1950 GST_LOG_OBJECT (parse, "Skipping lace before late keyframe");
1951 stream->set_discont = TRUE;
1957 sub = gst_buffer_create_sub (buf,
1958 GST_BUFFER_SIZE (buf) - size, lace_size[n]);
1959 GST_DEBUG_OBJECT (parse, "created subbuffer %p", sub);
1962 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1964 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1966 if (stream->encodings != NULL && stream->encodings->len > 0)
1967 sub = gst_matroska_decode_buffer (stream, sub);
1970 GST_WARNING_OBJECT (parse, "Decoding buffer failed");
1974 GST_BUFFER_TIMESTAMP (sub) = lace_time;
1976 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
1977 GstClockTime last_stop_end;
1979 /* Check if this stream is after segment stop */
1980 if (GST_CLOCK_TIME_IS_VALID (parse->common.segment.stop) &&
1981 lace_time >= parse->common.segment.stop) {
1982 GST_DEBUG_OBJECT (parse,
1983 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
1984 GST_TIME_ARGS (parse->common.segment.stop));
1985 gst_buffer_unref (sub);
1988 if (offset >= stream->to_offset) {
1989 GST_DEBUG_OBJECT (parse, "Stream %d after playback section",
1991 gst_buffer_unref (sub);
1995 /* handle gaps, e.g. non-zero start-time, or an cue index entry
1996 * that landed us with timestamps not quite intended */
1997 if (GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop) &&
1998 parse->segment.rate > 0.0) {
1999 GstClockTimeDiff diff;
2001 /* only send newsegments with increasing start times,
2002 * otherwise if these go back and forth downstream (sinks) increase
2003 * accumulated time and running_time */
2004 diff = GST_CLOCK_DIFF (parse->segment.last_stop, lace_time);
2005 if (diff > 2 * GST_SECOND && lace_time > parse->segment.start &&
2006 (!GST_CLOCK_TIME_IS_VALID (parse->segment.stop) ||
2007 lace_time < parse->segment.stop)) {
2008 GST_DEBUG_OBJECT (parse,
2009 "Gap of %" G_GINT64_FORMAT " ns detected in"
2010 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
2011 "Sending updated NEWSEGMENT events", diff,
2012 stream->index, GST_TIME_ARGS (stream->pos),
2013 GST_TIME_ARGS (lace_time));
2014 /* send newsegment events such that the gap is not accounted in
2015 * accum time, hence running_time */
2016 /* close ahead of gap */
2017 gst_matroska_parse_send_event (parse,
2018 gst_event_new_new_segment (TRUE, parse->segment.rate,
2019 parse->segment.format, parse->segment.last_stop,
2020 parse->segment.last_stop, parse->segment.last_stop));
2022 gst_matroska_parse_send_event (parse,
2023 gst_event_new_new_segment (FALSE, parse->segment.rate,
2024 parse->segment.format, lace_time, parse->segment.stop,
2026 /* align segment view with downstream,
2027 * prevents double-counting accum when closing segment */
2028 gst_segment_set_newsegment (&parse->segment, FALSE,
2029 parse->segment.rate, parse->segment.format, lace_time,
2030 parse->segment.stop, lace_time);
2031 parse->segment.last_stop = lace_time;
2035 if (!GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop)
2036 || parse->segment.last_stop < lace_time) {
2037 parse->segment.last_stop = lace_time;
2040 last_stop_end = lace_time;
2042 GST_BUFFER_DURATION (sub) = duration / laces;
2043 last_stop_end += GST_BUFFER_DURATION (sub);
2046 if (!GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) ||
2047 parse->last_stop_end < last_stop_end)
2048 parse->last_stop_end = last_stop_end;
2050 if (parse->segment.duration == -1 ||
2051 parse->segment.duration < lace_time) {
2052 gst_segment_set_duration (&parse->segment, GST_FORMAT_TIME,
2054 gst_element_post_message (GST_ELEMENT_CAST (parse),
2055 gst_message_new_duration (GST_OBJECT_CAST (parse),
2056 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
2060 stream->pos = lace_time;
2062 gst_matroska_parse_sync_streams (parse);
2064 if (stream->set_discont) {
2065 GST_DEBUG_OBJECT (parse, "marking DISCONT");
2066 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
2067 stream->set_discont = FALSE;
2070 /* reverse playback book-keeping */
2071 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
2072 stream->from_time = lace_time;
2073 if (stream->from_offset == -1)
2074 stream->from_offset = offset;
2076 GST_DEBUG_OBJECT (parse,
2077 "Pushing lace %d, data of size %d for stream %d, time=%"
2078 GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
2079 GST_BUFFER_SIZE (sub), stream_num,
2080 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
2081 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
2083 if (parse->element_index) {
2084 if (stream->index_writer_id == -1)
2085 gst_index_get_writer_id (parse->element_index,
2086 GST_OBJECT (stream->pad), &stream->index_writer_id);
2088 GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
2089 G_GUINT64_FORMAT " for writer id %d",
2090 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
2091 stream->index_writer_id);
2092 gst_index_add_association (parse->element_index,
2093 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
2094 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
2095 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
2096 cluster_offset, NULL);
2099 gst_buffer_set_caps (sub, GST_PAD_CAPS (parse->srcpad));
2101 /* Postprocess the buffers depending on the codec used */
2102 if (stream->postprocess_frame) {
2103 GST_LOG_OBJECT (parse, "running post process");
2104 ret = stream->postprocess_frame (GST_ELEMENT (parse), stream, &sub);
2107 ret = gst_pad_push (stream->pad, sub);
2108 if (parse->segment.rate < 0) {
2109 if (lace_time > parse->segment.stop && ret == GST_FLOW_EOS) {
2110 /* In reverse playback we can get a GST_FLOW_EOS when
2111 * we are at the end of the segment, so we just need to jump
2112 * back to the previous section. */
2113 GST_DEBUG_OBJECT (parse, "downstream has reached end of segment");
2118 ret = gst_matroska_parse_combine_flows (parse, stream, ret);
2122 size -= lace_size[n];
2123 if (lace_time != GST_CLOCK_TIME_NONE && duration)
2124 lace_time += duration / laces;
2126 lace_time = GST_CLOCK_TIME_NONE;
2132 gst_buffer_unmap (buf, &map);
2133 gst_buffer_unref (buf);
2142 GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
2143 /* non-fatal, try next block(group) */
2149 GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Data error"));
2150 /* non-fatal, try next block(group) */
2156 /* return FALSE if block(group) should be skipped (due to a seek) */
2157 static inline gboolean
2158 gst_matroska_parse_seek_block (GstMatroskaParse * parse)
2160 if (G_UNLIKELY (parse->seek_block)) {
2161 if (!(--parse->seek_block)) {
2164 GST_LOG_OBJECT (parse, "should skip block due to seek");
2172 static GstFlowReturn
2173 gst_matroska_parse_parse_contents_seekentry (GstMatroskaParse * parse,
2177 guint64 seek_pos = (guint64) - 1;
2178 guint32 seek_id = 0;
2181 DEBUG_ELEMENT_START (parse, ebml, "Seek");
2183 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2184 DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2188 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2189 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2193 case GST_MATROSKA_ID_SEEKID:
2197 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2200 GST_DEBUG_OBJECT (parse, "SeekID: %" G_GUINT64_FORMAT, t);
2205 case GST_MATROSKA_ID_SEEKPOSITION:
2209 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2212 if (t > G_MAXINT64) {
2213 GST_WARNING_OBJECT (parse,
2214 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
2218 GST_DEBUG_OBJECT (parse, "SeekPosition: %" G_GUINT64_FORMAT, t);
2224 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2230 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
2233 if (!seek_id || seek_pos == (guint64) - 1) {
2234 GST_WARNING_OBJECT (parse, "Incomplete seekhead entry (0x%x/%"
2235 G_GUINT64_FORMAT ")", seek_id, seek_pos);
2240 case GST_MATROSKA_ID_SEEKHEAD:
2243 case GST_MATROSKA_ID_CUES:
2244 case GST_MATROSKA_ID_TAGS:
2245 case GST_MATROSKA_ID_TRACKS:
2246 case GST_MATROSKA_ID_SEGMENTINFO:
2247 case GST_MATROSKA_ID_ATTACHMENTS:
2248 case GST_MATROSKA_ID_CHAPTERS:
2253 length = gst_matroska_read_common_get_length (&parse->common);
2255 if (length == (guint64) - 1) {
2256 GST_DEBUG_OBJECT (parse, "no upstream length, skipping SeakHead entry");
2260 /* check for validity */
2261 if (seek_pos + parse->common.ebml_segment_start + 12 >= length) {
2262 GST_WARNING_OBJECT (parse,
2263 "SeekHead reference lies outside file!" " (%"
2264 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
2265 G_GUINT64_FORMAT ")", seek_pos, parse->common.ebml_segment_start,
2270 /* only pick up index location when streaming */
2271 if (seek_id == GST_MATROSKA_ID_CUES) {
2272 parse->index_offset = seek_pos + parse->common.ebml_segment_start;
2273 GST_DEBUG_OBJECT (parse, "Cues located at offset %" G_GUINT64_FORMAT,
2274 parse->index_offset);
2280 GST_DEBUG_OBJECT (parse, "Ignoring Seek entry for ID=0x%x", seek_id);
2283 DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2288 static GstFlowReturn
2289 gst_matroska_parse_parse_contents (GstMatroskaParse * parse, GstEbmlRead * ebml)
2291 GstFlowReturn ret = GST_FLOW_OK;
2294 DEBUG_ELEMENT_START (parse, ebml, "SeekHead");
2296 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2297 DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2301 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2302 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2306 case GST_MATROSKA_ID_SEEKENTRY:
2308 ret = gst_matroska_parse_parse_contents_seekentry (parse, ebml);
2309 /* Ignore EOS and errors here */
2310 if (ret != GST_FLOW_OK) {
2311 GST_DEBUG_OBJECT (parse, "Ignoring %s", gst_flow_get_name (ret));
2318 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2324 DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2329 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
2331 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
2333 static inline GstFlowReturn
2334 gst_matroska_parse_check_read_size (GstMatroskaParse * parse, guint64 bytes)
2336 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
2337 /* only a few blocks are expected/allowed to be large,
2338 * and will be recursed into, whereas others will be read and must fit */
2339 /* fatal in streaming case, as we can't step over easily */
2340 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2341 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
2342 "file might be corrupt.", bytes));
2343 return GST_FLOW_ERROR;
2349 /* returns TRUE if we truely are in error state, and should give up */
2350 static inline gboolean
2351 gst_matroska_parse_check_parse_error (GstMatroskaParse * parse)
2355 /* sigh, one last attempt above and beyond call of duty ...;
2356 * search for cluster mark following current pos */
2357 pos = parse->common.offset;
2358 GST_WARNING_OBJECT (parse, "parse error, looking for next cluster");
2359 if (gst_matroska_parse_search_cluster (parse, &pos) != GST_FLOW_OK) {
2360 /* did not work, give up */
2363 GST_DEBUG_OBJECT (parse, "... found at %" G_GUINT64_FORMAT, pos);
2364 /* try that position */
2365 parse->common.offset = pos;
2370 /* initializes @ebml with @bytes from input stream at current offset.
2371 * Returns EOS if insufficient available,
2372 * ERROR if too much was attempted to read. */
2373 static inline GstFlowReturn
2374 gst_matroska_parse_take (GstMatroskaParse * parse, guint64 bytes,
2377 GstBuffer *buffer = NULL;
2378 GstFlowReturn ret = GST_FLOW_OK;
2380 GST_LOG_OBJECT (parse, "taking %" G_GUINT64_FORMAT " bytes for parsing",
2382 ret = gst_matroska_parse_check_read_size (parse, bytes);
2383 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
2384 /* otherwise fatal */
2385 ret = GST_FLOW_ERROR;
2388 if (gst_adapter_available (parse->common.adapter) >= bytes)
2389 buffer = gst_adapter_take_buffer (parse->common.adapter, bytes);
2392 if (G_LIKELY (buffer)) {
2393 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (parse), buffer,
2394 parse->common.offset);
2395 parse->common.offset += bytes;
2402 gst_matroska_parse_check_seekability (GstMatroskaParse * parse)
2405 gboolean seekable = FALSE;
2406 gint64 start = -1, stop = -1;
2408 query = gst_query_new_seeking (GST_FORMAT_BYTES);
2409 if (!gst_pad_peer_query (parse->common.sinkpad, query)) {
2410 GST_DEBUG_OBJECT (parse, "seeking query failed");
2414 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
2416 /* try harder to query upstream size if we didn't get it the first time */
2417 if (seekable && stop == -1) {
2418 GST_DEBUG_OBJECT (parse, "doing duration query to fix up unset stop");
2419 gst_pad_peer_query_duration (parse->common.sinkpad, GST_FORMAT_BYTES,
2423 /* if upstream doesn't know the size, it's likely that it's not seekable in
2424 * practice even if it technically may be seekable */
2425 if (seekable && (start != 0 || stop <= start)) {
2426 GST_DEBUG_OBJECT (parse, "seekable but unknown start/stop -> disable");
2431 GST_INFO_OBJECT (parse, "seekable: %d (%" G_GUINT64_FORMAT " - %"
2432 G_GUINT64_FORMAT ")", seekable, start, stop);
2433 parse->seekable = seekable;
2435 gst_query_unref (query);
2439 static GstFlowReturn
2440 gst_matroska_parse_find_tracks (GstMatroskaParse * parse)
2446 GstFlowReturn ret = GST_FLOW_OK;
2448 GST_WARNING_OBJECT (parse,
2449 "Found Cluster element before Tracks, searching Tracks");
2452 before_pos = parse->common.offset;
2454 /* Search Tracks element */
2456 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2457 GST_ELEMENT_CAST (parse), &id, &length, &needed);
2458 if (ret != GST_FLOW_OK)
2461 if (id != GST_MATROSKA_ID_TRACKS) {
2462 /* we may be skipping large cluster here, so forego size check etc */
2463 /* ... but we can't skip undefined size; force error */
2464 if (length == G_MAXUINT64) {
2465 ret = gst_matroska_parse_check_read_size (parse, length);
2468 parse->common.offset += needed;
2469 parse->offset += length;
2474 /* will lead to track parsing ... */
2475 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2480 parse->offset = before_pos;
2486 #define GST_READ_CHECK(stmt) \
2488 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
2489 if (ret == GST_FLOW_OVERFLOW) { \
2490 ret = GST_FLOW_OK; \
2497 gst_matroska_parse_accumulate_streamheader (GstMatroskaParse * parse,
2500 if (parse->pushed_headers) {
2501 GST_WARNING_OBJECT (parse,
2502 "Accumulating headers, but headers are already pushed");
2505 if (parse->streamheader) {
2506 parse->streamheader = gst_buffer_append (parse->streamheader,
2507 gst_buffer_ref (buffer));
2509 parse->streamheader = gst_buffer_ref (buffer);
2512 GST_DEBUG ("%" G_GSIZE_FORMAT, gst_buffer_get_size (parse->streamheader));
2515 static GstFlowReturn
2516 gst_matroska_parse_output (GstMatroskaParse * parse, GstBuffer * buffer,
2519 GstFlowReturn ret = GST_FLOW_OK;
2521 if (!parse->pushed_headers) {
2524 GValue streamheader = { 0 };
2525 GValue bufval = { 0 };
2528 caps = gst_pad_get_current_caps (parse->common.sinkpad);
2529 /* FIXME: could run typefinding over header and pick better default */
2531 caps = gst_caps_new_empty_simple ("video/x-matroska");
2533 caps = gst_caps_make_writable (caps);
2535 s = gst_caps_get_structure (caps, 0);
2536 g_value_init (&streamheader, GST_TYPE_ARRAY);
2537 g_value_init (&bufval, GST_TYPE_BUFFER);
2538 buf = gst_buffer_copy (parse->streamheader);
2539 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2540 gst_value_set_buffer (&bufval, buf);
2541 gst_buffer_unref (buf);
2542 gst_value_array_append_value (&streamheader, &bufval);
2543 g_value_unset (&bufval);
2544 gst_structure_set_value (s, "streamheader", &streamheader);
2545 g_value_unset (&streamheader);
2546 //gst_caps_replace (parse->caps, caps);
2547 gst_pad_set_caps (parse->srcpad, caps);
2549 buf = gst_buffer_copy (parse->streamheader);
2550 gst_caps_unref (caps);
2552 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2553 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2554 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
2556 ret = gst_pad_push (parse->srcpad, buf);
2558 parse->pushed_headers = TRUE;
2562 GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2564 GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2566 if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE) {
2567 parse->last_timestamp = GST_BUFFER_TIMESTAMP (buffer);
2569 GST_BUFFER_TIMESTAMP (buffer) = parse->last_timestamp;
2571 ret = gst_pad_push (parse->srcpad, gst_buffer_ref (buffer));
2576 static GstFlowReturn
2577 gst_matroska_parse_parse_id (GstMatroskaParse * parse, guint32 id,
2578 guint64 length, guint needed)
2580 GstEbmlRead ebml = { 0, };
2581 GstFlowReturn ret = GST_FLOW_OK;
2583 //GstBuffer *buffer;
2585 GST_DEBUG_OBJECT (parse, "Parsing Element id 0x%x, "
2586 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
2589 if (gst_adapter_available (parse->adapter) >= length + needed) {
2590 buffer = gst_adapter_take_buffer (parse->adapter, length + needed);
2591 gst_pad_push (parse->srcpad, buffer);
2595 //GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2602 /* if we plan to read and parse this element, we need prefix (id + length)
2603 * and the contents */
2604 /* mind about overflow wrap-around when dealing with undefined size */
2606 if (G_LIKELY (length != G_MAXUINT64))
2609 switch (parse->common.state) {
2610 case GST_MATROSKA_READ_STATE_START:
2612 case GST_EBML_ID_HEADER:
2613 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2614 ret = gst_matroska_read_common_parse_header (&parse->common, &ebml);
2615 if (ret != GST_FLOW_OK)
2617 parse->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
2618 gst_matroska_parse_check_seekability (parse);
2619 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2622 goto invalid_header;
2626 case GST_MATROSKA_READ_STATE_SEGMENT:
2628 case GST_MATROSKA_ID_SEGMENT:
2629 /* eat segment prefix */
2630 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2631 GST_DEBUG_OBJECT (parse,
2632 "Found Segment start at offset %" G_GUINT64_FORMAT,
2633 parse->common.offset);
2634 /* seeks are from the beginning of the segment,
2635 * after the segment ID/length */
2636 parse->common.ebml_segment_start = parse->common.offset;
2637 parse->common.state = GST_MATROSKA_READ_STATE_HEADER;
2638 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2641 GST_WARNING_OBJECT (parse,
2642 "Expected a Segment ID (0x%x), but received 0x%x!",
2643 GST_MATROSKA_ID_SEGMENT, id);
2644 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2645 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2649 case GST_MATROSKA_READ_STATE_SCANNING:
2650 if (id != GST_MATROSKA_ID_CLUSTER &&
2651 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
2654 case GST_MATROSKA_READ_STATE_HEADER:
2655 case GST_MATROSKA_READ_STATE_DATA:
2656 case GST_MATROSKA_READ_STATE_SEEK:
2658 case GST_MATROSKA_ID_SEGMENTINFO:
2659 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2660 if (!parse->common.segmentinfo_parsed) {
2661 ret = gst_matroska_read_common_parse_info (&parse->common,
2662 GST_ELEMENT_CAST (parse), &ebml);
2664 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2666 case GST_MATROSKA_ID_TRACKS:
2667 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2668 if (!parse->tracks_parsed) {
2669 ret = gst_matroska_parse_parse_tracks (parse, &ebml);
2671 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2673 case GST_MATROSKA_ID_CLUSTER:
2674 if (G_UNLIKELY (!parse->tracks_parsed)) {
2675 GST_DEBUG_OBJECT (parse, "Cluster before Track");
2676 goto not_streamable;
2678 if (G_UNLIKELY (parse->common.state
2679 == GST_MATROSKA_READ_STATE_HEADER)) {
2680 parse->common.state = GST_MATROSKA_READ_STATE_DATA;
2681 parse->first_cluster_offset = parse->common.offset;
2682 GST_DEBUG_OBJECT (parse, "signaling no more pads");
2684 parse->cluster_time = GST_CLOCK_TIME_NONE;
2685 parse->cluster_offset = parse->common.offset;
2686 if (G_UNLIKELY (!parse->seek_first && parse->seek_block)) {
2687 GST_DEBUG_OBJECT (parse, "seek target block %" G_GUINT64_FORMAT
2688 " not found in Cluster, trying next Cluster's first block instead",
2690 parse->seek_block = 0;
2692 parse->seek_first = FALSE;
2693 /* record next cluster for recovery */
2694 if (read != G_MAXUINT64)
2695 parse->next_cluster_offset = parse->cluster_offset + read;
2696 /* eat cluster prefix */
2697 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2698 ret = gst_matroska_parse_output (parse, ebml.buf, TRUE);
2699 //gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2701 case GST_MATROSKA_ID_CLUSTERTIMECODE:
2705 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2706 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
2708 GST_DEBUG_OBJECT (parse, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
2709 parse->cluster_time = num;
2711 if (parse->common.element_index) {
2712 if (parse->common.element_index_writer_id == -1)
2713 gst_index_get_writer_id (parse->common.element_index,
2714 GST_OBJECT (parse), &parse->common.element_index_writer_id);
2715 GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
2716 G_GUINT64_FORMAT " for writer id %d",
2717 GST_TIME_ARGS (parse->cluster_time), parse->cluster_offset,
2718 parse->common.element_index_writer_id);
2719 gst_index_add_association (parse->common.element_index,
2720 parse->common.element_index_writer_id,
2721 GST_ASSOCIATION_FLAG_KEY_UNIT,
2722 GST_FORMAT_TIME, parse->cluster_time,
2723 GST_FORMAT_BYTES, parse->cluster_offset, NULL);
2726 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2729 case GST_MATROSKA_ID_BLOCKGROUP:
2730 if (!gst_matroska_parse_seek_block (parse))
2732 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2733 DEBUG_ELEMENT_START (parse, &ebml, "BlockGroup");
2734 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
2735 ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
2736 &ebml, parse->cluster_time, parse->cluster_offset, FALSE);
2738 DEBUG_ELEMENT_STOP (parse, &ebml, "BlockGroup", ret);
2739 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2741 case GST_MATROSKA_ID_SIMPLEBLOCK:
2742 if (!gst_matroska_parse_seek_block (parse))
2744 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2745 DEBUG_ELEMENT_START (parse, &ebml, "SimpleBlock");
2746 ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
2747 &ebml, parse->cluster_time, parse->cluster_offset, TRUE);
2748 DEBUG_ELEMENT_STOP (parse, &ebml, "SimpleBlock", ret);
2749 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2751 case GST_MATROSKA_ID_ATTACHMENTS:
2752 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2753 if (!parse->common.attachments_parsed) {
2754 ret = gst_matroska_read_common_parse_attachments (&parse->common,
2755 GST_ELEMENT_CAST (parse), &ebml);
2757 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2759 case GST_MATROSKA_ID_TAGS:
2760 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2761 ret = gst_matroska_read_common_parse_metadata (&parse->common,
2762 GST_ELEMENT_CAST (parse), &ebml);
2763 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2765 case GST_MATROSKA_ID_CHAPTERS:
2766 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2767 ret = gst_matroska_read_common_parse_chapters (&parse->common, &ebml);
2768 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2770 case GST_MATROSKA_ID_SEEKHEAD:
2771 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2772 ret = gst_matroska_parse_parse_contents (parse, &ebml);
2773 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2775 case GST_MATROSKA_ID_CUES:
2776 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2777 if (!parse->common.index_parsed) {
2778 ret = gst_matroska_read_common_parse_index (&parse->common, &ebml);
2779 /* only push based; delayed index building */
2780 if (ret == GST_FLOW_OK
2781 && parse->common.state == GST_MATROSKA_READ_STATE_SEEK) {
2784 GST_OBJECT_LOCK (parse);
2785 event = parse->seek_event;
2786 parse->seek_event = NULL;
2787 GST_OBJECT_UNLOCK (parse);
2790 /* unlikely to fail, since we managed to seek to this point */
2791 if (!gst_matroska_parse_handle_seek_event (parse, NULL, event))
2793 /* resume data handling, main thread clear to seek again */
2794 GST_OBJECT_LOCK (parse);
2795 parse->common.state = GST_MATROSKA_READ_STATE_DATA;
2796 GST_OBJECT_UNLOCK (parse);
2799 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2801 case GST_MATROSKA_ID_POSITION:
2802 case GST_MATROSKA_ID_PREVSIZE:
2803 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
2804 case GST_MATROSKA_ID_SILENTTRACKS:
2805 GST_DEBUG_OBJECT (parse,
2806 "Skipping Cluster subelement 0x%x - ignoring", id);
2810 GST_DEBUG_OBJECT (parse, "skipping Element 0x%x", id);
2811 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2812 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2818 if (ret == GST_FLOW_PARSE)
2822 gst_ebml_read_clear (&ebml);
2828 /* simply exit, maybe not enough data yet */
2829 /* no ebml to clear if read error */
2834 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2835 ("Failed to parse Element 0x%x", id));
2836 ret = GST_FLOW_ERROR;
2841 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2842 ("File layout does not permit streaming"));
2843 ret = GST_FLOW_ERROR;
2849 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2850 ("No Tracks element found"));
2851 ret = GST_FLOW_ERROR;
2857 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Invalid header"));
2858 ret = GST_FLOW_ERROR;
2863 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Failed to seek"));
2864 ret = GST_FLOW_ERROR;
2871 gst_matroska_parse_loop (GstPad * pad)
2873 GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
2879 /* If we have to close a segment, send a new segment to do this now */
2880 if (G_LIKELY (parse->common.state == GST_MATROSKA_READ_STATE_DATA)) {
2881 if (G_UNLIKELY (parse->close_segment)) {
2882 gst_matroska_parse_send_event (parse, parse->close_segment);
2883 parse->close_segment = NULL;
2885 if (G_UNLIKELY (parse->new_segment)) {
2886 gst_matroska_parse_send_event (parse, parse->new_segment);
2887 parse->new_segment = NULL;
2891 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2892 GST_ELEMENT_CAST (parse), &id, &length, &needed);
2893 if (ret == GST_FLOW_EOS)
2895 if (ret != GST_FLOW_OK) {
2896 if (gst_matroska_parse_check_parse_error (parse))
2902 GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2903 "size %" G_GUINT64_FORMAT ", needed %d", parse->offset, id,
2906 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2907 if (ret == GST_FLOW_EOS)
2909 if (ret != GST_FLOW_OK)
2912 /* check if we're at the end of a configured segment */
2913 if (G_LIKELY (parse->src->len)) {
2916 g_assert (parse->num_streams == parse->src->len);
2917 for (i = 0; i < parse->src->len; i++) {
2918 GstMatroskaTrackContext *context = g_ptr_array_index (parse->src, i);
2919 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
2920 GST_TIME_ARGS (context->pos));
2921 if (context->eos == FALSE)
2925 GST_INFO_OBJECT (parse, "All streams are EOS");
2931 if (G_UNLIKELY (parse->offset ==
2932 gst_matroska_read_common_get_length (&parse->common))) {
2933 GST_LOG_OBJECT (parse, "Reached end of stream");
2943 if (parse->segment.rate < 0.0) {
2944 ret = gst_matroska_parse_seek_to_previous_keyframe (parse);
2945 if (ret == GST_FLOW_OK)
2952 const gchar *reason = gst_flow_get_name (ret);
2953 gboolean push_eos = FALSE;
2955 GST_LOG_OBJECT (parse, "pausing task, reason %s", reason);
2956 parse->segment_running = FALSE;
2957 gst_pad_pause_task (parse->common.sinkpad);
2959 if (ret == GST_FLOW_EOS) {
2960 /* perform EOS logic */
2962 /* Close the segment, i.e. update segment stop with the duration
2963 * if no stop was set */
2964 if (GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) &&
2965 !GST_CLOCK_TIME_IS_VALID (parse->segment.stop)) {
2967 gst_event_new_new_segment_full (TRUE, parse->segment.rate,
2968 parse->segment.applied_rate, parse->segment.format,
2969 parse->segment.start,
2970 MAX (parse->last_stop_end, parse->segment.start),
2971 parse->segment.time);
2972 gst_matroska_parse_send_event (parse, event);
2975 if (parse->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2978 /* for segment playback we need to post when (in stream time)
2979 * we stopped, this is either stop (when set) or the duration. */
2980 if ((stop = parse->segment.stop) == -1)
2981 stop = parse->last_stop_end;
2983 GST_LOG_OBJECT (parse, "Sending segment done, at end of segment");
2984 gst_element_post_message (GST_ELEMENT (parse),
2985 gst_message_new_segment_done (GST_OBJECT (parse), GST_FORMAT_TIME,
2990 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
2991 /* for fatal errors we post an error message */
2992 GST_ELEMENT_ERROR (parse, STREAM, FAILED, (NULL),
2993 ("stream stopped, reason %s", reason));
2997 /* send EOS, and prevent hanging if no streams yet */
2998 GST_LOG_OBJECT (parse, "Sending EOS, at end of stream");
2999 if (!gst_matroska_parse_send_event (parse, gst_event_new_eos ()) &&
3000 (ret == GST_FLOW_EOS)) {
3001 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3002 (NULL), ("got eos but no streams (yet)"));
3011 * Create and push a flushing seek event upstream
3014 perform_seek_to_offset (GstMatroskaParse * parse, guint64 offset)
3019 GST_DEBUG_OBJECT (parse, "Seeking to %" G_GUINT64_FORMAT, offset);
3022 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
3023 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
3024 GST_SEEK_TYPE_NONE, -1);
3026 res = gst_pad_push_event (parse->common.sinkpad, event);
3028 /* newsegment event will update offset */
3032 static GstFlowReturn
3033 gst_matroska_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
3035 GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
3037 GstFlowReturn ret = GST_FLOW_OK;
3042 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
3043 GST_DEBUG_OBJECT (parse, "got DISCONT");
3044 gst_adapter_clear (parse->common.adapter);
3045 GST_OBJECT_LOCK (parse);
3046 gst_matroska_read_common_reset_streams (&parse->common,
3047 GST_CLOCK_TIME_NONE, FALSE);
3048 GST_OBJECT_UNLOCK (parse);
3051 gst_adapter_push (parse->common.adapter, buffer);
3055 available = gst_adapter_available (parse->common.adapter);
3057 ret = gst_matroska_read_common_peek_id_length_push (&parse->common,
3058 GST_ELEMENT_CAST (parse), &id, &length, &needed);
3059 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS))
3062 GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
3063 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
3064 parse->common.offset, id, length, needed, available);
3066 if (needed > available)
3069 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
3070 if (ret == GST_FLOW_EOS) {
3071 /* need more data */
3073 } else if (ret != GST_FLOW_OK) {
3080 gst_matroska_parse_handle_sink_event (GstPad * pad, GstObject * parent,
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_SEGMENT:
3092 const GstSegment *segment;
3094 /* some debug output */
3095 gst_event_parse_segment (event, &segment);
3096 GST_DEBUG_OBJECT (parse,
3097 "received format %d newsegment %" GST_SEGMENT_FORMAT,
3098 segment->format, segment);
3100 if (parse->common.state < GST_MATROSKA_READ_STATE_DATA) {
3101 GST_DEBUG_OBJECT (parse, "still starting");
3105 /* we only expect a BYTE segment, e.g. following a seek */
3106 if (segment->format != GST_FORMAT_BYTES) {
3107 GST_DEBUG_OBJECT (parse, "unsupported segment format, ignoring");
3111 GST_DEBUG_OBJECT (parse, "clearing segment state");
3112 /* clear current segment leftover */
3113 gst_adapter_clear (parse->common.adapter);
3114 /* and some streaming setup */
3115 parse->common.offset = segment->start;
3116 /* do not know where we are;
3117 * need to come across a cluster and generate newsegment */
3118 parse->common.segment.position = GST_CLOCK_TIME_NONE;
3119 parse->cluster_time = GST_CLOCK_TIME_NONE;
3120 parse->cluster_offset = 0;
3121 parse->need_newsegment = TRUE;
3122 /* but keep some of the upstream segment */
3123 parse->common.segment.rate = segment->rate;
3125 /* chain will send initial newsegment after pads have been added,
3126 * or otherwise come up with one */
3127 GST_DEBUG_OBJECT (parse, "eating event");
3128 gst_event_unref (event);
3134 if (parse->common.state != GST_MATROSKA_READ_STATE_DATA) {
3135 gst_event_unref (event);
3136 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3137 (NULL), ("got eos and didn't receive a complete header object"));
3138 } else if (parse->common.num_streams == 0) {
3139 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3140 (NULL), ("got eos but no streams (yet)"));
3142 gst_matroska_parse_send_event (parse, event);
3146 case GST_EVENT_FLUSH_STOP:
3148 gst_adapter_clear (parse->common.adapter);
3149 GST_OBJECT_LOCK (parse);
3150 gst_matroska_read_common_reset_streams (&parse->common,
3151 GST_CLOCK_TIME_NONE, TRUE);
3152 GST_OBJECT_UNLOCK (parse);
3153 parse->common.segment.position = GST_CLOCK_TIME_NONE;
3154 parse->cluster_time = GST_CLOCK_TIME_NONE;
3155 parse->cluster_offset = 0;
3159 res = gst_pad_event_default (pad, parent, event);
3168 gst_matroska_parse_set_index (GstElement * element, GstIndex * index)
3170 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3172 GST_OBJECT_LOCK (parse);
3173 if (parse->common.element_index)
3174 gst_object_unref (parse->common.element_index);
3175 parse->common.element_index = index ? gst_object_ref (index) : NULL;
3176 GST_OBJECT_UNLOCK (parse);
3177 GST_DEBUG_OBJECT (parse, "Set index %" GST_PTR_FORMAT,
3178 parse->common.element_index);
3182 gst_matroska_parse_get_index (GstElement * element)
3184 GstIndex *result = NULL;
3185 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3187 GST_OBJECT_LOCK (parse);
3188 if (parse->common.element_index)
3189 result = gst_object_ref (parse->common.element_index);
3190 GST_OBJECT_UNLOCK (parse);
3192 GST_DEBUG_OBJECT (parse, "Returning index %" GST_PTR_FORMAT, result);
3198 static GstStateChangeReturn
3199 gst_matroska_parse_change_state (GstElement * element,
3200 GstStateChange transition)
3202 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3203 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
3205 /* handle upwards state changes here */
3206 switch (transition) {
3211 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
3213 /* handle downwards state changes */
3214 switch (transition) {
3215 case GST_STATE_CHANGE_PAUSED_TO_READY:
3216 gst_matroska_parse_reset (GST_ELEMENT (parse));
3226 gst_matroska_parse_plugin_init (GstPlugin * plugin)
3230 /* create an elementfactory for the matroska_parse element */
3231 if (!gst_element_register (plugin, "matroskaparse",
3232 GST_RANK_NONE, GST_TYPE_MATROSKA_PARSE))