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,
114 GstObject * parent, GstEvent * event);
115 static gboolean gst_matroska_parse_handle_src_query (GstPad * pad,
116 GstObject * parent, GstQuery * query);
118 static gboolean gst_matroska_parse_handle_sink_event (GstPad * pad,
119 GstObject * parent, GstEvent * event);
120 static GstFlowReturn gst_matroska_parse_chain (GstPad * pad,
121 GstObject * parent, GstBuffer * buffer);
123 static GstStateChangeReturn
124 gst_matroska_parse_change_state (GstElement * element,
125 GstStateChange transition);
127 gst_matroska_parse_set_index (GstElement * element, GstIndex * index);
128 static GstIndex *gst_matroska_parse_get_index (GstElement * element);
131 static void gst_matroska_parse_reset (GstElement * element);
132 static gboolean perform_seek_to_offset (GstMatroskaParse * parse,
135 GType gst_matroska_parse_get_type (void);
136 #define parent_class gst_matroska_parse_parent_class
137 G_DEFINE_TYPE (GstMatroskaParse, gst_matroska_parse, GST_TYPE_ELEMENT);
140 gst_matroska_parse_finalize (GObject * object)
142 GstMatroskaParse *parse = GST_MATROSKA_PARSE (object);
144 if (parse->common.src) {
145 g_ptr_array_free (parse->common.src, TRUE);
146 parse->common.src = NULL;
149 if (parse->common.global_tags) {
150 gst_tag_list_free (parse->common.global_tags);
151 parse->common.global_tags = NULL;
154 g_object_unref (parse->common.adapter);
156 G_OBJECT_CLASS (parent_class)->finalize (object);
160 gst_matroska_parse_class_init (GstMatroskaParseClass * klass)
162 GObjectClass *gobject_class = (GObjectClass *) klass;
163 GstElementClass *gstelement_class = (GstElementClass *) klass;
165 GST_DEBUG_CATEGORY_INIT (matroskaparse_debug, "matroskaparse", 0,
168 gobject_class->finalize = gst_matroska_parse_finalize;
170 gstelement_class->change_state =
171 GST_DEBUG_FUNCPTR (gst_matroska_parse_change_state);
172 gstelement_class->send_event =
173 GST_DEBUG_FUNCPTR (gst_matroska_parse_element_send_event);
174 gstelement_class->query =
175 GST_DEBUG_FUNCPTR (gst_matroska_parse_element_query);
177 gstelement_class->set_index =
178 GST_DEBUG_FUNCPTR (gst_matroska_parse_set_index);
179 gstelement_class->get_index =
180 GST_DEBUG_FUNCPTR (gst_matroska_parse_get_index);
182 gst_element_class_add_pad_template (gstelement_class,
183 gst_static_pad_template_get (&src_templ));
184 gst_element_class_add_pad_template (gstelement_class,
185 gst_static_pad_template_get (&sink_templ));
187 gst_element_class_set_details_simple (gstelement_class,
188 "Matroska parser", "Codec/Parser",
189 "Parses Matroska/WebM streams into video/audio/subtitles",
190 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
194 gst_matroska_parse_init (GstMatroskaParse * parse)
196 parse->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
198 gst_pad_set_chain_function (parse->common.sinkpad,
199 GST_DEBUG_FUNCPTR (gst_matroska_parse_chain));
200 gst_pad_set_event_function (parse->common.sinkpad,
201 GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_sink_event));
202 gst_element_add_pad (GST_ELEMENT (parse), parse->common.sinkpad);
204 parse->srcpad = gst_pad_new_from_static_template (&src_templ, "src");
205 gst_pad_set_event_function (parse->srcpad,
206 GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_event));
207 gst_pad_set_query_function (parse->srcpad,
208 GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_query));
209 gst_pad_use_fixed_caps (parse->srcpad);
211 gst_element_add_pad (GST_ELEMENT (parse), parse->srcpad);
213 /* initial stream no. */
214 parse->common.src = NULL;
216 parse->common.writing_app = NULL;
217 parse->common.muxing_app = NULL;
218 parse->common.index = NULL;
219 parse->common.global_tags = NULL;
221 parse->common.adapter = gst_adapter_new ();
223 GST_OBJECT_FLAG_SET (parse, GST_ELEMENT_FLAG_INDEXABLE);
226 gst_matroska_parse_reset (GST_ELEMENT (parse));
230 gst_matroska_track_free (GstMatroskaTrackContext * track)
232 g_free (track->codec_id);
233 g_free (track->codec_name);
234 g_free (track->name);
235 g_free (track->language);
236 g_free (track->codec_priv);
237 g_free (track->codec_state);
239 if (track->encodings != NULL) {
242 for (i = 0; i < track->encodings->len; ++i) {
243 GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
244 GstMatroskaTrackEncoding,
247 g_free (enc->comp_settings);
249 g_array_free (track->encodings, TRUE);
252 if (track->pending_tags)
253 gst_tag_list_free (track->pending_tags);
255 if (track->index_table)
256 g_array_free (track->index_table, TRUE);
262 gst_matroska_parse_free_parsed_el (gpointer mem, gpointer user_data)
264 g_slice_free (guint64, mem);
268 gst_matroska_parse_reset (GstElement * element)
270 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
273 GST_DEBUG_OBJECT (parse, "Resetting state");
276 parse->common.state = GST_MATROSKA_READ_STATE_START;
278 /* clean up existing streams */
279 if (parse->common.src) {
280 g_assert (parse->common.src->len == parse->common.num_streams);
281 for (i = 0; i < parse->common.src->len; i++) {
282 GstMatroskaTrackContext *context = g_ptr_array_index (parse->common.src,
285 gst_caps_replace (&context->caps, NULL);
286 gst_matroska_track_free (context);
288 g_ptr_array_free (parse->common.src, TRUE);
290 parse->common.src = g_ptr_array_new ();
292 parse->common.num_streams = 0;
293 parse->num_a_streams = 0;
294 parse->num_t_streams = 0;
295 parse->num_v_streams = 0;
297 /* reset media info */
298 g_free (parse->common.writing_app);
299 parse->common.writing_app = NULL;
300 g_free (parse->common.muxing_app);
301 parse->common.muxing_app = NULL;
304 if (parse->common.index) {
305 g_array_free (parse->common.index, TRUE);
306 parse->common.index = NULL;
311 parse->common.time_scale = 1000000;
312 parse->common.created = G_MININT64;
314 parse->common.index_parsed = FALSE;
315 parse->tracks_parsed = FALSE;
316 parse->common.segmentinfo_parsed = FALSE;
317 parse->common.attachments_parsed = FALSE;
319 g_list_foreach (parse->common.tags_parsed,
320 (GFunc) gst_matroska_parse_free_parsed_el, NULL);
321 g_list_free (parse->common.tags_parsed);
322 parse->common.tags_parsed = NULL;
324 g_list_foreach (parse->seek_parsed,
325 (GFunc) gst_matroska_parse_free_parsed_el, NULL);
326 g_list_free (parse->seek_parsed);
327 parse->seek_parsed = NULL;
329 gst_segment_init (&parse->common.segment, GST_FORMAT_TIME);
330 parse->last_stop_end = GST_CLOCK_TIME_NONE;
331 parse->seek_block = 0;
333 parse->common.offset = 0;
334 parse->cluster_time = GST_CLOCK_TIME_NONE;
335 parse->cluster_offset = 0;
336 parse->next_cluster_offset = 0;
337 parse->index_offset = 0;
338 parse->seekable = FALSE;
339 parse->need_newsegment = FALSE;
340 parse->building_index = FALSE;
341 if (parse->seek_event) {
342 gst_event_unref (parse->seek_event);
343 parse->seek_event = NULL;
346 parse->seek_index = NULL;
347 parse->seek_entry = 0;
349 if (parse->close_segment) {
350 gst_event_unref (parse->close_segment);
351 parse->close_segment = NULL;
354 if (parse->new_segment) {
355 gst_event_unref (parse->new_segment);
356 parse->new_segment = NULL;
359 if (parse->common.element_index) {
360 gst_object_unref (parse->common.element_index);
361 parse->common.element_index = NULL;
363 parse->common.element_index_writer_id = -1;
365 if (parse->common.global_tags) {
366 gst_tag_list_free (parse->common.global_tags);
368 parse->common.global_tags = gst_tag_list_new_empty ();
370 if (parse->common.cached_buffer) {
371 gst_buffer_unref (parse->common.cached_buffer);
372 parse->common.cached_buffer = NULL;
375 if (parse->streamheader != NULL) {
376 gst_buffer_unref (parse->streamheader);
377 parse->streamheader = NULL;
382 gst_matroska_parse_add_stream (GstMatroskaParse * parse, GstEbmlRead * ebml)
384 GstMatroskaTrackContext *context;
388 DEBUG_ELEMENT_START (parse, ebml, "TrackEntry");
390 /* start with the master */
391 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
392 DEBUG_ELEMENT_STOP (parse, ebml, "TrackEntry", ret);
396 /* allocate generic... if we know the type, we'll g_renew()
397 * with the precise type */
398 context = g_new0 (GstMatroskaTrackContext, 1);
399 g_ptr_array_add (parse->common.src, context);
400 context->index = parse->common.num_streams;
401 context->index_writer_id = -1;
402 context->type = 0; /* no type yet */
403 context->default_duration = 0;
405 context->set_discont = TRUE;
406 context->timecodescale = 1.0;
408 GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
409 GST_MATROSKA_TRACK_LACING;
410 context->last_flow = GST_FLOW_OK;
411 context->to_offset = G_MAXINT64;
412 context->alignment = 1;
413 parse->common.num_streams++;
414 g_assert (parse->common.src->len == parse->common.num_streams);
416 GST_DEBUG_OBJECT (parse, "Stream number %d", context->index);
418 /* try reading the trackentry headers */
419 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
420 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
424 /* track number (unique stream ID) */
425 case GST_MATROSKA_ID_TRACKNUMBER:{
428 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
432 GST_ERROR_OBJECT (parse, "Invalid TrackNumber 0");
433 ret = GST_FLOW_ERROR;
435 } else if (!gst_matroska_read_common_tracknumber_unique (&parse->common,
437 GST_ERROR_OBJECT (parse, "TrackNumber %" G_GUINT64_FORMAT
438 " is not unique", num);
439 ret = GST_FLOW_ERROR;
443 GST_DEBUG_OBJECT (parse, "TrackNumber: %" G_GUINT64_FORMAT, num);
447 /* track UID (unique identifier) */
448 case GST_MATROSKA_ID_TRACKUID:{
451 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
455 GST_ERROR_OBJECT (parse, "Invalid TrackUID 0");
456 ret = GST_FLOW_ERROR;
460 GST_DEBUG_OBJECT (parse, "TrackUID: %" G_GUINT64_FORMAT, num);
465 /* track type (video, audio, combined, subtitle, etc.) */
466 case GST_MATROSKA_ID_TRACKTYPE:{
469 if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
473 if (context->type != 0 && context->type != track_type) {
474 GST_WARNING_OBJECT (parse,
475 "More than one tracktype defined in a TrackEntry - skipping");
477 } else if (track_type < 1 || track_type > 254) {
478 GST_WARNING_OBJECT (parse, "Invalid TrackType %" G_GUINT64_FORMAT,
483 GST_DEBUG_OBJECT (parse, "TrackType: %" G_GUINT64_FORMAT, track_type);
485 /* ok, so we're actually going to reallocate this thing */
486 switch (track_type) {
487 case GST_MATROSKA_TRACK_TYPE_VIDEO:
488 gst_matroska_track_init_video_context (&context);
490 case GST_MATROSKA_TRACK_TYPE_AUDIO:
491 gst_matroska_track_init_audio_context (&context);
493 case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
494 gst_matroska_track_init_subtitle_context (&context);
496 case GST_MATROSKA_TRACK_TYPE_COMPLEX:
497 case GST_MATROSKA_TRACK_TYPE_LOGO:
498 case GST_MATROSKA_TRACK_TYPE_BUTTONS:
499 case GST_MATROSKA_TRACK_TYPE_CONTROL:
501 GST_WARNING_OBJECT (parse,
502 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
507 g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
512 /* tracktype specific stuff for video */
513 case GST_MATROSKA_ID_TRACKVIDEO:{
514 GstMatroskaTrackVideoContext *videocontext;
516 DEBUG_ELEMENT_START (parse, ebml, "TrackVideo");
518 if (!gst_matroska_track_init_video_context (&context)) {
519 GST_WARNING_OBJECT (parse,
520 "TrackVideo element in non-video track - ignoring track");
521 ret = GST_FLOW_ERROR;
523 } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
526 videocontext = (GstMatroskaTrackVideoContext *) context;
527 g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
530 while (ret == GST_FLOW_OK &&
531 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
532 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
536 /* Should be one level up but some broken muxers write it here. */
537 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
540 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
544 GST_WARNING_OBJECT (parse, "Invalid TrackDefaultDuration 0");
548 GST_DEBUG_OBJECT (parse,
549 "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
550 context->default_duration = num;
554 /* video framerate */
555 /* NOTE: This one is here only for backward compatibility.
556 * Use _TRACKDEFAULDURATION one level up. */
557 case GST_MATROSKA_ID_VIDEOFRAMERATE:{
560 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
564 GST_WARNING_OBJECT (parse, "Invalid TrackVideoFPS %lf", num);
568 GST_DEBUG_OBJECT (parse, "TrackVideoFrameRate: %lf", num);
569 if (context->default_duration == 0)
570 context->default_duration =
571 gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
572 videocontext->default_fps = num;
576 /* width of the size to display the video at */
577 case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
580 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
584 GST_WARNING_OBJECT (parse, "Invalid TrackVideoDisplayWidth 0");
588 GST_DEBUG_OBJECT (parse,
589 "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
590 videocontext->display_width = num;
594 /* height of the size to display the video at */
595 case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
598 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
602 GST_WARNING_OBJECT (parse, "Invalid TrackVideoDisplayHeight 0");
606 GST_DEBUG_OBJECT (parse,
607 "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
608 videocontext->display_height = num;
612 /* width of the video in the file */
613 case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
616 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
620 GST_WARNING_OBJECT (parse, "Invalid TrackVideoPixelWidth 0");
624 GST_DEBUG_OBJECT (parse,
625 "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
626 videocontext->pixel_width = num;
630 /* height of the video in the file */
631 case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
634 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
638 GST_WARNING_OBJECT (parse, "Invalid TrackVideoPixelHeight 0");
642 GST_DEBUG_OBJECT (parse,
643 "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
644 videocontext->pixel_height = num;
648 /* whether the video is interlaced */
649 case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
652 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
656 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
658 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
659 GST_DEBUG_OBJECT (parse, "TrackVideoInterlaced: %d",
660 (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
665 /* aspect ratio behaviour */
666 case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
669 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
672 if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
673 num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
674 num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
675 GST_WARNING_OBJECT (parse,
676 "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
679 GST_DEBUG_OBJECT (parse,
680 "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
681 videocontext->asr_mode = num;
685 /* colourspace (only matters for raw video) fourcc */
686 case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
691 gst_ebml_read_binary (ebml, &id, &data,
692 &datalen)) != GST_FLOW_OK)
697 GST_WARNING_OBJECT (parse,
698 "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
703 memcpy (&videocontext->fourcc, data, 4);
704 GST_DEBUG_OBJECT (parse,
705 "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
706 GST_FOURCC_ARGS (videocontext->fourcc));
712 GST_WARNING_OBJECT (parse,
713 "Unknown TrackVideo subelement 0x%x - ignoring", id);
715 case GST_MATROSKA_ID_VIDEOSTEREOMODE:
716 case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
717 case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
718 case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
719 case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
720 case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
721 case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
722 ret = gst_ebml_read_skip (ebml);
727 DEBUG_ELEMENT_STOP (parse, ebml, "TrackVideo", ret);
731 /* tracktype specific stuff for audio */
732 case GST_MATROSKA_ID_TRACKAUDIO:{
733 GstMatroskaTrackAudioContext *audiocontext;
735 DEBUG_ELEMENT_START (parse, ebml, "TrackAudio");
737 if (!gst_matroska_track_init_audio_context (&context)) {
738 GST_WARNING_OBJECT (parse,
739 "TrackAudio element in non-audio track - ignoring track");
740 ret = GST_FLOW_ERROR;
744 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
747 audiocontext = (GstMatroskaTrackAudioContext *) context;
748 g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
751 while (ret == GST_FLOW_OK &&
752 gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
753 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
758 case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
761 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
766 GST_WARNING_OBJECT (parse,
767 "Invalid TrackAudioSamplingFrequency %lf", num);
771 GST_DEBUG_OBJECT (parse, "TrackAudioSamplingFrequency: %lf", num);
772 audiocontext->samplerate = num;
777 case GST_MATROSKA_ID_AUDIOBITDEPTH:{
780 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
784 GST_WARNING_OBJECT (parse, "Invalid TrackAudioBitDepth 0");
788 GST_DEBUG_OBJECT (parse, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
790 audiocontext->bitdepth = num;
795 case GST_MATROSKA_ID_AUDIOCHANNELS:{
798 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
802 GST_WARNING_OBJECT (parse, "Invalid TrackAudioChannels 0");
806 GST_DEBUG_OBJECT (parse, "TrackAudioChannels: %" G_GUINT64_FORMAT,
808 audiocontext->channels = num;
813 GST_WARNING_OBJECT (parse,
814 "Unknown TrackAudio subelement 0x%x - ignoring", id);
816 case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
817 case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
818 ret = gst_ebml_read_skip (ebml);
823 DEBUG_ELEMENT_STOP (parse, ebml, "TrackAudio", ret);
828 /* codec identifier */
829 case GST_MATROSKA_ID_CODECID:{
832 if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
835 GST_DEBUG_OBJECT (parse, "CodecID: %s", GST_STR_NULL (text));
836 context->codec_id = text;
840 /* codec private data */
841 case GST_MATROSKA_ID_CODECPRIVATE:{
846 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
849 context->codec_priv = data;
850 context->codec_priv_size = size;
852 GST_DEBUG_OBJECT (parse, "CodecPrivate of size %" G_GUINT64_FORMAT,
857 /* name of the codec */
858 case GST_MATROSKA_ID_CODECNAME:{
861 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
864 GST_DEBUG_OBJECT (parse, "CodecName: %s", GST_STR_NULL (text));
865 context->codec_name = text;
869 /* name of this track */
870 case GST_MATROSKA_ID_TRACKNAME:{
873 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
876 context->name = text;
877 GST_DEBUG_OBJECT (parse, "TrackName: %s", GST_STR_NULL (text));
881 /* language (matters for audio/subtitles, mostly) */
882 case GST_MATROSKA_ID_TRACKLANGUAGE:{
885 if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
889 context->language = text;
892 if (strlen (context->language) >= 4 && context->language[3] == '-')
893 context->language[3] = '\0';
895 GST_DEBUG_OBJECT (parse, "TrackLanguage: %s",
896 GST_STR_NULL (context->language));
900 /* whether this is actually used */
901 case GST_MATROSKA_ID_TRACKFLAGENABLED:{
904 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
908 context->flags |= GST_MATROSKA_TRACK_ENABLED;
910 context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
912 GST_DEBUG_OBJECT (parse, "TrackEnabled: %d",
913 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
917 /* whether it's the default for this track type */
918 case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
921 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
925 context->flags |= GST_MATROSKA_TRACK_DEFAULT;
927 context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
929 GST_DEBUG_OBJECT (parse, "TrackDefault: %d",
930 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
934 /* whether the track must be used during playback */
935 case GST_MATROSKA_ID_TRACKFLAGFORCED:{
938 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
942 context->flags |= GST_MATROSKA_TRACK_FORCED;
944 context->flags &= ~GST_MATROSKA_TRACK_FORCED;
946 GST_DEBUG_OBJECT (parse, "TrackForced: %d",
947 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
951 /* lacing (like MPEG, where blocks don't end/start on frame
953 case GST_MATROSKA_ID_TRACKFLAGLACING:{
956 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
960 context->flags |= GST_MATROSKA_TRACK_LACING;
962 context->flags &= ~GST_MATROSKA_TRACK_LACING;
964 GST_DEBUG_OBJECT (parse, "TrackLacing: %d",
965 (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
969 /* default length (in time) of one data block in this track */
970 case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
973 if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
978 GST_WARNING_OBJECT (parse, "Invalid TrackDefaultDuration 0");
982 GST_DEBUG_OBJECT (parse, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
984 context->default_duration = num;
988 case GST_MATROSKA_ID_CONTENTENCODINGS:{
989 ret = gst_matroska_read_common_read_track_encodings (&parse->common,
994 case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
997 if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1001 GST_WARNING_OBJECT (parse, "Invalid TrackTimeCodeScale %lf", num);
1005 GST_DEBUG_OBJECT (parse, "TrackTimeCodeScale: %lf", num);
1006 context->timecodescale = num;
1011 GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1014 /* we ignore these because they're nothing useful (i.e. crap)
1015 * or simply not implemented yet. */
1016 case GST_MATROSKA_ID_TRACKMINCACHE:
1017 case GST_MATROSKA_ID_TRACKMAXCACHE:
1018 case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1019 case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1020 case GST_MATROSKA_ID_TRACKOVERLAY:
1021 case GST_MATROSKA_ID_TRACKTRANSLATE:
1022 case GST_MATROSKA_ID_TRACKOFFSET:
1023 case GST_MATROSKA_ID_CODECSETTINGS:
1024 case GST_MATROSKA_ID_CODECINFOURL:
1025 case GST_MATROSKA_ID_CODECDOWNLOADURL:
1026 case GST_MATROSKA_ID_CODECDECODEALL:
1027 ret = gst_ebml_read_skip (ebml);
1032 DEBUG_ELEMENT_STOP (parse, ebml, "TrackEntry", ret);
1034 /* Decode codec private data if necessary */
1035 if (context->encodings && context->encodings->len > 0 && context->codec_priv
1036 && context->codec_priv_size > 0) {
1037 if (!gst_matroska_decode_data (context->encodings,
1038 &context->codec_priv, &context->codec_priv_size,
1039 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1040 GST_WARNING_OBJECT (parse, "Decoding codec private data failed");
1041 ret = GST_FLOW_ERROR;
1045 if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1046 && ret != GST_FLOW_UNEXPECTED)) {
1047 if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
1048 GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1050 parse->common.num_streams--;
1051 g_ptr_array_remove_index (parse->common.src, parse->common.num_streams);
1052 g_assert (parse->common.src->len == parse->common.num_streams);
1054 gst_matroska_track_free (context);
1060 if ((context->language == NULL || *context->language == '\0') &&
1061 (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1062 context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1063 GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1064 context->language = g_strdup ("eng");
1073 gst_matroska_parse_query (GstMatroskaParse * parse, GstPad * pad,
1076 gboolean res = FALSE;
1077 GstMatroskaTrackContext *context = NULL;
1080 context = gst_pad_get_element_private (pad);
1083 switch (GST_QUERY_TYPE (query)) {
1084 case GST_QUERY_POSITION:
1088 gst_query_parse_position (query, &format, NULL);
1090 if (format == GST_FORMAT_TIME) {
1091 GST_OBJECT_LOCK (parse);
1093 gst_query_set_position (query, GST_FORMAT_TIME, context->pos);
1095 gst_query_set_position (query, GST_FORMAT_TIME,
1096 parse->common.segment.position);
1097 GST_OBJECT_UNLOCK (parse);
1098 } else if (format == GST_FORMAT_DEFAULT && context
1099 && context->default_duration) {
1100 GST_OBJECT_LOCK (parse);
1101 gst_query_set_position (query, GST_FORMAT_DEFAULT,
1102 context->pos / context->default_duration);
1103 GST_OBJECT_UNLOCK (parse);
1105 GST_DEBUG_OBJECT (parse,
1106 "only position query in TIME and DEFAULT format is supported");
1112 case GST_QUERY_DURATION:
1116 gst_query_parse_duration (query, &format, NULL);
1118 if (format == GST_FORMAT_TIME) {
1119 GST_OBJECT_LOCK (parse);
1120 gst_query_set_duration (query, GST_FORMAT_TIME,
1121 parse->common.segment.duration);
1122 GST_OBJECT_UNLOCK (parse);
1123 } else if (format == GST_FORMAT_DEFAULT && context
1124 && context->default_duration) {
1125 GST_OBJECT_LOCK (parse);
1126 gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1127 parse->common.segment.duration / context->default_duration);
1128 GST_OBJECT_UNLOCK (parse);
1130 GST_DEBUG_OBJECT (parse,
1131 "only duration query in TIME and DEFAULT format is supported");
1138 case GST_QUERY_SEEKING:
1142 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1143 if (fmt == GST_FORMAT_TIME) {
1146 /* assuming we'll be able to get an index ... */
1147 seekable = parse->seekable;
1149 gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1150 0, parse->common.segment.duration);
1156 res = gst_pad_query_default (pad, (GstObject *) parse, query);
1164 gst_matroska_parse_element_query (GstElement * element, GstQuery * query)
1166 return gst_matroska_parse_query (GST_MATROSKA_PARSE (element), NULL, query);
1170 gst_matroska_parse_handle_src_query (GstPad * pad, GstObject * parent,
1174 GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
1176 ret = gst_matroska_parse_query (parse, pad, query);
1181 /* returns FALSE if there are no pads to deliver event to,
1182 * otherwise TRUE (whatever the outcome of event sending),
1183 * takes ownership of the passed event! */
1185 gst_matroska_parse_send_event (GstMatroskaParse * parse, GstEvent * event)
1187 gboolean ret = FALSE;
1189 g_return_val_if_fail (event != NULL, FALSE);
1191 GST_DEBUG_OBJECT (parse, "Sending event of type %s to all source pads",
1192 GST_EVENT_TYPE_NAME (event));
1194 gst_pad_push_event (parse->srcpad, event);
1200 gst_matroska_parse_element_send_event (GstElement * element, GstEvent * event)
1202 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
1205 g_return_val_if_fail (event != NULL, FALSE);
1207 if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1208 res = gst_matroska_parse_handle_seek_event (parse, NULL, event);
1210 GST_WARNING_OBJECT (parse, "Unhandled event of type %s",
1211 GST_EVENT_TYPE_NAME (event));
1214 gst_event_unref (event);
1218 /* searches for a cluster start from @pos,
1219 * return GST_FLOW_OK and cluster position in @pos if found */
1220 static GstFlowReturn
1221 gst_matroska_parse_search_cluster (GstMatroskaParse * parse, gint64 * pos)
1223 gint64 newpos = *pos;
1225 GstFlowReturn ret = GST_FLOW_OK;
1226 const guint chunk = 64 * 1024;
1227 GstBuffer *buf = NULL;
1234 orig_offset = parse->common.offset;
1236 /* read in at newpos and scan for ebml cluster id */
1238 GstByteReader reader;
1241 ret = gst_pad_pull_range (parse->common.sinkpad, newpos, chunk, &buf);
1242 if (ret != GST_FLOW_OK)
1244 GST_DEBUG_OBJECT (parse, "read buffer size %d at offset %" G_GINT64_FORMAT,
1245 gst_buffer_get_size (buf), newpos);
1246 data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
1247 gst_byte_reader_init (&reader, data, size);
1250 cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1251 GST_MATROSKA_ID_CLUSTER, cluster_pos, size - cluster_pos);
1252 if (cluster_pos >= 0) {
1253 newpos += cluster_pos;
1254 GST_DEBUG_OBJECT (parse,
1255 "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1256 /* extra checks whether we really sync'ed to a cluster:
1257 * - either it is the first and only cluster
1258 * - either there is a cluster after this one
1259 * - either cluster length is undefined
1261 /* ok if first cluster (there may not a subsequent one) */
1262 if (newpos == parse->first_cluster_offset) {
1263 GST_DEBUG_OBJECT (parse, "cluster is first cluster -> OK");
1266 parse->common.offset = newpos;
1267 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1268 GST_ELEMENT_CAST (parse), &id, &length, &needed);
1269 if (ret != GST_FLOW_OK)
1271 g_assert (id == GST_MATROSKA_ID_CLUSTER);
1272 GST_DEBUG_OBJECT (parse, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1274 /* ok if undefined length or first cluster */
1275 if (length == G_MAXUINT64) {
1276 GST_DEBUG_OBJECT (parse, "cluster has undefined length -> OK");
1280 parse->common.offset += length + needed;
1281 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1282 GST_ELEMENT_CAST (parse), &id, &length, &needed);
1283 if (ret != GST_FLOW_OK)
1285 GST_DEBUG_OBJECT (parse, "next element is %scluster",
1286 id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1287 if (id == GST_MATROSKA_ID_CLUSTER)
1289 /* not ok, resume */
1292 /* partial cluster id may have been in tail of buffer */
1293 newpos += MAX (size, 4) - 3;
1294 gst_buffer_unmap (buf, data, size);
1295 gst_buffer_unref (buf);
1301 gst_buffer_unmap (buf, data, size);
1302 gst_buffer_unref (buf);
1306 parse->common.offset = orig_offset;
1313 gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
1314 GstPad * pad, GstEvent * event)
1316 GstMatroskaIndex *entry = NULL;
1318 GstSeekType cur_type, stop_type;
1322 GstMatroskaTrackContext *track = NULL;
1323 GstSegment seeksegment = { 0, };
1327 track = gst_pad_get_element_private (pad);
1329 track = gst_matroska_read_common_get_seek_track (&parse->common, track);
1331 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1334 /* we can only seek on time */
1335 if (format != GST_FORMAT_TIME) {
1336 GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1340 /* copy segment, we need this because we still need the old
1341 * segment when we close the current segment. */
1342 memcpy (&seeksegment, &parse->common.segment, sizeof (GstSegment));
1345 GST_DEBUG_OBJECT (parse, "configuring seek");
1346 gst_segment_do_seek (&seeksegment, rate, format, flags,
1347 cur_type, cur, stop_type, stop, &update);
1350 GST_DEBUG_OBJECT (parse, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1352 /* check sanity before we start flushing and all that */
1353 GST_OBJECT_LOCK (parse);
1354 if ((entry = gst_matroska_read_common_do_index_seek (&parse->common, track,
1355 seeksegment.position, &parse->seek_index, &parse->seek_entry)) ==
1357 /* pull mode without index can scan later on */
1358 GST_DEBUG_OBJECT (parse, "No matching seek entry in index");
1359 GST_OBJECT_UNLOCK (parse);
1362 GST_DEBUG_OBJECT (parse, "Seek position looks sane");
1363 GST_OBJECT_UNLOCK (parse);
1365 /* need to seek to cluster start to pick up cluster time */
1366 /* upstream takes care of flushing and all that
1367 * ... and newsegment event handling takes care of the rest */
1368 return perform_seek_to_offset (parse, entry->pos
1369 + parse->common.ebml_segment_start);
1373 * Handle whether we can perform the seek event or if we have to let the chain
1374 * function handle seeks to build the seek indexes first.
1377 gst_matroska_parse_handle_seek_push (GstMatroskaParse * parse, GstPad * pad,
1381 GstSeekType cur_type, stop_type;
1386 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1391 /* we can only seek on time */
1392 if (format != GST_FORMAT_TIME) {
1393 GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1397 if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
1398 GST_DEBUG_OBJECT (parse, "Seek end-time not supported in streaming mode");
1402 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
1403 GST_DEBUG_OBJECT (parse,
1404 "Non-flushing seek not supported in streaming mode");
1408 if (flags & GST_SEEK_FLAG_SEGMENT) {
1409 GST_DEBUG_OBJECT (parse, "Segment seek not supported in streaming mode");
1413 /* check for having parsed index already */
1414 if (!parse->common.index_parsed) {
1415 gboolean building_index;
1418 if (!parse->index_offset) {
1419 GST_DEBUG_OBJECT (parse, "no index (location); no seek in push mode");
1423 GST_OBJECT_LOCK (parse);
1424 /* handle the seek event in the chain function */
1425 parse->common.state = GST_MATROSKA_READ_STATE_SEEK;
1426 /* no more seek can be issued until state reset to _DATA */
1428 /* copy the event */
1429 if (parse->seek_event)
1430 gst_event_unref (parse->seek_event);
1431 parse->seek_event = gst_event_ref (event);
1433 /* set the building_index flag so that only one thread can setup the
1434 * structures for index seeking. */
1435 building_index = parse->building_index;
1436 if (!building_index) {
1437 parse->building_index = TRUE;
1438 offset = parse->index_offset;
1440 GST_OBJECT_UNLOCK (parse);
1442 if (!building_index) {
1443 /* seek to the first subindex or legacy index */
1444 GST_INFO_OBJECT (parse, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
1445 return perform_seek_to_offset (parse, offset);
1448 /* well, we are handling it already */
1452 /* delegate to tweaked regular seek */
1453 return gst_matroska_parse_handle_seek_event (parse, pad, event);
1457 gst_matroska_parse_handle_src_event (GstPad * pad, GstObject * parent,
1460 GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
1461 gboolean res = TRUE;
1463 switch (GST_EVENT_TYPE (event)) {
1464 case GST_EVENT_SEEK:
1465 /* no seeking until we are (safely) ready */
1466 if (parse->common.state != GST_MATROSKA_READ_STATE_DATA) {
1467 GST_DEBUG_OBJECT (parse, "not ready for seeking yet");
1470 res = gst_matroska_parse_handle_seek_push (parse, pad, event);
1471 gst_event_unref (event);
1476 GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
1477 if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
1478 GstMatroskaTrackVideoContext *videocontext =
1479 (GstMatroskaTrackVideoContext *) context;
1481 GstClockTimeDiff diff;
1482 GstClockTime timestamp;
1484 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
1486 GST_OBJECT_LOCK (parse);
1487 videocontext->earliest_time = timestamp + diff;
1488 GST_OBJECT_UNLOCK (parse);
1491 gst_event_unref (event);
1495 /* events we don't need to handle */
1496 case GST_EVENT_NAVIGATION:
1497 gst_event_unref (event);
1501 case GST_EVENT_LATENCY:
1503 res = gst_pad_push_event (parse->common.sinkpad, event);
1510 static GstFlowReturn
1511 gst_matroska_parse_parse_tracks (GstMatroskaParse * parse, GstEbmlRead * ebml)
1513 GstFlowReturn ret = GST_FLOW_OK;
1516 DEBUG_ELEMENT_START (parse, ebml, "Tracks");
1518 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1519 DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1523 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1524 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1528 /* one track within the "all-tracks" header */
1529 case GST_MATROSKA_ID_TRACKENTRY:
1530 ret = gst_matroska_parse_add_stream (parse, ebml);
1534 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1539 DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1541 parse->tracks_parsed = TRUE;
1547 * Read signed/unsigned "EBML" numbers.
1548 * Return: number of bytes processed.
1552 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
1554 gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
1562 while (read <= 8 && !(total & len_mask)) {
1569 if ((total &= (len_mask - 1)) == len_mask - 1)
1574 if (data[n] == 0xff)
1576 total = (total << 8) | data[n];
1580 if (read == num_ffs && total != 0)
1589 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
1594 /* read as unsigned number first */
1595 if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
1599 if (unum == G_MAXUINT64)
1602 *num = unum - ((1 << ((7 * res) - 1)) - 1);
1607 static GstFlowReturn
1608 gst_matroska_parse_parse_blockgroup_or_simpleblock (GstMatroskaParse * parse,
1609 GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
1610 gboolean is_simpleblock)
1612 GstMatroskaTrackContext *stream = NULL;
1613 GstFlowReturn ret = GST_FLOW_OK;
1614 gboolean readblock = FALSE;
1616 guint64 block_duration = 0;
1617 GstBuffer *buf = NULL;
1618 gpointer buf_data = NULL;
1620 gint stream_num = -1, n, laces = 0;
1622 gint *lace_size = NULL;
1625 gint64 referenceblock = 0;
1627 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1628 if (!is_simpleblock) {
1629 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
1633 id = GST_MATROSKA_ID_SIMPLEBLOCK;
1637 /* one block inside the group. Note, block parsing is one
1638 * of the harder things, so this code is a bit complicated.
1639 * See http://www.matroska.org/ for documentation. */
1640 case GST_MATROSKA_ID_SIMPLEBLOCK:
1641 case GST_MATROSKA_ID_BLOCK:
1647 gst_buffer_unref (buf);
1650 if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
1653 buf_data = gst_buffer_map (buf, &buf_size, NULL, GST_MAP_READ);
1658 /* first byte(s): blocknum */
1659 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1664 /* fetch stream from num */
1665 stream_num = gst_matroska_read_common_stream_from_num (&parse->common,
1667 if (G_UNLIKELY (size < 3)) {
1668 GST_WARNING_OBJECT (parse, "Invalid size %u", size);
1669 /* non-fatal, try next block(group) */
1672 } else if (G_UNLIKELY (stream_num < 0 ||
1673 stream_num >= parse->common.num_streams)) {
1674 /* let's not give up on a stray invalid track number */
1675 GST_WARNING_OBJECT (parse,
1676 "Invalid stream %d for track number %" G_GUINT64_FORMAT
1677 "; ignoring block", stream_num, num);
1681 stream = g_ptr_array_index (parse->common.src, stream_num);
1683 /* time (relative to cluster time) */
1684 time = ((gint16) GST_READ_UINT16_BE (data));
1687 flags = GST_READ_UINT8 (data);
1691 GST_LOG_OBJECT (parse, "time %" G_GUINT64_FORMAT ", flags %d", time,
1694 switch ((flags & 0x06) >> 1) {
1695 case 0x0: /* no lacing */
1697 lace_size = g_new (gint, 1);
1698 lace_size[0] = size;
1701 case 0x1: /* xiph lacing */
1702 case 0x2: /* fixed-size lacing */
1703 case 0x3: /* EBML lacing */
1705 goto invalid_lacing;
1706 laces = GST_READ_UINT8 (data) + 1;
1709 lace_size = g_new0 (gint, laces);
1711 switch ((flags & 0x06) >> 1) {
1712 case 0x1: /* xiph lacing */ {
1713 guint temp, total = 0;
1715 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
1718 goto invalid_lacing;
1719 temp = GST_READ_UINT8 (data);
1720 lace_size[n] += temp;
1726 total += lace_size[n];
1728 lace_size[n] = size - total;
1732 case 0x2: /* fixed-size lacing */
1733 for (n = 0; n < laces; n++)
1734 lace_size[n] = size / laces;
1737 case 0x3: /* EBML lacing */ {
1740 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1744 total = lace_size[0] = num;
1745 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
1749 if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
1753 lace_size[n] = lace_size[n - 1] + snum;
1754 total += lace_size[n];
1757 lace_size[n] = size - total;
1764 if (ret != GST_FLOW_OK)
1771 case GST_MATROSKA_ID_BLOCKDURATION:{
1772 ret = gst_ebml_read_uint (ebml, &id, &block_duration);
1773 GST_DEBUG_OBJECT (parse, "BlockDuration: %" G_GUINT64_FORMAT,
1778 case GST_MATROSKA_ID_REFERENCEBLOCK:{
1779 ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
1780 GST_DEBUG_OBJECT (parse, "ReferenceBlock: %" G_GINT64_FORMAT,
1785 case GST_MATROSKA_ID_CODECSTATE:{
1787 guint64 data_len = 0;
1790 gst_ebml_read_binary (ebml, &id, &data,
1791 &data_len)) != GST_FLOW_OK)
1794 if (G_UNLIKELY (stream == NULL)) {
1795 GST_WARNING_OBJECT (parse,
1796 "Unexpected CodecState subelement - ignoring");
1800 g_free (stream->codec_state);
1801 stream->codec_state = data;
1802 stream->codec_state_size = data_len;
1808 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1812 case GST_MATROSKA_ID_BLOCKVIRTUAL:
1813 case GST_MATROSKA_ID_BLOCKADDITIONS:
1814 case GST_MATROSKA_ID_REFERENCEPRIORITY:
1815 case GST_MATROSKA_ID_REFERENCEVIRTUAL:
1816 case GST_MATROSKA_ID_SLICES:
1817 GST_DEBUG_OBJECT (parse,
1818 "Skipping BlockGroup subelement 0x%x - ignoring", id);
1819 ret = gst_ebml_read_skip (ebml);
1827 /* reading a number or so could have failed */
1828 if (ret != GST_FLOW_OK)
1831 if (ret == GST_FLOW_OK && readblock) {
1832 guint64 duration = 0;
1833 gint64 lace_time = 0;
1834 gboolean delta_unit;
1836 stream = g_ptr_array_index (parse->common.src, stream_num);
1838 if (cluster_time != GST_CLOCK_TIME_NONE) {
1839 /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
1840 * Drop unless the lace contains timestamp 0? */
1841 if (time < 0 && (-time) > cluster_time) {
1844 if (stream->timecodescale == 1.0)
1845 lace_time = (cluster_time + time) * parse->common.time_scale;
1848 gst_util_guint64_to_gdouble ((cluster_time + time) *
1849 parse->common.time_scale) * stream->timecodescale;
1852 lace_time = GST_CLOCK_TIME_NONE;
1855 if (lace_time != GST_CLOCK_TIME_NONE) {
1856 parse->last_timestamp = lace_time;
1858 /* need to refresh segment info ASAP */
1859 if (GST_CLOCK_TIME_IS_VALID (lace_time) && parse->need_newsegment) {
1861 GST_DEBUG_OBJECT (parse,
1862 "generating segment starting at %" GST_TIME_FORMAT,
1863 GST_TIME_ARGS (lace_time));
1864 /* pretend we seeked here */
1865 gst_segment_do_seek (&parse->common.segment, parse->common.segment.rate,
1866 GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, lace_time,
1867 GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE, NULL);
1868 /* now convey our segment notion downstream */
1869 segment = parse->common.segment;
1870 segment.position = segment.start;
1871 gst_matroska_parse_send_event (parse, gst_event_new_segment (&segment));
1872 parse->need_newsegment = FALSE;
1875 if (block_duration) {
1876 if (stream->timecodescale == 1.0)
1877 duration = gst_util_uint64_scale (block_duration,
1878 parse->common.time_scale, 1);
1881 gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
1882 (gst_util_uint64_scale (block_duration, parse->common.time_scale,
1883 1)) * stream->timecodescale);
1884 } else if (stream->default_duration) {
1885 duration = stream->default_duration * laces;
1887 /* else duration is diff between timecode of this and next block */
1889 /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
1890 a ReferenceBlock implies that this is not a keyframe. In either
1891 case, it only makes sense for video streams. */
1892 delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1893 ((is_simpleblock && !(flags & 0x80)) || referenceblock);
1895 if (delta_unit && stream->set_discont) {
1896 /* When doing seeks or such, we need to restart on key frames or
1897 * decoders might choke. */
1898 GST_DEBUG_OBJECT (parse, "skipping delta unit");
1902 for (n = 0; n < laces; n++) {
1903 if (G_UNLIKELY (lace_size[n] > size)) {
1904 GST_WARNING_OBJECT (parse, "Invalid lace size");
1908 /* QoS for video track with an index. the assumption is that
1909 index entries point to keyframes, but if that is not true we
1910 will instad skip until the next keyframe. */
1911 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1912 stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1913 stream->index_table && parse->common.segment.rate > 0.0) {
1914 GstMatroskaTrackVideoContext *videocontext =
1915 (GstMatroskaTrackVideoContext *) stream;
1916 GstClockTime earliest_time;
1917 GstClockTime earliest_stream_time;
1919 GST_OBJECT_LOCK (parse);
1920 earliest_time = videocontext->earliest_time;
1921 GST_OBJECT_UNLOCK (parse);
1922 earliest_stream_time = gst_segment_to_position (&parse->common.segment,
1923 GST_FORMAT_TIME, earliest_time);
1925 if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1926 GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
1927 lace_time <= earliest_stream_time) {
1928 /* find index entry (keyframe) <= earliest_stream_time */
1929 GstMatroskaIndex *entry =
1930 gst_util_array_binary_search (stream->index_table->data,
1931 stream->index_table->len, sizeof (GstMatroskaIndex),
1932 (GCompareDataFunc) gst_matroska_index_seek_find,
1933 GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
1935 /* if that entry (keyframe) is after the current the current
1936 buffer, we can skip pushing (and thus decoding) all
1937 buffers until that keyframe. */
1938 if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
1939 entry->time > lace_time) {
1940 GST_LOG_OBJECT (parse, "Skipping lace before late keyframe");
1941 stream->set_discont = TRUE;
1947 sub = gst_buffer_create_sub (buf,
1948 GST_BUFFER_SIZE (buf) - size, lace_size[n]);
1949 GST_DEBUG_OBJECT (parse, "created subbuffer %p", sub);
1952 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1954 GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1956 if (stream->encodings != NULL && stream->encodings->len > 0)
1957 sub = gst_matroska_decode_buffer (stream, sub);
1960 GST_WARNING_OBJECT (parse, "Decoding buffer failed");
1964 GST_BUFFER_TIMESTAMP (sub) = lace_time;
1966 if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
1967 GstClockTime last_stop_end;
1969 /* Check if this stream is after segment stop */
1970 if (GST_CLOCK_TIME_IS_VALID (parse->common.segment.stop) &&
1971 lace_time >= parse->common.segment.stop) {
1972 GST_DEBUG_OBJECT (parse,
1973 "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
1974 GST_TIME_ARGS (parse->common.segment.stop));
1975 gst_buffer_unref (sub);
1978 if (offset >= stream->to_offset) {
1979 GST_DEBUG_OBJECT (parse, "Stream %d after playback section",
1981 gst_buffer_unref (sub);
1985 /* handle gaps, e.g. non-zero start-time, or an cue index entry
1986 * that landed us with timestamps not quite intended */
1987 if (GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop) &&
1988 parse->segment.rate > 0.0) {
1989 GstClockTimeDiff diff;
1991 /* only send newsegments with increasing start times,
1992 * otherwise if these go back and forth downstream (sinks) increase
1993 * accumulated time and running_time */
1994 diff = GST_CLOCK_DIFF (parse->segment.last_stop, lace_time);
1995 if (diff > 2 * GST_SECOND && lace_time > parse->segment.start &&
1996 (!GST_CLOCK_TIME_IS_VALID (parse->segment.stop) ||
1997 lace_time < parse->segment.stop)) {
1998 GST_DEBUG_OBJECT (parse,
1999 "Gap of %" G_GINT64_FORMAT " ns detected in"
2000 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
2001 "Sending updated NEWSEGMENT events", diff,
2002 stream->index, GST_TIME_ARGS (stream->pos),
2003 GST_TIME_ARGS (lace_time));
2004 /* send newsegment events such that the gap is not accounted in
2005 * accum time, hence running_time */
2006 /* close ahead of gap */
2007 gst_matroska_parse_send_event (parse,
2008 gst_event_new_new_segment (TRUE, parse->segment.rate,
2009 parse->segment.format, parse->segment.last_stop,
2010 parse->segment.last_stop, parse->segment.last_stop));
2012 gst_matroska_parse_send_event (parse,
2013 gst_event_new_new_segment (FALSE, parse->segment.rate,
2014 parse->segment.format, lace_time, parse->segment.stop,
2016 /* align segment view with downstream,
2017 * prevents double-counting accum when closing segment */
2018 gst_segment_set_newsegment (&parse->segment, FALSE,
2019 parse->segment.rate, parse->segment.format, lace_time,
2020 parse->segment.stop, lace_time);
2021 parse->segment.last_stop = lace_time;
2025 if (!GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop)
2026 || parse->segment.last_stop < lace_time) {
2027 parse->segment.last_stop = lace_time;
2030 last_stop_end = lace_time;
2032 GST_BUFFER_DURATION (sub) = duration / laces;
2033 last_stop_end += GST_BUFFER_DURATION (sub);
2036 if (!GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) ||
2037 parse->last_stop_end < last_stop_end)
2038 parse->last_stop_end = last_stop_end;
2040 if (parse->segment.duration == -1 ||
2041 parse->segment.duration < lace_time) {
2042 gst_segment_set_duration (&parse->segment, GST_FORMAT_TIME,
2044 gst_element_post_message (GST_ELEMENT_CAST (parse),
2045 gst_message_new_duration (GST_OBJECT_CAST (parse),
2046 GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
2050 stream->pos = lace_time;
2052 gst_matroska_parse_sync_streams (parse);
2054 if (stream->set_discont) {
2055 GST_DEBUG_OBJECT (parse, "marking DISCONT");
2056 GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
2057 stream->set_discont = FALSE;
2060 /* reverse playback book-keeping */
2061 if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
2062 stream->from_time = lace_time;
2063 if (stream->from_offset == -1)
2064 stream->from_offset = offset;
2066 GST_DEBUG_OBJECT (parse,
2067 "Pushing lace %d, data of size %d for stream %d, time=%"
2068 GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
2069 GST_BUFFER_SIZE (sub), stream_num,
2070 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
2071 GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
2073 if (parse->element_index) {
2074 if (stream->index_writer_id == -1)
2075 gst_index_get_writer_id (parse->element_index,
2076 GST_OBJECT (stream->pad), &stream->index_writer_id);
2078 GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
2079 G_GUINT64_FORMAT " for writer id %d",
2080 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
2081 stream->index_writer_id);
2082 gst_index_add_association (parse->element_index,
2083 stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
2084 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
2085 GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
2086 cluster_offset, NULL);
2089 gst_buffer_set_caps (sub, GST_PAD_CAPS (parse->srcpad));
2091 /* Postprocess the buffers depending on the codec used */
2092 if (stream->postprocess_frame) {
2093 GST_LOG_OBJECT (parse, "running post process");
2094 ret = stream->postprocess_frame (GST_ELEMENT (parse), stream, &sub);
2097 ret = gst_pad_push (stream->pad, sub);
2098 if (parse->segment.rate < 0) {
2099 if (lace_time > parse->segment.stop && ret == GST_FLOW_UNEXPECTED) {
2100 /* In reverse playback we can get a GST_FLOW_UNEXPECTED when
2101 * we are at the end of the segment, so we just need to jump
2102 * back to the previous section. */
2103 GST_DEBUG_OBJECT (parse, "downstream has reached end of segment");
2108 ret = gst_matroska_parse_combine_flows (parse, stream, ret);
2112 size -= lace_size[n];
2113 if (lace_time != GST_CLOCK_TIME_NONE && duration)
2114 lace_time += duration / laces;
2116 lace_time = GST_CLOCK_TIME_NONE;
2122 gst_buffer_unmap (buf, buf_data, buf_size);
2123 gst_buffer_unref (buf);
2132 GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
2133 /* non-fatal, try next block(group) */
2139 GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Data error"));
2140 /* non-fatal, try next block(group) */
2146 /* return FALSE if block(group) should be skipped (due to a seek) */
2147 static inline gboolean
2148 gst_matroska_parse_seek_block (GstMatroskaParse * parse)
2150 if (G_UNLIKELY (parse->seek_block)) {
2151 if (!(--parse->seek_block)) {
2154 GST_LOG_OBJECT (parse, "should skip block due to seek");
2162 static GstFlowReturn
2163 gst_matroska_parse_parse_contents_seekentry (GstMatroskaParse * parse,
2167 guint64 seek_pos = (guint64) - 1;
2168 guint32 seek_id = 0;
2171 DEBUG_ELEMENT_START (parse, ebml, "Seek");
2173 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2174 DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2178 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2179 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2183 case GST_MATROSKA_ID_SEEKID:
2187 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2190 GST_DEBUG_OBJECT (parse, "SeekID: %" G_GUINT64_FORMAT, t);
2195 case GST_MATROSKA_ID_SEEKPOSITION:
2199 if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2202 if (t > G_MAXINT64) {
2203 GST_WARNING_OBJECT (parse,
2204 "Too large SeekPosition %" G_GUINT64_FORMAT, t);
2208 GST_DEBUG_OBJECT (parse, "SeekPosition: %" G_GUINT64_FORMAT, t);
2214 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2220 if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
2223 if (!seek_id || seek_pos == (guint64) - 1) {
2224 GST_WARNING_OBJECT (parse, "Incomplete seekhead entry (0x%x/%"
2225 G_GUINT64_FORMAT ")", seek_id, seek_pos);
2230 case GST_MATROSKA_ID_SEEKHEAD:
2233 case GST_MATROSKA_ID_CUES:
2234 case GST_MATROSKA_ID_TAGS:
2235 case GST_MATROSKA_ID_TRACKS:
2236 case GST_MATROSKA_ID_SEGMENTINFO:
2237 case GST_MATROSKA_ID_ATTACHMENTS:
2238 case GST_MATROSKA_ID_CHAPTERS:
2243 length = gst_matroska_read_common_get_length (&parse->common);
2245 if (length == (guint64) - 1) {
2246 GST_DEBUG_OBJECT (parse, "no upstream length, skipping SeakHead entry");
2250 /* check for validity */
2251 if (seek_pos + parse->common.ebml_segment_start + 12 >= length) {
2252 GST_WARNING_OBJECT (parse,
2253 "SeekHead reference lies outside file!" " (%"
2254 G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
2255 G_GUINT64_FORMAT ")", seek_pos, parse->common.ebml_segment_start,
2260 /* only pick up index location when streaming */
2261 if (seek_id == GST_MATROSKA_ID_CUES) {
2262 parse->index_offset = seek_pos + parse->common.ebml_segment_start;
2263 GST_DEBUG_OBJECT (parse, "Cues located at offset %" G_GUINT64_FORMAT,
2264 parse->index_offset);
2270 GST_DEBUG_OBJECT (parse, "Ignoring Seek entry for ID=0x%x", seek_id);
2273 DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2278 static GstFlowReturn
2279 gst_matroska_parse_parse_contents (GstMatroskaParse * parse, GstEbmlRead * ebml)
2281 GstFlowReturn ret = GST_FLOW_OK;
2284 DEBUG_ELEMENT_START (parse, ebml, "SeekHead");
2286 if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2287 DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2291 while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2292 if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2296 case GST_MATROSKA_ID_SEEKENTRY:
2298 ret = gst_matroska_parse_parse_contents_seekentry (parse, ebml);
2299 /* Ignore EOS and errors here */
2300 if (ret != GST_FLOW_OK) {
2301 GST_DEBUG_OBJECT (parse, "Ignoring %s", gst_flow_get_name (ret));
2308 ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2314 DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2319 #define GST_FLOW_OVERFLOW GST_FLOW_CUSTOM_ERROR
2321 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
2323 static inline GstFlowReturn
2324 gst_matroska_parse_check_read_size (GstMatroskaParse * parse, guint64 bytes)
2326 if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
2327 /* only a few blocks are expected/allowed to be large,
2328 * and will be recursed into, whereas others will be read and must fit */
2329 /* fatal in streaming case, as we can't step over easily */
2330 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2331 ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
2332 "file might be corrupt.", bytes));
2333 return GST_FLOW_ERROR;
2339 /* returns TRUE if we truely are in error state, and should give up */
2340 static inline gboolean
2341 gst_matroska_parse_check_parse_error (GstMatroskaParse * parse)
2345 /* sigh, one last attempt above and beyond call of duty ...;
2346 * search for cluster mark following current pos */
2347 pos = parse->common.offset;
2348 GST_WARNING_OBJECT (parse, "parse error, looking for next cluster");
2349 if (gst_matroska_parse_search_cluster (parse, &pos) != GST_FLOW_OK) {
2350 /* did not work, give up */
2353 GST_DEBUG_OBJECT (parse, "... found at %" G_GUINT64_FORMAT, pos);
2354 /* try that position */
2355 parse->common.offset = pos;
2360 /* initializes @ebml with @bytes from input stream at current offset.
2361 * Returns UNEXPECTED if insufficient available,
2362 * ERROR if too much was attempted to read. */
2363 static inline GstFlowReturn
2364 gst_matroska_parse_take (GstMatroskaParse * parse, guint64 bytes,
2367 GstBuffer *buffer = NULL;
2368 GstFlowReturn ret = GST_FLOW_OK;
2370 GST_LOG_OBJECT (parse, "taking %" G_GUINT64_FORMAT " bytes for parsing",
2372 ret = gst_matroska_parse_check_read_size (parse, bytes);
2373 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
2374 /* otherwise fatal */
2375 ret = GST_FLOW_ERROR;
2378 if (gst_adapter_available (parse->common.adapter) >= bytes)
2379 buffer = gst_adapter_take_buffer (parse->common.adapter, bytes);
2381 ret = GST_FLOW_UNEXPECTED;
2382 if (G_LIKELY (buffer)) {
2383 gst_ebml_read_init (ebml, GST_ELEMENT_CAST (parse), buffer,
2384 parse->common.offset);
2385 parse->common.offset += bytes;
2392 gst_matroska_parse_check_seekability (GstMatroskaParse * parse)
2395 gboolean seekable = FALSE;
2396 gint64 start = -1, stop = -1;
2398 query = gst_query_new_seeking (GST_FORMAT_BYTES);
2399 if (!gst_pad_peer_query (parse->common.sinkpad, query)) {
2400 GST_DEBUG_OBJECT (parse, "seeking query failed");
2404 gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
2406 /* try harder to query upstream size if we didn't get it the first time */
2407 if (seekable && stop == -1) {
2408 GST_DEBUG_OBJECT (parse, "doing duration query to fix up unset stop");
2409 gst_pad_peer_query_duration (parse->common.sinkpad, GST_FORMAT_BYTES,
2413 /* if upstream doesn't know the size, it's likely that it's not seekable in
2414 * practice even if it technically may be seekable */
2415 if (seekable && (start != 0 || stop <= start)) {
2416 GST_DEBUG_OBJECT (parse, "seekable but unknown start/stop -> disable");
2421 GST_INFO_OBJECT (parse, "seekable: %d (%" G_GUINT64_FORMAT " - %"
2422 G_GUINT64_FORMAT ")", seekable, start, stop);
2423 parse->seekable = seekable;
2425 gst_query_unref (query);
2429 static GstFlowReturn
2430 gst_matroska_parse_find_tracks (GstMatroskaParse * parse)
2436 GstFlowReturn ret = GST_FLOW_OK;
2438 GST_WARNING_OBJECT (parse,
2439 "Found Cluster element before Tracks, searching Tracks");
2442 before_pos = parse->common.offset;
2444 /* Search Tracks element */
2446 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2447 GST_ELEMENT_CAST (parse), &id, &length, &needed);
2448 if (ret != GST_FLOW_OK)
2451 if (id != GST_MATROSKA_ID_TRACKS) {
2452 /* we may be skipping large cluster here, so forego size check etc */
2453 /* ... but we can't skip undefined size; force error */
2454 if (length == G_MAXUINT64) {
2455 ret = gst_matroska_parse_check_read_size (parse, length);
2458 parse->common.offset += needed;
2459 parse->offset += length;
2464 /* will lead to track parsing ... */
2465 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2470 parse->offset = before_pos;
2476 #define GST_READ_CHECK(stmt) \
2478 if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
2479 if (ret == GST_FLOW_OVERFLOW) { \
2480 ret = GST_FLOW_OK; \
2487 gst_matroska_parse_accumulate_streamheader (GstMatroskaParse * parse,
2490 if (parse->pushed_headers) {
2491 GST_WARNING_OBJECT (parse,
2492 "Accumulating headers, but headers are already pushed");
2495 if (parse->streamheader) {
2498 buf = gst_buffer_span (parse->streamheader, 0, buffer,
2499 gst_buffer_get_size (parse->streamheader) +
2500 gst_buffer_get_size (buffer));
2501 gst_buffer_unref (parse->streamheader);
2502 parse->streamheader = buf;
2504 parse->streamheader = gst_buffer_ref (buffer);
2507 GST_DEBUG ("%d", gst_buffer_get_size (parse->streamheader));
2510 static GstFlowReturn
2511 gst_matroska_parse_output (GstMatroskaParse * parse, GstBuffer * buffer,
2514 GstFlowReturn ret = GST_FLOW_OK;
2516 if (!parse->pushed_headers) {
2519 GValue streamheader = { 0 };
2520 GValue bufval = { 0 };
2523 caps = gst_caps_new_empty_simple ("video/x-matroska");
2524 s = gst_caps_get_structure (caps, 0);
2525 g_value_init (&streamheader, GST_TYPE_ARRAY);
2526 g_value_init (&bufval, GST_TYPE_BUFFER);
2527 buf = gst_buffer_copy (parse->streamheader);
2528 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
2529 gst_value_set_buffer (&bufval, buf);
2530 gst_buffer_unref (buf);
2531 gst_value_array_append_value (&streamheader, &bufval);
2532 g_value_unset (&bufval);
2533 gst_structure_set_value (s, "streamheader", &streamheader);
2534 g_value_unset (&streamheader);
2535 //gst_caps_replace (parse->caps, caps);
2536 gst_pad_set_caps (parse->srcpad, caps);
2538 buf = gst_buffer_copy (parse->streamheader);
2539 gst_caps_unref (caps);
2541 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2542 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
2543 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
2545 ret = gst_pad_push (parse->srcpad, buf);
2547 parse->pushed_headers = TRUE;
2551 GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2553 GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2555 if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE) {
2556 parse->last_timestamp = GST_BUFFER_TIMESTAMP (buffer);
2558 GST_BUFFER_TIMESTAMP (buffer) = parse->last_timestamp;
2560 ret = gst_pad_push (parse->srcpad, gst_buffer_ref (buffer));
2565 static GstFlowReturn
2566 gst_matroska_parse_parse_id (GstMatroskaParse * parse, guint32 id,
2567 guint64 length, guint needed)
2569 GstEbmlRead ebml = { 0, };
2570 GstFlowReturn ret = GST_FLOW_OK;
2572 //GstBuffer *buffer;
2574 GST_DEBUG_OBJECT (parse, "Parsing Element id 0x%x, "
2575 "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
2578 if (gst_adapter_available (parse->adapter) >= length + needed) {
2579 buffer = gst_adapter_take_buffer (parse->adapter, length + needed);
2580 gst_pad_push (parse->srcpad, buffer);
2582 ret = GST_FLOW_UNEXPECTED;
2584 //GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2591 /* if we plan to read and parse this element, we need prefix (id + length)
2592 * and the contents */
2593 /* mind about overflow wrap-around when dealing with undefined size */
2595 if (G_LIKELY (length != G_MAXUINT64))
2598 switch (parse->common.state) {
2599 case GST_MATROSKA_READ_STATE_START:
2601 case GST_EBML_ID_HEADER:
2602 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2603 ret = gst_matroska_read_common_parse_header (&parse->common, &ebml);
2604 if (ret != GST_FLOW_OK)
2606 parse->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
2607 gst_matroska_parse_check_seekability (parse);
2608 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2611 goto invalid_header;
2615 case GST_MATROSKA_READ_STATE_SEGMENT:
2617 case GST_MATROSKA_ID_SEGMENT:
2618 /* eat segment prefix */
2619 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2620 GST_DEBUG_OBJECT (parse,
2621 "Found Segment start at offset %" G_GUINT64_FORMAT,
2622 parse->common.offset);
2623 /* seeks are from the beginning of the segment,
2624 * after the segment ID/length */
2625 parse->common.ebml_segment_start = parse->common.offset;
2626 parse->common.state = GST_MATROSKA_READ_STATE_HEADER;
2627 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2630 GST_WARNING_OBJECT (parse,
2631 "Expected a Segment ID (0x%x), but received 0x%x!",
2632 GST_MATROSKA_ID_SEGMENT, id);
2633 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2634 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2638 case GST_MATROSKA_READ_STATE_SCANNING:
2639 if (id != GST_MATROSKA_ID_CLUSTER &&
2640 id != GST_MATROSKA_ID_CLUSTERTIMECODE)
2643 case GST_MATROSKA_READ_STATE_HEADER:
2644 case GST_MATROSKA_READ_STATE_DATA:
2645 case GST_MATROSKA_READ_STATE_SEEK:
2647 case GST_MATROSKA_ID_SEGMENTINFO:
2648 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2649 if (!parse->common.segmentinfo_parsed) {
2650 ret = gst_matroska_read_common_parse_info (&parse->common,
2651 GST_ELEMENT_CAST (parse), &ebml);
2653 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2655 case GST_MATROSKA_ID_TRACKS:
2656 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2657 if (!parse->tracks_parsed) {
2658 ret = gst_matroska_parse_parse_tracks (parse, &ebml);
2660 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2662 case GST_MATROSKA_ID_CLUSTER:
2663 if (G_UNLIKELY (!parse->tracks_parsed)) {
2664 GST_DEBUG_OBJECT (parse, "Cluster before Track");
2665 goto not_streamable;
2667 if (G_UNLIKELY (parse->common.state
2668 == GST_MATROSKA_READ_STATE_HEADER)) {
2669 parse->common.state = GST_MATROSKA_READ_STATE_DATA;
2670 parse->first_cluster_offset = parse->common.offset;
2671 GST_DEBUG_OBJECT (parse, "signaling no more pads");
2673 parse->cluster_time = GST_CLOCK_TIME_NONE;
2674 parse->cluster_offset = parse->common.offset;
2675 if (G_UNLIKELY (!parse->seek_first && parse->seek_block)) {
2676 GST_DEBUG_OBJECT (parse, "seek target block %" G_GUINT64_FORMAT
2677 " not found in Cluster, trying next Cluster's first block instead",
2679 parse->seek_block = 0;
2681 parse->seek_first = FALSE;
2682 /* record next cluster for recovery */
2683 if (read != G_MAXUINT64)
2684 parse->next_cluster_offset = parse->cluster_offset + read;
2685 /* eat cluster prefix */
2686 GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2687 ret = gst_matroska_parse_output (parse, ebml.buf, TRUE);
2688 //gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2690 case GST_MATROSKA_ID_CLUSTERTIMECODE:
2694 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2695 if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
2697 GST_DEBUG_OBJECT (parse, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
2698 parse->cluster_time = num;
2699 if (parse->common.element_index) {
2700 if (parse->common.element_index_writer_id == -1)
2701 gst_index_get_writer_id (parse->common.element_index,
2702 GST_OBJECT (parse), &parse->common.element_index_writer_id);
2703 GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
2704 G_GUINT64_FORMAT " for writer id %d",
2705 GST_TIME_ARGS (parse->cluster_time), parse->cluster_offset,
2706 parse->common.element_index_writer_id);
2707 gst_index_add_association (parse->common.element_index,
2708 parse->common.element_index_writer_id,
2709 GST_ASSOCIATION_FLAG_KEY_UNIT,
2710 GST_FORMAT_TIME, parse->cluster_time,
2711 GST_FORMAT_BYTES, parse->cluster_offset, NULL);
2713 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2716 case GST_MATROSKA_ID_BLOCKGROUP:
2717 if (!gst_matroska_parse_seek_block (parse))
2719 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2720 DEBUG_ELEMENT_START (parse, &ebml, "BlockGroup");
2721 if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
2722 ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
2723 &ebml, parse->cluster_time, parse->cluster_offset, FALSE);
2725 DEBUG_ELEMENT_STOP (parse, &ebml, "BlockGroup", ret);
2726 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2728 case GST_MATROSKA_ID_SIMPLEBLOCK:
2729 if (!gst_matroska_parse_seek_block (parse))
2731 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2732 DEBUG_ELEMENT_START (parse, &ebml, "SimpleBlock");
2733 ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
2734 &ebml, parse->cluster_time, parse->cluster_offset, TRUE);
2735 DEBUG_ELEMENT_STOP (parse, &ebml, "SimpleBlock", ret);
2736 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2738 case GST_MATROSKA_ID_ATTACHMENTS:
2739 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2740 if (!parse->common.attachments_parsed) {
2741 ret = gst_matroska_read_common_parse_attachments (&parse->common,
2742 GST_ELEMENT_CAST (parse), &ebml);
2744 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2746 case GST_MATROSKA_ID_TAGS:
2747 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2748 ret = gst_matroska_read_common_parse_metadata (&parse->common,
2749 GST_ELEMENT_CAST (parse), &ebml);
2750 gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2752 case GST_MATROSKA_ID_CHAPTERS:
2753 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2754 ret = gst_matroska_read_common_parse_chapters (&parse->common, &ebml);
2755 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2757 case GST_MATROSKA_ID_SEEKHEAD:
2758 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2759 ret = gst_matroska_parse_parse_contents (parse, &ebml);
2760 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2762 case GST_MATROSKA_ID_CUES:
2763 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2764 if (!parse->common.index_parsed) {
2765 ret = gst_matroska_read_common_parse_index (&parse->common, &ebml);
2766 /* only push based; delayed index building */
2767 if (ret == GST_FLOW_OK
2768 && parse->common.state == GST_MATROSKA_READ_STATE_SEEK) {
2771 GST_OBJECT_LOCK (parse);
2772 event = parse->seek_event;
2773 parse->seek_event = NULL;
2774 GST_OBJECT_UNLOCK (parse);
2777 /* unlikely to fail, since we managed to seek to this point */
2778 if (!gst_matroska_parse_handle_seek_event (parse, NULL, event))
2780 /* resume data handling, main thread clear to seek again */
2781 GST_OBJECT_LOCK (parse);
2782 parse->common.state = GST_MATROSKA_READ_STATE_DATA;
2783 GST_OBJECT_UNLOCK (parse);
2786 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2788 case GST_MATROSKA_ID_POSITION:
2789 case GST_MATROSKA_ID_PREVSIZE:
2790 case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
2791 case GST_MATROSKA_ID_SILENTTRACKS:
2792 GST_DEBUG_OBJECT (parse,
2793 "Skipping Cluster subelement 0x%x - ignoring", id);
2797 GST_DEBUG_OBJECT (parse, "skipping Element 0x%x", id);
2798 GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2799 gst_matroska_parse_output (parse, ebml.buf, FALSE);
2805 if (ret == GST_FLOW_PARSE)
2809 gst_ebml_read_clear (&ebml);
2815 /* simply exit, maybe not enough data yet */
2816 /* no ebml to clear if read error */
2821 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2822 ("Failed to parse Element 0x%x", id));
2823 ret = GST_FLOW_ERROR;
2828 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2829 ("File layout does not permit streaming"));
2830 ret = GST_FLOW_ERROR;
2836 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2837 ("No Tracks element found"));
2838 ret = GST_FLOW_ERROR;
2844 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Invalid header"));
2845 ret = GST_FLOW_ERROR;
2850 GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Failed to seek"));
2851 ret = GST_FLOW_ERROR;
2858 gst_matroska_parse_loop (GstPad * pad)
2860 GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
2866 /* If we have to close a segment, send a new segment to do this now */
2867 if (G_LIKELY (parse->common.state == GST_MATROSKA_READ_STATE_DATA)) {
2868 if (G_UNLIKELY (parse->close_segment)) {
2869 gst_matroska_parse_send_event (parse, parse->close_segment);
2870 parse->close_segment = NULL;
2872 if (G_UNLIKELY (parse->new_segment)) {
2873 gst_matroska_parse_send_event (parse, parse->new_segment);
2874 parse->new_segment = NULL;
2878 ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2879 GST_ELEMENT_CAST (parse), &id, &length, &needed);
2880 if (ret == GST_FLOW_UNEXPECTED)
2882 if (ret != GST_FLOW_OK) {
2883 if (gst_matroska_parse_check_parse_error (parse))
2889 GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2890 "size %" G_GUINT64_FORMAT ", needed %d", parse->offset, id,
2893 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2894 if (ret == GST_FLOW_UNEXPECTED)
2896 if (ret != GST_FLOW_OK)
2899 /* check if we're at the end of a configured segment */
2900 if (G_LIKELY (parse->src->len)) {
2903 g_assert (parse->num_streams == parse->src->len);
2904 for (i = 0; i < parse->src->len; i++) {
2905 GstMatroskaTrackContext *context = g_ptr_array_index (parse->src, i);
2906 GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
2907 GST_TIME_ARGS (context->pos));
2908 if (context->eos == FALSE)
2912 GST_INFO_OBJECT (parse, "All streams are EOS");
2913 ret = GST_FLOW_UNEXPECTED;
2918 if (G_UNLIKELY (parse->offset ==
2919 gst_matroska_read_common_get_length (&parse->common))) {
2920 GST_LOG_OBJECT (parse, "Reached end of stream");
2921 ret = GST_FLOW_UNEXPECTED;
2930 if (parse->segment.rate < 0.0) {
2931 ret = gst_matroska_parse_seek_to_previous_keyframe (parse);
2932 if (ret == GST_FLOW_OK)
2939 const gchar *reason = gst_flow_get_name (ret);
2940 gboolean push_eos = FALSE;
2942 GST_LOG_OBJECT (parse, "pausing task, reason %s", reason);
2943 parse->segment_running = FALSE;
2944 gst_pad_pause_task (parse->common.sinkpad);
2946 if (ret == GST_FLOW_UNEXPECTED) {
2947 /* perform EOS logic */
2949 /* Close the segment, i.e. update segment stop with the duration
2950 * if no stop was set */
2951 if (GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) &&
2952 !GST_CLOCK_TIME_IS_VALID (parse->segment.stop)) {
2954 gst_event_new_new_segment_full (TRUE, parse->segment.rate,
2955 parse->segment.applied_rate, parse->segment.format,
2956 parse->segment.start,
2957 MAX (parse->last_stop_end, parse->segment.start),
2958 parse->segment.time);
2959 gst_matroska_parse_send_event (parse, event);
2962 if (parse->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2965 /* for segment playback we need to post when (in stream time)
2966 * we stopped, this is either stop (when set) or the duration. */
2967 if ((stop = parse->segment.stop) == -1)
2968 stop = parse->last_stop_end;
2970 GST_LOG_OBJECT (parse, "Sending segment done, at end of segment");
2971 gst_element_post_message (GST_ELEMENT (parse),
2972 gst_message_new_segment_done (GST_OBJECT (parse), GST_FORMAT_TIME,
2977 } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_UNEXPECTED) {
2978 /* for fatal errors we post an error message */
2979 GST_ELEMENT_ERROR (parse, STREAM, FAILED, (NULL),
2980 ("stream stopped, reason %s", reason));
2984 /* send EOS, and prevent hanging if no streams yet */
2985 GST_LOG_OBJECT (parse, "Sending EOS, at end of stream");
2986 if (!gst_matroska_parse_send_event (parse, gst_event_new_eos ()) &&
2987 (ret == GST_FLOW_UNEXPECTED)) {
2988 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
2989 (NULL), ("got eos but no streams (yet)"));
2998 * Create and push a flushing seek event upstream
3001 perform_seek_to_offset (GstMatroskaParse * parse, guint64 offset)
3006 GST_DEBUG_OBJECT (parse, "Seeking to %" G_GUINT64_FORMAT, offset);
3009 gst_event_new_seek (1.0, GST_FORMAT_BYTES,
3010 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
3011 GST_SEEK_TYPE_NONE, -1);
3013 res = gst_pad_push_event (parse->common.sinkpad, event);
3015 /* newsegment event will update offset */
3019 static GstFlowReturn
3020 gst_matroska_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
3022 GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
3024 GstFlowReturn ret = GST_FLOW_OK;
3029 if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
3030 GST_DEBUG_OBJECT (parse, "got DISCONT");
3031 gst_adapter_clear (parse->common.adapter);
3032 GST_OBJECT_LOCK (parse);
3033 gst_matroska_read_common_reset_streams (&parse->common,
3034 GST_CLOCK_TIME_NONE, FALSE);
3035 GST_OBJECT_UNLOCK (parse);
3038 gst_adapter_push (parse->common.adapter, buffer);
3042 available = gst_adapter_available (parse->common.adapter);
3044 ret = gst_matroska_read_common_peek_id_length_push (&parse->common,
3045 GST_ELEMENT_CAST (parse), &id, &length, &needed);
3046 if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED))
3049 GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
3050 "size %" G_GUINT64_FORMAT ", needed %d, available %d",
3051 parse->common.offset, id, length, needed, available);
3053 if (needed > available)
3056 ret = gst_matroska_parse_parse_id (parse, id, length, needed);
3057 if (ret == GST_FLOW_UNEXPECTED) {
3058 /* need more data */
3060 } else if (ret != GST_FLOW_OK) {
3067 gst_matroska_parse_handle_sink_event (GstPad * pad, GstObject * parent,
3070 gboolean res = TRUE;
3071 GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
3073 GST_DEBUG_OBJECT (parse,
3074 "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
3076 switch (GST_EVENT_TYPE (event)) {
3077 case GST_EVENT_SEGMENT:
3079 const GstSegment *segment;
3081 /* some debug output */
3082 gst_event_parse_segment (event, &segment);
3083 GST_DEBUG_OBJECT (parse,
3084 "received format %d newsegment %" GST_SEGMENT_FORMAT,
3085 segment->format, segment);
3087 if (parse->common.state < GST_MATROSKA_READ_STATE_DATA) {
3088 GST_DEBUG_OBJECT (parse, "still starting");
3092 /* we only expect a BYTE segment, e.g. following a seek */
3093 if (segment->format != GST_FORMAT_BYTES) {
3094 GST_DEBUG_OBJECT (parse, "unsupported segment format, ignoring");
3098 GST_DEBUG_OBJECT (parse, "clearing segment state");
3099 /* clear current segment leftover */
3100 gst_adapter_clear (parse->common.adapter);
3101 /* and some streaming setup */
3102 parse->common.offset = segment->start;
3103 /* do not know where we are;
3104 * need to come across a cluster and generate newsegment */
3105 parse->common.segment.position = GST_CLOCK_TIME_NONE;
3106 parse->cluster_time = GST_CLOCK_TIME_NONE;
3107 parse->cluster_offset = 0;
3108 parse->need_newsegment = TRUE;
3109 /* but keep some of the upstream segment */
3110 parse->common.segment.rate = segment->rate;
3112 /* chain will send initial newsegment after pads have been added,
3113 * or otherwise come up with one */
3114 GST_DEBUG_OBJECT (parse, "eating event");
3115 gst_event_unref (event);
3121 if (parse->common.state != GST_MATROSKA_READ_STATE_DATA) {
3122 gst_event_unref (event);
3123 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3124 (NULL), ("got eos and didn't receive a complete header object"));
3125 } else if (parse->common.num_streams == 0) {
3126 GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3127 (NULL), ("got eos but no streams (yet)"));
3129 gst_matroska_parse_send_event (parse, event);
3133 case GST_EVENT_FLUSH_STOP:
3135 gst_adapter_clear (parse->common.adapter);
3136 GST_OBJECT_LOCK (parse);
3137 gst_matroska_read_common_reset_streams (&parse->common,
3138 GST_CLOCK_TIME_NONE, TRUE);
3139 GST_OBJECT_UNLOCK (parse);
3140 parse->common.segment.position = GST_CLOCK_TIME_NONE;
3141 parse->cluster_time = GST_CLOCK_TIME_NONE;
3142 parse->cluster_offset = 0;
3146 res = gst_pad_event_default (pad, parent, event);
3154 gst_matroska_parse_set_index (GstElement * element, GstIndex * index)
3156 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3158 GST_OBJECT_LOCK (parse);
3159 if (parse->common.element_index)
3160 gst_object_unref (parse->common.element_index);
3161 parse->common.element_index = index ? gst_object_ref (index) : NULL;
3162 GST_OBJECT_UNLOCK (parse);
3163 GST_DEBUG_OBJECT (parse, "Set index %" GST_PTR_FORMAT,
3164 parse->common.element_index);
3168 gst_matroska_parse_get_index (GstElement * element)
3170 GstIndex *result = NULL;
3171 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3173 GST_OBJECT_LOCK (parse);
3174 if (parse->common.element_index)
3175 result = gst_object_ref (parse->common.element_index);
3176 GST_OBJECT_UNLOCK (parse);
3178 GST_DEBUG_OBJECT (parse, "Returning index %" GST_PTR_FORMAT, result);
3183 static GstStateChangeReturn
3184 gst_matroska_parse_change_state (GstElement * element,
3185 GstStateChange transition)
3187 GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3188 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
3190 /* handle upwards state changes here */
3191 switch (transition) {
3196 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
3198 /* handle downwards state changes */
3199 switch (transition) {
3200 case GST_STATE_CHANGE_PAUSED_TO_READY:
3201 gst_matroska_parse_reset (GST_ELEMENT (parse));
3211 gst_matroska_parse_plugin_init (GstPlugin * plugin)
3215 /* create an elementfactory for the matroska_parse element */
3216 if (!gst_element_register (plugin, "matroskaparse",
3217 GST_RANK_NONE, GST_TYPE_MATROSKA_PARSE))