matroska: refactor code common to matroskademux and matroskaparse
[gstreamer-omap:kzeros-gst-plugins-good.git] / gst / matroska / matroska-parse.c
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>
6  *
7  * matroska-parse.c: matroska file/stream parser
8  *
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.
13  *
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.
18  *
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.
23  */
24
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
32  */
33
34 /**
35  * SECTION:element-matroskaparse
36  *
37  * matroskaparse parsees a Matroska file into the different contained streams.
38  *
39  * <refsect2>
40  * <title>Example launch line</title>
41  * |[
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.
44  * </refsect2>
45  */
46
47
48 #ifdef HAVE_CONFIG_H
49 #include "config.h"
50 #endif
51
52 #include <math.h>
53 #include <string.h>
54 #include <glib/gprintf.h>
55
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>
61
62 #include <gst/tag/tag.h>
63
64 #include <gst/pbutils/pbutils.h>
65
66 #include "matroska-parse.h"
67 #include "matroska-ids.h"
68
69 GST_DEBUG_CATEGORY_STATIC (matroskaparse_debug);
70 #define GST_CAT_DEFAULT matroskaparse_debug
71
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))
75
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))
79
80 enum
81 {
82   ARG_0,
83   ARG_METADATA,
84   ARG_STREAMINFO
85 };
86
87 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
88     GST_PAD_SINK,
89     GST_PAD_ALWAYS,
90     GST_STATIC_CAPS ("video/x-matroska; video/webm")
91     );
92
93 static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
94     GST_PAD_SRC,
95     GST_PAD_ALWAYS,
96     GST_STATIC_CAPS ("video/x-matroska; video/webm")
97     );
98
99 static GstFlowReturn gst_matroska_parse_parse_id (GstMatroskaParse * parse,
100     guint32 id, guint64 length, guint needed);
101
102 /* element functions */
103 //static void gst_matroska_parse_loop (GstPad * pad);
104
105 static gboolean gst_matroska_parse_element_send_event (GstElement * element,
106     GstEvent * event);
107 static gboolean gst_matroska_parse_element_query (GstElement * element,
108     GstQuery * query);
109
110 /* pad functions */
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     GstEvent * event);
115 static const GstQueryType *gst_matroska_parse_get_src_query_types (GstPad *
116     pad);
117 static gboolean gst_matroska_parse_handle_src_query (GstPad * pad,
118     GstQuery * query);
119
120 static gboolean gst_matroska_parse_handle_sink_event (GstPad * pad,
121     GstEvent * event);
122 static GstFlowReturn gst_matroska_parse_chain (GstPad * pad,
123     GstBuffer * buffer);
124
125 static GstStateChangeReturn
126 gst_matroska_parse_change_state (GstElement * element,
127     GstStateChange transition);
128 static void
129 gst_matroska_parse_set_index (GstElement * element, GstIndex * index);
130 static GstIndex *gst_matroska_parse_get_index (GstElement * element);
131
132 /* stream methods */
133 static void gst_matroska_parse_reset (GstElement * element);
134 static gboolean perform_seek_to_offset (GstMatroskaParse * parse,
135     guint64 offset);
136
137 GType gst_matroska_parse_get_type (void);
138 GST_BOILERPLATE (GstMatroskaParse, gst_matroska_parse, GstElement,
139     GST_TYPE_ELEMENT);
140
141 static void
142 gst_matroska_parse_base_init (gpointer klass)
143 {
144   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
145
146   gst_element_class_add_pad_template (element_class,
147       gst_static_pad_template_get (&src_templ));
148   gst_element_class_add_pad_template (element_class,
149       gst_static_pad_template_get (&sink_templ));
150
151   gst_element_class_set_details_simple (element_class, "Matroska parser",
152       "Codec/Parser",
153       "Parses Matroska/WebM streams into video/audio/subtitles",
154       "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
155 }
156
157 static void
158 gst_matroska_parse_finalize (GObject * object)
159 {
160   GstMatroskaParse *parse = GST_MATROSKA_PARSE (object);
161
162   if (parse->common.src) {
163     g_ptr_array_free (parse->common.src, TRUE);
164     parse->common.src = NULL;
165   }
166
167   if (parse->common.global_tags) {
168     gst_tag_list_free (parse->common.global_tags);
169     parse->common.global_tags = NULL;
170   }
171
172   g_object_unref (parse->common.adapter);
173
174   G_OBJECT_CLASS (parent_class)->finalize (object);
175 }
176
177 static void
178 gst_matroska_parse_class_init (GstMatroskaParseClass * klass)
179 {
180   GObjectClass *gobject_class = (GObjectClass *) klass;
181   GstElementClass *gstelement_class = (GstElementClass *) klass;
182
183   GST_DEBUG_CATEGORY_INIT (matroskaparse_debug, "matroskaparse", 0,
184       "Matroska parser");
185
186   gobject_class->finalize = gst_matroska_parse_finalize;
187
188   gstelement_class->change_state =
189       GST_DEBUG_FUNCPTR (gst_matroska_parse_change_state);
190   gstelement_class->send_event =
191       GST_DEBUG_FUNCPTR (gst_matroska_parse_element_send_event);
192   gstelement_class->query =
193       GST_DEBUG_FUNCPTR (gst_matroska_parse_element_query);
194
195   gstelement_class->set_index =
196       GST_DEBUG_FUNCPTR (gst_matroska_parse_set_index);
197   gstelement_class->get_index =
198       GST_DEBUG_FUNCPTR (gst_matroska_parse_get_index);
199 }
200
201 static void
202 gst_matroska_parse_init (GstMatroskaParse * parse,
203     GstMatroskaParseClass * klass)
204 {
205   parse->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
206       "sink");
207   gst_pad_set_chain_function (parse->common.sinkpad,
208       GST_DEBUG_FUNCPTR (gst_matroska_parse_chain));
209   gst_pad_set_event_function (parse->common.sinkpad,
210       GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_sink_event));
211   gst_element_add_pad (GST_ELEMENT (parse), parse->common.sinkpad);
212
213   parse->srcpad = gst_pad_new_from_static_template (&src_templ, "src");
214   gst_pad_set_event_function (parse->srcpad,
215       GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_event));
216   gst_pad_set_query_type_function (parse->srcpad,
217       GST_DEBUG_FUNCPTR (gst_matroska_parse_get_src_query_types));
218   gst_pad_set_query_function (parse->srcpad,
219       GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_query));
220   gst_pad_use_fixed_caps (parse->srcpad);
221
222   gst_element_add_pad (GST_ELEMENT (parse), parse->srcpad);
223
224   /* initial stream no. */
225   parse->common.src = NULL;
226
227   parse->common.writing_app = NULL;
228   parse->common.muxing_app = NULL;
229   parse->common.index = NULL;
230   parse->common.global_tags = NULL;
231
232   parse->common.adapter = gst_adapter_new ();
233
234   /* finish off */
235   gst_matroska_parse_reset (GST_ELEMENT (parse));
236 }
237
238 static void
239 gst_matroska_track_free (GstMatroskaTrackContext * track)
240 {
241   g_free (track->codec_id);
242   g_free (track->codec_name);
243   g_free (track->name);
244   g_free (track->language);
245   g_free (track->codec_priv);
246   g_free (track->codec_state);
247
248   if (track->encodings != NULL) {
249     int i;
250
251     for (i = 0; i < track->encodings->len; ++i) {
252       GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
253           GstMatroskaTrackEncoding,
254           i);
255
256       g_free (enc->comp_settings);
257     }
258     g_array_free (track->encodings, TRUE);
259   }
260
261   if (track->pending_tags)
262     gst_tag_list_free (track->pending_tags);
263
264   if (track->index_table)
265     g_array_free (track->index_table, TRUE);
266
267   g_free (track);
268 }
269
270 static void
271 gst_matroska_parse_free_parsed_el (gpointer mem, gpointer user_data)
272 {
273   g_slice_free (guint64, mem);
274 }
275
276 static void
277 gst_matroska_parse_reset (GstElement * element)
278 {
279   GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
280   guint i;
281
282   GST_DEBUG_OBJECT (parse, "Resetting state");
283
284   /* reset input */
285   parse->common.state = GST_MATROSKA_READ_STATE_START;
286
287   /* clean up existing streams */
288   if (parse->common.src) {
289     g_assert (parse->common.src->len == parse->common.num_streams);
290     for (i = 0; i < parse->common.src->len; i++) {
291       GstMatroskaTrackContext *context = g_ptr_array_index (parse->common.src,
292           i);
293
294       gst_caps_replace (&context->caps, NULL);
295       gst_matroska_track_free (context);
296     }
297     g_ptr_array_free (parse->common.src, TRUE);
298   }
299   parse->common.src = g_ptr_array_new ();
300
301   parse->common.num_streams = 0;
302   parse->num_a_streams = 0;
303   parse->num_t_streams = 0;
304   parse->num_v_streams = 0;
305
306   /* reset media info */
307   g_free (parse->common.writing_app);
308   parse->common.writing_app = NULL;
309   g_free (parse->common.muxing_app);
310   parse->common.muxing_app = NULL;
311
312   /* reset indexes */
313   if (parse->common.index) {
314     g_array_free (parse->common.index, TRUE);
315     parse->common.index = NULL;
316   }
317
318   /* reset timers */
319   parse->clock = NULL;
320   parse->common.time_scale = 1000000;
321   parse->common.created = G_MININT64;
322
323   parse->common.index_parsed = FALSE;
324   parse->tracks_parsed = FALSE;
325   parse->common.segmentinfo_parsed = FALSE;
326   parse->attachments_parsed = FALSE;
327
328   g_list_foreach (parse->common.tags_parsed,
329       (GFunc) gst_matroska_parse_free_parsed_el, NULL);
330   g_list_free (parse->common.tags_parsed);
331   parse->common.tags_parsed = NULL;
332
333   g_list_foreach (parse->seek_parsed,
334       (GFunc) gst_matroska_parse_free_parsed_el, NULL);
335   g_list_free (parse->seek_parsed);
336   parse->seek_parsed = NULL;
337
338   gst_segment_init (&parse->common.segment, GST_FORMAT_TIME);
339   parse->last_stop_end = GST_CLOCK_TIME_NONE;
340   parse->seek_block = 0;
341
342   parse->common.offset = 0;
343   parse->cluster_time = GST_CLOCK_TIME_NONE;
344   parse->cluster_offset = 0;
345   parse->next_cluster_offset = 0;
346   parse->index_offset = 0;
347   parse->seekable = FALSE;
348   parse->need_newsegment = FALSE;
349   parse->building_index = FALSE;
350   if (parse->seek_event) {
351     gst_event_unref (parse->seek_event);
352     parse->seek_event = NULL;
353   }
354
355   parse->seek_index = NULL;
356   parse->seek_entry = 0;
357
358   if (parse->close_segment) {
359     gst_event_unref (parse->close_segment);
360     parse->close_segment = NULL;
361   }
362
363   if (parse->new_segment) {
364     gst_event_unref (parse->new_segment);
365     parse->new_segment = NULL;
366   }
367
368   if (parse->common.element_index) {
369     gst_object_unref (parse->common.element_index);
370     parse->common.element_index = NULL;
371   }
372   parse->common.element_index_writer_id = -1;
373
374   if (parse->common.global_tags) {
375     gst_tag_list_free (parse->common.global_tags);
376   }
377   parse->common.global_tags = gst_tag_list_new ();
378
379   if (parse->common.cached_buffer) {
380     gst_buffer_unref (parse->common.cached_buffer);
381     parse->common.cached_buffer = NULL;
382   }
383 }
384
385 static GstFlowReturn
386 gst_matroska_parse_add_stream (GstMatroskaParse * parse, GstEbmlRead * ebml)
387 {
388   GstMatroskaTrackContext *context;
389   GstFlowReturn ret;
390   guint32 id;
391
392   DEBUG_ELEMENT_START (parse, ebml, "TrackEntry");
393
394   /* start with the master */
395   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
396     DEBUG_ELEMENT_STOP (parse, ebml, "TrackEntry", ret);
397     return ret;
398   }
399
400   /* allocate generic... if we know the type, we'll g_renew()
401    * with the precise type */
402   context = g_new0 (GstMatroskaTrackContext, 1);
403   g_ptr_array_add (parse->common.src, context);
404   context->index = parse->common.num_streams;
405   context->index_writer_id = -1;
406   context->type = 0;            /* no type yet */
407   context->default_duration = 0;
408   context->pos = 0;
409   context->set_discont = TRUE;
410   context->timecodescale = 1.0;
411   context->flags =
412       GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
413       GST_MATROSKA_TRACK_LACING;
414   context->last_flow = GST_FLOW_OK;
415   context->to_offset = G_MAXINT64;
416   parse->common.num_streams++;
417   g_assert (parse->common.src->len == parse->common.num_streams);
418
419   GST_DEBUG_OBJECT (parse, "Stream number %d", context->index);
420
421   /* try reading the trackentry headers */
422   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
423     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
424       break;
425
426     switch (id) {
427         /* track number (unique stream ID) */
428       case GST_MATROSKA_ID_TRACKNUMBER:{
429         guint64 num;
430
431         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
432           break;
433
434         if (num == 0) {
435           GST_ERROR_OBJECT (parse, "Invalid TrackNumber 0");
436           ret = GST_FLOW_ERROR;
437           break;
438         } else if (!gst_matroska_read_common_tracknumber_unique (&parse->common,
439                 num)) {
440           GST_ERROR_OBJECT (parse, "TrackNumber %" G_GUINT64_FORMAT
441               " is not unique", num);
442           ret = GST_FLOW_ERROR;
443           break;
444         }
445
446         GST_DEBUG_OBJECT (parse, "TrackNumber: %" G_GUINT64_FORMAT, num);
447         context->num = num;
448         break;
449       }
450         /* track UID (unique identifier) */
451       case GST_MATROSKA_ID_TRACKUID:{
452         guint64 num;
453
454         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
455           break;
456
457         if (num == 0) {
458           GST_ERROR_OBJECT (parse, "Invalid TrackUID 0");
459           ret = GST_FLOW_ERROR;
460           break;
461         }
462
463         GST_DEBUG_OBJECT (parse, "TrackUID: %" G_GUINT64_FORMAT, num);
464         context->uid = num;
465         break;
466       }
467
468         /* track type (video, audio, combined, subtitle, etc.) */
469       case GST_MATROSKA_ID_TRACKTYPE:{
470         guint64 track_type;
471
472         if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
473           break;
474         }
475
476         if (context->type != 0 && context->type != track_type) {
477           GST_WARNING_OBJECT (parse,
478               "More than one tracktype defined in a TrackEntry - skipping");
479           break;
480         } else if (track_type < 1 || track_type > 254) {
481           GST_WARNING_OBJECT (parse, "Invalid TrackType %" G_GUINT64_FORMAT,
482               track_type);
483           break;
484         }
485
486         GST_DEBUG_OBJECT (parse, "TrackType: %" G_GUINT64_FORMAT, track_type);
487
488         /* ok, so we're actually going to reallocate this thing */
489         switch (track_type) {
490           case GST_MATROSKA_TRACK_TYPE_VIDEO:
491             gst_matroska_track_init_video_context (&context);
492             break;
493           case GST_MATROSKA_TRACK_TYPE_AUDIO:
494             gst_matroska_track_init_audio_context (&context);
495             break;
496           case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
497             gst_matroska_track_init_subtitle_context (&context);
498             break;
499           case GST_MATROSKA_TRACK_TYPE_COMPLEX:
500           case GST_MATROSKA_TRACK_TYPE_LOGO:
501           case GST_MATROSKA_TRACK_TYPE_BUTTONS:
502           case GST_MATROSKA_TRACK_TYPE_CONTROL:
503           default:
504             GST_WARNING_OBJECT (parse,
505                 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
506                 track_type);
507             context->type = 0;
508             break;
509         }
510         g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
511             = context;
512         break;
513       }
514
515         /* tracktype specific stuff for video */
516       case GST_MATROSKA_ID_TRACKVIDEO:{
517         GstMatroskaTrackVideoContext *videocontext;
518
519         DEBUG_ELEMENT_START (parse, ebml, "TrackVideo");
520
521         if (!gst_matroska_track_init_video_context (&context)) {
522           GST_WARNING_OBJECT (parse,
523               "TrackVideo element in non-video track - ignoring track");
524           ret = GST_FLOW_ERROR;
525           break;
526         } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
527           break;
528         }
529         videocontext = (GstMatroskaTrackVideoContext *) context;
530         g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
531             = context;
532
533         while (ret == GST_FLOW_OK &&
534             gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
535           if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
536             break;
537
538           switch (id) {
539               /* Should be one level up but some broken muxers write it here. */
540             case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
541               guint64 num;
542
543               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
544                 break;
545
546               if (num == 0) {
547                 GST_WARNING_OBJECT (parse, "Invalid TrackDefaultDuration 0");
548                 break;
549               }
550
551               GST_DEBUG_OBJECT (parse,
552                   "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
553               context->default_duration = num;
554               break;
555             }
556
557               /* video framerate */
558               /* NOTE: This one is here only for backward compatibility.
559                * Use _TRACKDEFAULDURATION one level up. */
560             case GST_MATROSKA_ID_VIDEOFRAMERATE:{
561               gdouble num;
562
563               if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
564                 break;
565
566               if (num <= 0.0) {
567                 GST_WARNING_OBJECT (parse, "Invalid TrackVideoFPS %lf", num);
568                 break;
569               }
570
571               GST_DEBUG_OBJECT (parse, "TrackVideoFrameRate: %lf", num);
572               if (context->default_duration == 0)
573                 context->default_duration =
574                     gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
575               videocontext->default_fps = num;
576               break;
577             }
578
579               /* width of the size to display the video at */
580             case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
581               guint64 num;
582
583               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
584                 break;
585
586               if (num == 0) {
587                 GST_WARNING_OBJECT (parse, "Invalid TrackVideoDisplayWidth 0");
588                 break;
589               }
590
591               GST_DEBUG_OBJECT (parse,
592                   "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
593               videocontext->display_width = num;
594               break;
595             }
596
597               /* height of the size to display the video at */
598             case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
599               guint64 num;
600
601               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
602                 break;
603
604               if (num == 0) {
605                 GST_WARNING_OBJECT (parse, "Invalid TrackVideoDisplayHeight 0");
606                 break;
607               }
608
609               GST_DEBUG_OBJECT (parse,
610                   "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
611               videocontext->display_height = num;
612               break;
613             }
614
615               /* width of the video in the file */
616             case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
617               guint64 num;
618
619               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
620                 break;
621
622               if (num == 0) {
623                 GST_WARNING_OBJECT (parse, "Invalid TrackVideoPixelWidth 0");
624                 break;
625               }
626
627               GST_DEBUG_OBJECT (parse,
628                   "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
629               videocontext->pixel_width = num;
630               break;
631             }
632
633               /* height of the video in the file */
634             case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
635               guint64 num;
636
637               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
638                 break;
639
640               if (num == 0) {
641                 GST_WARNING_OBJECT (parse, "Invalid TrackVideoPixelHeight 0");
642                 break;
643               }
644
645               GST_DEBUG_OBJECT (parse,
646                   "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
647               videocontext->pixel_height = num;
648               break;
649             }
650
651               /* whether the video is interlaced */
652             case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
653               guint64 num;
654
655               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
656                 break;
657
658               if (num)
659                 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
660               else
661                 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
662               GST_DEBUG_OBJECT (parse, "TrackVideoInterlaced: %d",
663                   (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
664                   0);
665               break;
666             }
667
668               /* aspect ratio behaviour */
669             case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
670               guint64 num;
671
672               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
673                 break;
674
675               if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
676                   num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
677                   num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
678                 GST_WARNING_OBJECT (parse,
679                     "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
680                 break;
681               }
682               GST_DEBUG_OBJECT (parse,
683                   "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
684               videocontext->asr_mode = num;
685               break;
686             }
687
688               /* colourspace (only matters for raw video) fourcc */
689             case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
690               guint8 *data;
691               guint64 datalen;
692
693               if ((ret =
694                       gst_ebml_read_binary (ebml, &id, &data,
695                           &datalen)) != GST_FLOW_OK)
696                 break;
697
698               if (datalen != 4) {
699                 g_free (data);
700                 GST_WARNING_OBJECT (parse,
701                     "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
702                     datalen);
703                 break;
704               }
705
706               memcpy (&videocontext->fourcc, data, 4);
707               GST_DEBUG_OBJECT (parse,
708                   "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
709                   GST_FOURCC_ARGS (videocontext->fourcc));
710               g_free (data);
711               break;
712             }
713
714             default:
715               GST_WARNING_OBJECT (parse,
716                   "Unknown TrackVideo subelement 0x%x - ignoring", id);
717               /* fall through */
718             case GST_MATROSKA_ID_VIDEOSTEREOMODE:
719             case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
720             case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
721             case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
722             case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
723             case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
724             case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
725               ret = gst_ebml_read_skip (ebml);
726               break;
727           }
728         }
729
730         DEBUG_ELEMENT_STOP (parse, ebml, "TrackVideo", ret);
731         break;
732       }
733
734         /* tracktype specific stuff for audio */
735       case GST_MATROSKA_ID_TRACKAUDIO:{
736         GstMatroskaTrackAudioContext *audiocontext;
737
738         DEBUG_ELEMENT_START (parse, ebml, "TrackAudio");
739
740         if (!gst_matroska_track_init_audio_context (&context)) {
741           GST_WARNING_OBJECT (parse,
742               "TrackAudio element in non-audio track - ignoring track");
743           ret = GST_FLOW_ERROR;
744           break;
745         }
746
747         if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
748           break;
749
750         audiocontext = (GstMatroskaTrackAudioContext *) context;
751         g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
752             = context;
753
754         while (ret == GST_FLOW_OK &&
755             gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
756           if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
757             break;
758
759           switch (id) {
760               /* samplerate */
761             case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
762               gdouble num;
763
764               if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
765                 break;
766
767
768               if (num <= 0.0) {
769                 GST_WARNING_OBJECT (parse,
770                     "Invalid TrackAudioSamplingFrequency %lf", num);
771                 break;
772               }
773
774               GST_DEBUG_OBJECT (parse, "TrackAudioSamplingFrequency: %lf", num);
775               audiocontext->samplerate = num;
776               break;
777             }
778
779               /* bitdepth */
780             case GST_MATROSKA_ID_AUDIOBITDEPTH:{
781               guint64 num;
782
783               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
784                 break;
785
786               if (num == 0) {
787                 GST_WARNING_OBJECT (parse, "Invalid TrackAudioBitDepth 0");
788                 break;
789               }
790
791               GST_DEBUG_OBJECT (parse, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
792                   num);
793               audiocontext->bitdepth = num;
794               break;
795             }
796
797               /* channels */
798             case GST_MATROSKA_ID_AUDIOCHANNELS:{
799               guint64 num;
800
801               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
802                 break;
803
804               if (num == 0) {
805                 GST_WARNING_OBJECT (parse, "Invalid TrackAudioChannels 0");
806                 break;
807               }
808
809               GST_DEBUG_OBJECT (parse, "TrackAudioChannels: %" G_GUINT64_FORMAT,
810                   num);
811               audiocontext->channels = num;
812               break;
813             }
814
815             default:
816               GST_WARNING_OBJECT (parse,
817                   "Unknown TrackAudio subelement 0x%x - ignoring", id);
818               /* fall through */
819             case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
820             case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
821               ret = gst_ebml_read_skip (ebml);
822               break;
823           }
824         }
825
826         DEBUG_ELEMENT_STOP (parse, ebml, "TrackAudio", ret);
827
828         break;
829       }
830
831         /* codec identifier */
832       case GST_MATROSKA_ID_CODECID:{
833         gchar *text;
834
835         if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
836           break;
837
838         GST_DEBUG_OBJECT (parse, "CodecID: %s", GST_STR_NULL (text));
839         context->codec_id = text;
840         break;
841       }
842
843         /* codec private data */
844       case GST_MATROSKA_ID_CODECPRIVATE:{
845         guint8 *data;
846         guint64 size;
847
848         if ((ret =
849                 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
850           break;
851
852         context->codec_priv = data;
853         context->codec_priv_size = size;
854
855         GST_DEBUG_OBJECT (parse, "CodecPrivate of size %" G_GUINT64_FORMAT,
856             size);
857         break;
858       }
859
860         /* name of the codec */
861       case GST_MATROSKA_ID_CODECNAME:{
862         gchar *text;
863
864         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
865           break;
866
867         GST_DEBUG_OBJECT (parse, "CodecName: %s", GST_STR_NULL (text));
868         context->codec_name = text;
869         break;
870       }
871
872         /* name of this track */
873       case GST_MATROSKA_ID_TRACKNAME:{
874         gchar *text;
875
876         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
877           break;
878
879         context->name = text;
880         GST_DEBUG_OBJECT (parse, "TrackName: %s", GST_STR_NULL (text));
881         break;
882       }
883
884         /* language (matters for audio/subtitles, mostly) */
885       case GST_MATROSKA_ID_TRACKLANGUAGE:{
886         gchar *text;
887
888         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
889           break;
890
891
892         context->language = text;
893
894         /* fre-ca => fre */
895         if (strlen (context->language) >= 4 && context->language[3] == '-')
896           context->language[3] = '\0';
897
898         GST_DEBUG_OBJECT (parse, "TrackLanguage: %s",
899             GST_STR_NULL (context->language));
900         break;
901       }
902
903         /* whether this is actually used */
904       case GST_MATROSKA_ID_TRACKFLAGENABLED:{
905         guint64 num;
906
907         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
908           break;
909
910         if (num)
911           context->flags |= GST_MATROSKA_TRACK_ENABLED;
912         else
913           context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
914
915         GST_DEBUG_OBJECT (parse, "TrackEnabled: %d",
916             (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
917         break;
918       }
919
920         /* whether it's the default for this track type */
921       case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
922         guint64 num;
923
924         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
925           break;
926
927         if (num)
928           context->flags |= GST_MATROSKA_TRACK_DEFAULT;
929         else
930           context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
931
932         GST_DEBUG_OBJECT (parse, "TrackDefault: %d",
933             (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
934         break;
935       }
936
937         /* whether the track must be used during playback */
938       case GST_MATROSKA_ID_TRACKFLAGFORCED:{
939         guint64 num;
940
941         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
942           break;
943
944         if (num)
945           context->flags |= GST_MATROSKA_TRACK_FORCED;
946         else
947           context->flags &= ~GST_MATROSKA_TRACK_FORCED;
948
949         GST_DEBUG_OBJECT (parse, "TrackForced: %d",
950             (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
951         break;
952       }
953
954         /* lacing (like MPEG, where blocks don't end/start on frame
955          * boundaries) */
956       case GST_MATROSKA_ID_TRACKFLAGLACING:{
957         guint64 num;
958
959         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
960           break;
961
962         if (num)
963           context->flags |= GST_MATROSKA_TRACK_LACING;
964         else
965           context->flags &= ~GST_MATROSKA_TRACK_LACING;
966
967         GST_DEBUG_OBJECT (parse, "TrackLacing: %d",
968             (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
969         break;
970       }
971
972         /* default length (in time) of one data block in this track */
973       case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
974         guint64 num;
975
976         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
977           break;
978
979
980         if (num == 0) {
981           GST_WARNING_OBJECT (parse, "Invalid TrackDefaultDuration 0");
982           break;
983         }
984
985         GST_DEBUG_OBJECT (parse, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
986             num);
987         context->default_duration = num;
988         break;
989       }
990
991       case GST_MATROSKA_ID_CONTENTENCODINGS:{
992         ret = gst_matroska_read_common_read_track_encodings (&parse->common,
993             ebml, context);
994         break;
995       }
996
997       case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
998         gdouble num;
999
1000         if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1001           break;
1002
1003         if (num <= 0.0) {
1004           GST_WARNING_OBJECT (parse, "Invalid TrackTimeCodeScale %lf", num);
1005           break;
1006         }
1007
1008         GST_DEBUG_OBJECT (parse, "TrackTimeCodeScale: %lf", num);
1009         context->timecodescale = num;
1010         break;
1011       }
1012
1013       default:
1014         GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1015         /* pass-through */
1016
1017         /* we ignore these because they're nothing useful (i.e. crap)
1018          * or simply not implemented yet. */
1019       case GST_MATROSKA_ID_TRACKMINCACHE:
1020       case GST_MATROSKA_ID_TRACKMAXCACHE:
1021       case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1022       case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1023       case GST_MATROSKA_ID_TRACKOVERLAY:
1024       case GST_MATROSKA_ID_TRACKTRANSLATE:
1025       case GST_MATROSKA_ID_TRACKOFFSET:
1026       case GST_MATROSKA_ID_CODECSETTINGS:
1027       case GST_MATROSKA_ID_CODECINFOURL:
1028       case GST_MATROSKA_ID_CODECDOWNLOADURL:
1029       case GST_MATROSKA_ID_CODECDECODEALL:
1030         ret = gst_ebml_read_skip (ebml);
1031         break;
1032     }
1033   }
1034
1035   DEBUG_ELEMENT_STOP (parse, ebml, "TrackEntry", ret);
1036
1037   /* Decode codec private data if necessary */
1038   if (context->encodings && context->encodings->len > 0 && context->codec_priv
1039       && context->codec_priv_size > 0) {
1040     if (!gst_matroska_decode_data (context->encodings,
1041             &context->codec_priv, &context->codec_priv_size,
1042             GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1043       GST_WARNING_OBJECT (parse, "Decoding codec private data failed");
1044       ret = GST_FLOW_ERROR;
1045     }
1046   }
1047
1048   if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1049           && ret != GST_FLOW_UNEXPECTED)) {
1050     if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
1051       GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1052
1053     parse->common.num_streams--;
1054     g_ptr_array_remove_index (parse->common.src, parse->common.num_streams);
1055     g_assert (parse->common.src->len == parse->common.num_streams);
1056     if (context) {
1057       gst_matroska_track_free (context);
1058     }
1059
1060     return ret;
1061   }
1062
1063   if ((context->language == NULL || *context->language == '\0') &&
1064       (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1065           context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1066     GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1067     context->language = g_strdup ("eng");
1068   }
1069
1070
1071   /* tadaah! */
1072   return ret;
1073 }
1074
1075 static const GstQueryType *
1076 gst_matroska_parse_get_src_query_types (GstPad * pad)
1077 {
1078   static const GstQueryType query_types[] = {
1079     GST_QUERY_POSITION,
1080     GST_QUERY_DURATION,
1081     GST_QUERY_SEEKING,
1082     0
1083   };
1084
1085   return query_types;
1086 }
1087
1088 static gboolean
1089 gst_matroska_parse_query (GstMatroskaParse * parse, GstPad * pad,
1090     GstQuery * query)
1091 {
1092   gboolean res = FALSE;
1093   GstMatroskaTrackContext *context = NULL;
1094
1095   if (pad) {
1096     context = gst_pad_get_element_private (pad);
1097   }
1098
1099   switch (GST_QUERY_TYPE (query)) {
1100     case GST_QUERY_POSITION:
1101     {
1102       GstFormat format;
1103
1104       gst_query_parse_position (query, &format, NULL);
1105
1106       if (format == GST_FORMAT_TIME) {
1107         GST_OBJECT_LOCK (parse);
1108         if (context)
1109           gst_query_set_position (query, GST_FORMAT_TIME, context->pos);
1110         else
1111           gst_query_set_position (query, GST_FORMAT_TIME,
1112               parse->common.segment.last_stop);
1113         GST_OBJECT_UNLOCK (parse);
1114       } else if (format == GST_FORMAT_DEFAULT && context
1115           && context->default_duration) {
1116         GST_OBJECT_LOCK (parse);
1117         gst_query_set_position (query, GST_FORMAT_DEFAULT,
1118             context->pos / context->default_duration);
1119         GST_OBJECT_UNLOCK (parse);
1120       } else {
1121         GST_DEBUG_OBJECT (parse,
1122             "only position query in TIME and DEFAULT format is supported");
1123       }
1124
1125       res = TRUE;
1126       break;
1127     }
1128     case GST_QUERY_DURATION:
1129     {
1130       GstFormat format;
1131
1132       gst_query_parse_duration (query, &format, NULL);
1133
1134       if (format == GST_FORMAT_TIME) {
1135         GST_OBJECT_LOCK (parse);
1136         gst_query_set_duration (query, GST_FORMAT_TIME,
1137             parse->common.segment.duration);
1138         GST_OBJECT_UNLOCK (parse);
1139       } else if (format == GST_FORMAT_DEFAULT && context
1140           && context->default_duration) {
1141         GST_OBJECT_LOCK (parse);
1142         gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1143             parse->common.segment.duration / context->default_duration);
1144         GST_OBJECT_UNLOCK (parse);
1145       } else {
1146         GST_DEBUG_OBJECT (parse,
1147             "only duration query in TIME and DEFAULT format is supported");
1148       }
1149
1150       res = TRUE;
1151       break;
1152     }
1153
1154     case GST_QUERY_SEEKING:
1155     {
1156       GstFormat fmt;
1157
1158       gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1159       if (fmt == GST_FORMAT_TIME) {
1160         gboolean seekable;
1161
1162         /* assuming we'll be able to get an index ... */
1163         seekable = parse->seekable;
1164
1165         gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1166             0, parse->common.segment.duration);
1167         res = TRUE;
1168       }
1169       break;
1170     }
1171     default:
1172       res = gst_pad_query_default (pad, query);
1173       break;
1174   }
1175
1176   return res;
1177 }
1178
1179 static gboolean
1180 gst_matroska_parse_element_query (GstElement * element, GstQuery * query)
1181 {
1182   return gst_matroska_parse_query (GST_MATROSKA_PARSE (element), NULL, query);
1183 }
1184
1185 static gboolean
1186 gst_matroska_parse_handle_src_query (GstPad * pad, GstQuery * query)
1187 {
1188   gboolean ret;
1189   GstMatroskaParse *parse = GST_MATROSKA_PARSE (gst_pad_get_parent (pad));
1190
1191   ret = gst_matroska_parse_query (parse, pad, query);
1192
1193   gst_object_unref (parse);
1194
1195   return ret;
1196 }
1197
1198 /* returns FALSE if there are no pads to deliver event to,
1199  * otherwise TRUE (whatever the outcome of event sending),
1200  * takes ownership of the passed event! */
1201 static gboolean
1202 gst_matroska_parse_send_event (GstMatroskaParse * parse, GstEvent * event)
1203 {
1204   gboolean ret = FALSE;
1205
1206   g_return_val_if_fail (event != NULL, FALSE);
1207
1208   GST_DEBUG_OBJECT (parse, "Sending event of type %s to all source pads",
1209       GST_EVENT_TYPE_NAME (event));
1210
1211   gst_pad_push_event (parse->srcpad, event);
1212
1213   return ret;
1214 }
1215
1216 static gboolean
1217 gst_matroska_parse_element_send_event (GstElement * element, GstEvent * event)
1218 {
1219   GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
1220   gboolean res;
1221
1222   g_return_val_if_fail (event != NULL, FALSE);
1223
1224   if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1225     res = gst_matroska_parse_handle_seek_event (parse, NULL, event);
1226   } else {
1227     GST_WARNING_OBJECT (parse, "Unhandled event of type %s",
1228         GST_EVENT_TYPE_NAME (event));
1229     res = FALSE;
1230   }
1231   gst_event_unref (event);
1232   return res;
1233 }
1234
1235 /* searches for a cluster start from @pos,
1236  * return GST_FLOW_OK and cluster position in @pos if found */
1237 static GstFlowReturn
1238 gst_matroska_parse_search_cluster (GstMatroskaParse * parse, gint64 * pos)
1239 {
1240   gint64 newpos = *pos;
1241   gint64 orig_offset;
1242   GstFlowReturn ret = GST_FLOW_OK;
1243   const guint chunk = 64 * 1024;
1244   GstBuffer *buf = NULL;
1245   guint64 length;
1246   guint32 id;
1247   guint needed;
1248
1249   orig_offset = parse->common.offset;
1250
1251   /* read in at newpos and scan for ebml cluster id */
1252   while (1) {
1253     GstByteReader reader;
1254     gint cluster_pos;
1255
1256     ret = gst_pad_pull_range (parse->common.sinkpad, newpos, chunk, &buf);
1257     if (ret != GST_FLOW_OK)
1258       break;
1259     GST_DEBUG_OBJECT (parse, "read buffer size %d at offset %" G_GINT64_FORMAT,
1260         GST_BUFFER_SIZE (buf), newpos);
1261     gst_byte_reader_init_from_buffer (&reader, buf);
1262     cluster_pos = 0;
1263   resume:
1264     cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1265         GST_MATROSKA_ID_CLUSTER, cluster_pos,
1266         GST_BUFFER_SIZE (buf) - cluster_pos);
1267     if (cluster_pos >= 0) {
1268       newpos += cluster_pos;
1269       GST_DEBUG_OBJECT (parse,
1270           "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1271       /* extra checks whether we really sync'ed to a cluster:
1272        * - either it is the first and only cluster
1273        * - either there is a cluster after this one
1274        * - either cluster length is undefined
1275        */
1276       /* ok if first cluster (there may not a subsequent one) */
1277       if (newpos == parse->first_cluster_offset) {
1278         GST_DEBUG_OBJECT (parse, "cluster is first cluster -> OK");
1279         break;
1280       }
1281       parse->common.offset = newpos;
1282       ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1283           GST_ELEMENT_CAST (parse), &id, &length, &needed);
1284       if (ret != GST_FLOW_OK)
1285         goto resume;
1286       g_assert (id == GST_MATROSKA_ID_CLUSTER);
1287       GST_DEBUG_OBJECT (parse, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1288           length, needed);
1289       /* ok if undefined length or first cluster */
1290       if (length == G_MAXUINT64) {
1291         GST_DEBUG_OBJECT (parse, "cluster has undefined length -> OK");
1292         break;
1293       }
1294       /* skip cluster */
1295       parse->common.offset += length + needed;
1296       ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1297           GST_ELEMENT_CAST (parse), &id, &length, &needed);
1298       if (ret != GST_FLOW_OK)
1299         goto resume;
1300       GST_DEBUG_OBJECT (parse, "next element is %scluster",
1301           id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1302       if (id == GST_MATROSKA_ID_CLUSTER)
1303         break;
1304       /* not ok, resume */
1305       goto resume;
1306     } else {
1307       /* partial cluster id may have been in tail of buffer */
1308       newpos += MAX (GST_BUFFER_SIZE (buf), 4) - 3;
1309       gst_buffer_unref (buf);
1310       buf = NULL;
1311     }
1312   }
1313
1314   if (buf) {
1315     gst_buffer_unref (buf);
1316     buf = NULL;
1317   }
1318
1319   parse->common.offset = orig_offset;
1320   *pos = newpos;
1321   return ret;
1322 }
1323
1324
1325 static gboolean
1326 gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
1327     GstPad * pad, GstEvent * event)
1328 {
1329   GstMatroskaIndex *entry = NULL;
1330   GstSeekFlags flags;
1331   GstSeekType cur_type, stop_type;
1332   GstFormat format;
1333   gdouble rate;
1334   gint64 cur, stop;
1335   GstMatroskaTrackContext *track = NULL;
1336   GstSegment seeksegment = { 0, };
1337   gboolean update;
1338
1339   if (pad)
1340     track = gst_pad_get_element_private (pad);
1341
1342   track = gst_matroska_read_common_get_seek_track (&parse->common, track);
1343
1344   gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1345       &stop_type, &stop);
1346
1347   /* we can only seek on time */
1348   if (format != GST_FORMAT_TIME) {
1349     GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1350     return FALSE;
1351   }
1352
1353   /* copy segment, we need this because we still need the old
1354    * segment when we close the current segment. */
1355   memcpy (&seeksegment, &parse->common.segment, sizeof (GstSegment));
1356
1357   if (event) {
1358     GST_DEBUG_OBJECT (parse, "configuring seek");
1359     gst_segment_set_seek (&seeksegment, rate, format, flags,
1360         cur_type, cur, stop_type, stop, &update);
1361   }
1362
1363   GST_DEBUG_OBJECT (parse, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1364
1365   /* check sanity before we start flushing and all that */
1366   GST_OBJECT_LOCK (parse);
1367   if ((entry = gst_matroska_read_common_do_index_seek (&parse->common, track,
1368               seeksegment.last_stop, &parse->seek_index, &parse->seek_entry)) ==
1369       NULL) {
1370     /* pull mode without index can scan later on */
1371     GST_DEBUG_OBJECT (parse, "No matching seek entry in index");
1372     GST_OBJECT_UNLOCK (parse);
1373     return FALSE;
1374   }
1375   GST_DEBUG_OBJECT (parse, "Seek position looks sane");
1376   GST_OBJECT_UNLOCK (parse);
1377
1378   /* need to seek to cluster start to pick up cluster time */
1379   /* upstream takes care of flushing and all that
1380    * ... and newsegment event handling takes care of the rest */
1381   return perform_seek_to_offset (parse, entry->pos
1382       + parse->common.ebml_segment_start);
1383 }
1384
1385 /*
1386  * Handle whether we can perform the seek event or if we have to let the chain
1387  * function handle seeks to build the seek indexes first.
1388  */
1389 static gboolean
1390 gst_matroska_parse_handle_seek_push (GstMatroskaParse * parse, GstPad * pad,
1391     GstEvent * event)
1392 {
1393   GstSeekFlags flags;
1394   GstSeekType cur_type, stop_type;
1395   GstFormat format;
1396   gdouble rate;
1397   gint64 cur, stop;
1398
1399   gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1400       &stop_type, &stop);
1401
1402   /* sanity checks */
1403
1404   /* we can only seek on time */
1405   if (format != GST_FORMAT_TIME) {
1406     GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1407     return FALSE;
1408   }
1409
1410   if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
1411     GST_DEBUG_OBJECT (parse, "Seek end-time not supported in streaming mode");
1412     return FALSE;
1413   }
1414
1415   if (!(flags & GST_SEEK_FLAG_FLUSH)) {
1416     GST_DEBUG_OBJECT (parse,
1417         "Non-flushing seek not supported in streaming mode");
1418     return FALSE;
1419   }
1420
1421   if (flags & GST_SEEK_FLAG_SEGMENT) {
1422     GST_DEBUG_OBJECT (parse, "Segment seek not supported in streaming mode");
1423     return FALSE;
1424   }
1425
1426   /* check for having parsed index already */
1427   if (!parse->common.index_parsed) {
1428     gboolean building_index;
1429     guint64 offset = 0;
1430
1431     if (!parse->index_offset) {
1432       GST_DEBUG_OBJECT (parse, "no index (location); no seek in push mode");
1433       return FALSE;
1434     }
1435
1436     GST_OBJECT_LOCK (parse);
1437     /* handle the seek event in the chain function */
1438     parse->common.state = GST_MATROSKA_READ_STATE_SEEK;
1439     /* no more seek can be issued until state reset to _DATA */
1440
1441     /* copy the event */
1442     if (parse->seek_event)
1443       gst_event_unref (parse->seek_event);
1444     parse->seek_event = gst_event_ref (event);
1445
1446     /* set the building_index flag so that only one thread can setup the
1447      * structures for index seeking. */
1448     building_index = parse->building_index;
1449     if (!building_index) {
1450       parse->building_index = TRUE;
1451       offset = parse->index_offset;
1452     }
1453     GST_OBJECT_UNLOCK (parse);
1454
1455     if (!building_index) {
1456       /* seek to the first subindex or legacy index */
1457       GST_INFO_OBJECT (parse, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
1458       return perform_seek_to_offset (parse, offset);
1459     }
1460
1461     /* well, we are handling it already */
1462     return TRUE;
1463   }
1464
1465   /* delegate to tweaked regular seek */
1466   return gst_matroska_parse_handle_seek_event (parse, pad, event);
1467 }
1468
1469 static gboolean
1470 gst_matroska_parse_handle_src_event (GstPad * pad, GstEvent * event)
1471 {
1472   GstMatroskaParse *parse = GST_MATROSKA_PARSE (gst_pad_get_parent (pad));
1473   gboolean res = TRUE;
1474
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");
1480         return FALSE;
1481       }
1482       res = gst_matroska_parse_handle_seek_push (parse, pad, event);
1483       gst_event_unref (event);
1484       break;
1485
1486     case GST_EVENT_QOS:
1487     {
1488       GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
1489       if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
1490         GstMatroskaTrackVideoContext *videocontext =
1491             (GstMatroskaTrackVideoContext *) context;
1492         gdouble proportion;
1493         GstClockTimeDiff diff;
1494         GstClockTime timestamp;
1495
1496         gst_event_parse_qos (event, &proportion, &diff, &timestamp);
1497
1498         GST_OBJECT_LOCK (parse);
1499         videocontext->earliest_time = timestamp + diff;
1500         GST_OBJECT_UNLOCK (parse);
1501       }
1502       res = TRUE;
1503       gst_event_unref (event);
1504       break;
1505     }
1506
1507       /* events we don't need to handle */
1508     case GST_EVENT_NAVIGATION:
1509       gst_event_unref (event);
1510       res = FALSE;
1511       break;
1512
1513     case GST_EVENT_LATENCY:
1514     default:
1515       res = gst_pad_push_event (parse->common.sinkpad, event);
1516       break;
1517   }
1518
1519   gst_object_unref (parse);
1520
1521   return res;
1522 }
1523
1524 static GstFlowReturn
1525 gst_matroska_parse_parse_tracks (GstMatroskaParse * parse, GstEbmlRead * ebml)
1526 {
1527   GstFlowReturn ret = GST_FLOW_OK;
1528   guint32 id;
1529
1530   DEBUG_ELEMENT_START (parse, ebml, "Tracks");
1531
1532   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1533     DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1534     return ret;
1535   }
1536
1537   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1538     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1539       break;
1540
1541     switch (id) {
1542         /* one track within the "all-tracks" header */
1543       case GST_MATROSKA_ID_TRACKENTRY:
1544         ret = gst_matroska_parse_add_stream (parse, ebml);
1545         break;
1546
1547       default:
1548         ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1549             "Track", id);
1550         break;
1551     }
1552   }
1553   DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1554
1555   parse->tracks_parsed = TRUE;
1556
1557   return ret;
1558 }
1559
1560 static GstFlowReturn
1561 gst_matroska_parse_parse_attachments (GstMatroskaParse * parse,
1562     GstEbmlRead * ebml)
1563 {
1564   guint32 id;
1565   GstFlowReturn ret = GST_FLOW_OK;
1566   GstTagList *taglist;
1567
1568   DEBUG_ELEMENT_START (parse, ebml, "Attachments");
1569
1570   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1571     DEBUG_ELEMENT_STOP (parse, ebml, "Attachments", ret);
1572     return ret;
1573   }
1574
1575   taglist = gst_tag_list_new ();
1576
1577   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1578     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1579       break;
1580
1581     switch (id) {
1582       case GST_MATROSKA_ID_ATTACHEDFILE:
1583         ret = gst_matroska_read_common_parse_attached_file (&parse->common,
1584             ebml, taglist);
1585         break;
1586
1587       default:
1588         ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1589             "Attachments", id);
1590         break;
1591     }
1592   }
1593   DEBUG_ELEMENT_STOP (parse, ebml, "Attachments", ret);
1594
1595   if (gst_structure_n_fields (GST_STRUCTURE (taglist)) > 0) {
1596     GST_DEBUG_OBJECT (parse, "Storing attachment tags");
1597     gst_matroska_read_common_found_global_tag (&parse->common,
1598         GST_ELEMENT_CAST (parse), taglist);
1599   } else {
1600     GST_DEBUG_OBJECT (parse, "No valid attachments found");
1601     gst_tag_list_free (taglist);
1602   }
1603
1604   parse->attachments_parsed = TRUE;
1605
1606   return ret;
1607 }
1608
1609 static GstFlowReturn
1610 gst_matroska_parse_parse_chapters (GstMatroskaParse * parse, GstEbmlRead * ebml)
1611 {
1612   guint32 id;
1613   GstFlowReturn ret = GST_FLOW_OK;
1614
1615   GST_WARNING_OBJECT (parse, "Parsing of chapters not implemented yet");
1616
1617   /* TODO: implement parsing of chapters */
1618
1619   DEBUG_ELEMENT_START (parse, ebml, "Chapters");
1620
1621   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1622     DEBUG_ELEMENT_STOP (parse, ebml, "Chapters", ret);
1623     return ret;
1624   }
1625
1626   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1627     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1628       break;
1629
1630     switch (id) {
1631       default:
1632         ret = gst_ebml_read_skip (ebml);
1633         break;
1634     }
1635   }
1636
1637   DEBUG_ELEMENT_STOP (parse, ebml, "Chapters", ret);
1638   return ret;
1639 }
1640
1641 /*
1642  * Read signed/unsigned "EBML" numbers.
1643  * Return: number of bytes processed.
1644  */
1645
1646 static gint
1647 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
1648 {
1649   gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
1650   guint64 total;
1651
1652   if (size <= 0) {
1653     return -1;
1654   }
1655
1656   total = data[0];
1657   while (read <= 8 && !(total & len_mask)) {
1658     read++;
1659     len_mask >>= 1;
1660   }
1661   if (read > 8)
1662     return -1;
1663
1664   if ((total &= (len_mask - 1)) == len_mask - 1)
1665     num_ffs++;
1666   if (size < read)
1667     return -1;
1668   while (n < read) {
1669     if (data[n] == 0xff)
1670       num_ffs++;
1671     total = (total << 8) | data[n];
1672     n++;
1673   }
1674
1675   if (read == num_ffs && total != 0)
1676     *num = G_MAXUINT64;
1677   else
1678     *num = total;
1679
1680   return read;
1681 }
1682
1683 static gint
1684 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
1685 {
1686   guint64 unum;
1687   gint res;
1688
1689   /* read as unsigned number first */
1690   if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
1691     return -1;
1692
1693   /* make signed */
1694   if (unum == G_MAXUINT64)
1695     *num = G_MAXINT64;
1696   else
1697     *num = unum - ((1 << ((7 * res) - 1)) - 1);
1698
1699   return res;
1700 }
1701
1702 static GstFlowReturn
1703 gst_matroska_parse_parse_blockgroup_or_simpleblock (GstMatroskaParse * parse,
1704     GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
1705     gboolean is_simpleblock)
1706 {
1707   GstMatroskaTrackContext *stream = NULL;
1708   GstFlowReturn ret = GST_FLOW_OK;
1709   gboolean readblock = FALSE;
1710   guint32 id;
1711   guint64 block_duration = 0;
1712   GstBuffer *buf = NULL;
1713   gint stream_num = -1, n, laces = 0;
1714   guint size = 0;
1715   gint *lace_size = NULL;
1716   gint64 time = 0;
1717   gint flags = 0;
1718   gint64 referenceblock = 0;
1719
1720   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1721     if (!is_simpleblock) {
1722       if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
1723         goto data_error;
1724       }
1725     } else {
1726       id = GST_MATROSKA_ID_SIMPLEBLOCK;
1727     }
1728
1729     switch (id) {
1730         /* one block inside the group. Note, block parsing is one
1731          * of the harder things, so this code is a bit complicated.
1732          * See http://www.matroska.org/ for documentation. */
1733       case GST_MATROSKA_ID_SIMPLEBLOCK:
1734       case GST_MATROSKA_ID_BLOCK:
1735       {
1736         guint64 num;
1737         guint8 *data;
1738
1739         if (buf) {
1740           gst_buffer_unref (buf);
1741           buf = NULL;
1742         }
1743         if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
1744           break;
1745
1746         data = GST_BUFFER_DATA (buf);
1747         size = GST_BUFFER_SIZE (buf);
1748
1749         /* first byte(s): blocknum */
1750         if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1751           goto data_error;
1752         data += n;
1753         size -= n;
1754
1755         /* fetch stream from num */
1756         stream_num = gst_matroska_read_common_stream_from_num (&parse->common,
1757             num);
1758         if (G_UNLIKELY (size < 3)) {
1759           GST_WARNING_OBJECT (parse, "Invalid size %u", size);
1760           /* non-fatal, try next block(group) */
1761           ret = GST_FLOW_OK;
1762           goto done;
1763         } else if (G_UNLIKELY (stream_num < 0 ||
1764                 stream_num >= parse->common.num_streams)) {
1765           /* let's not give up on a stray invalid track number */
1766           GST_WARNING_OBJECT (parse,
1767               "Invalid stream %d for track number %" G_GUINT64_FORMAT
1768               "; ignoring block", stream_num, num);
1769           goto done;
1770         }
1771
1772         stream = g_ptr_array_index (parse->common.src, stream_num);
1773
1774         /* time (relative to cluster time) */
1775         time = ((gint16) GST_READ_UINT16_BE (data));
1776         data += 2;
1777         size -= 2;
1778         flags = GST_READ_UINT8 (data);
1779         data += 1;
1780         size -= 1;
1781
1782         GST_LOG_OBJECT (parse, "time %" G_GUINT64_FORMAT ", flags %d", time,
1783             flags);
1784
1785         switch ((flags & 0x06) >> 1) {
1786           case 0x0:            /* no lacing */
1787             laces = 1;
1788             lace_size = g_new (gint, 1);
1789             lace_size[0] = size;
1790             break;
1791
1792           case 0x1:            /* xiph lacing */
1793           case 0x2:            /* fixed-size lacing */
1794           case 0x3:            /* EBML lacing */
1795             if (size == 0)
1796               goto invalid_lacing;
1797             laces = GST_READ_UINT8 (data) + 1;
1798             data += 1;
1799             size -= 1;
1800             lace_size = g_new0 (gint, laces);
1801
1802             switch ((flags & 0x06) >> 1) {
1803               case 0x1:        /* xiph lacing */  {
1804                 guint temp, total = 0;
1805
1806                 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
1807                   while (1) {
1808                     if (size == 0)
1809                       goto invalid_lacing;
1810                     temp = GST_READ_UINT8 (data);
1811                     lace_size[n] += temp;
1812                     data += 1;
1813                     size -= 1;
1814                     if (temp != 0xff)
1815                       break;
1816                   }
1817                   total += lace_size[n];
1818                 }
1819                 lace_size[n] = size - total;
1820                 break;
1821               }
1822
1823               case 0x2:        /* fixed-size lacing */
1824                 for (n = 0; n < laces; n++)
1825                   lace_size[n] = size / laces;
1826                 break;
1827
1828               case 0x3:        /* EBML lacing */  {
1829                 guint total;
1830
1831                 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1832                   goto data_error;
1833                 data += n;
1834                 size -= n;
1835                 total = lace_size[0] = num;
1836                 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
1837                   gint64 snum;
1838                   gint r;
1839
1840                   if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
1841                     goto data_error;
1842                   data += r;
1843                   size -= r;
1844                   lace_size[n] = lace_size[n - 1] + snum;
1845                   total += lace_size[n];
1846                 }
1847                 if (n < laces)
1848                   lace_size[n] = size - total;
1849                 break;
1850               }
1851             }
1852             break;
1853         }
1854
1855         if (ret != GST_FLOW_OK)
1856           break;
1857
1858         readblock = TRUE;
1859         break;
1860       }
1861
1862       case GST_MATROSKA_ID_BLOCKDURATION:{
1863         ret = gst_ebml_read_uint (ebml, &id, &block_duration);
1864         GST_DEBUG_OBJECT (parse, "BlockDuration: %" G_GUINT64_FORMAT,
1865             block_duration);
1866         break;
1867       }
1868
1869       case GST_MATROSKA_ID_REFERENCEBLOCK:{
1870         ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
1871         GST_DEBUG_OBJECT (parse, "ReferenceBlock: %" G_GINT64_FORMAT,
1872             referenceblock);
1873         break;
1874       }
1875
1876       case GST_MATROSKA_ID_CODECSTATE:{
1877         guint8 *data;
1878         guint64 data_len = 0;
1879
1880         if ((ret =
1881                 gst_ebml_read_binary (ebml, &id, &data,
1882                     &data_len)) != GST_FLOW_OK)
1883           break;
1884
1885         if (G_UNLIKELY (stream == NULL)) {
1886           GST_WARNING_OBJECT (parse,
1887               "Unexpected CodecState subelement - ignoring");
1888           break;
1889         }
1890
1891         g_free (stream->codec_state);
1892         stream->codec_state = data;
1893         stream->codec_state_size = data_len;
1894
1895         break;
1896       }
1897
1898       default:
1899         ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1900             "BlockGroup", id);
1901         break;
1902
1903       case GST_MATROSKA_ID_BLOCKVIRTUAL:
1904       case GST_MATROSKA_ID_BLOCKADDITIONS:
1905       case GST_MATROSKA_ID_REFERENCEPRIORITY:
1906       case GST_MATROSKA_ID_REFERENCEVIRTUAL:
1907       case GST_MATROSKA_ID_SLICES:
1908         GST_DEBUG_OBJECT (parse,
1909             "Skipping BlockGroup subelement 0x%x - ignoring", id);
1910         ret = gst_ebml_read_skip (ebml);
1911         break;
1912     }
1913
1914     if (is_simpleblock)
1915       break;
1916   }
1917
1918   /* reading a number or so could have failed */
1919   if (ret != GST_FLOW_OK)
1920     goto data_error;
1921
1922   if (ret == GST_FLOW_OK && readblock) {
1923     guint64 duration = 0;
1924     gint64 lace_time = 0;
1925     gboolean delta_unit;
1926
1927     stream = g_ptr_array_index (parse->common.src, stream_num);
1928
1929     if (cluster_time != GST_CLOCK_TIME_NONE) {
1930       /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
1931        * Drop unless the lace contains timestamp 0? */
1932       if (time < 0 && (-time) > cluster_time) {
1933         lace_time = 0;
1934       } else {
1935         if (stream->timecodescale == 1.0)
1936           lace_time = (cluster_time + time) * parse->common.time_scale;
1937         else
1938           lace_time =
1939               gst_util_guint64_to_gdouble ((cluster_time + time) *
1940               parse->common.time_scale) * stream->timecodescale;
1941       }
1942     } else {
1943       lace_time = GST_CLOCK_TIME_NONE;
1944     }
1945
1946     if (lace_time != GST_CLOCK_TIME_NONE) {
1947       parse->last_timestamp = lace_time;
1948     }
1949     /* need to refresh segment info ASAP */
1950     if (GST_CLOCK_TIME_IS_VALID (lace_time) && parse->need_newsegment) {
1951       GST_DEBUG_OBJECT (parse,
1952           "generating segment starting at %" GST_TIME_FORMAT,
1953           GST_TIME_ARGS (lace_time));
1954       /* pretend we seeked here */
1955       gst_segment_set_seek (&parse->common.segment, parse->common.segment.rate,
1956           GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, lace_time,
1957           GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE, NULL);
1958       /* now convey our segment notion downstream */
1959       gst_matroska_parse_send_event (parse, gst_event_new_new_segment (FALSE,
1960               parse->common.segment.rate, parse->common.segment.format,
1961               parse->common.segment.start, parse->common.segment.stop,
1962               parse->common.segment.start));
1963       parse->need_newsegment = FALSE;
1964     }
1965
1966     if (block_duration) {
1967       if (stream->timecodescale == 1.0)
1968         duration = gst_util_uint64_scale (block_duration,
1969             parse->common.time_scale, 1);
1970       else
1971         duration =
1972             gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
1973             (gst_util_uint64_scale (block_duration, parse->common.time_scale,
1974                     1)) * stream->timecodescale);
1975     } else if (stream->default_duration) {
1976       duration = stream->default_duration * laces;
1977     }
1978     /* else duration is diff between timecode of this and next block */
1979
1980     /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
1981        a ReferenceBlock implies that this is not a keyframe. In either
1982        case, it only makes sense for video streams. */
1983     delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1984         ((is_simpleblock && !(flags & 0x80)) || referenceblock);
1985
1986     if (delta_unit && stream->set_discont) {
1987       /* When doing seeks or such, we need to restart on key frames or
1988        * decoders might choke. */
1989       GST_DEBUG_OBJECT (parse, "skipping delta unit");
1990       goto done;
1991     }
1992
1993     for (n = 0; n < laces; n++) {
1994       if (G_UNLIKELY (lace_size[n] > size)) {
1995         GST_WARNING_OBJECT (parse, "Invalid lace size");
1996         break;
1997       }
1998
1999       /* QoS for video track with an index. the assumption is that
2000          index entries point to keyframes, but if that is not true we
2001          will instad skip until the next keyframe. */
2002       if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
2003           stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
2004           stream->index_table && parse->common.segment.rate > 0.0) {
2005         GstMatroskaTrackVideoContext *videocontext =
2006             (GstMatroskaTrackVideoContext *) stream;
2007         GstClockTime earliest_time;
2008         GstClockTime earliest_stream_time;
2009
2010         GST_OBJECT_LOCK (parse);
2011         earliest_time = videocontext->earliest_time;
2012         GST_OBJECT_UNLOCK (parse);
2013         earliest_stream_time = gst_segment_to_position (&parse->common.segment,
2014             GST_FORMAT_TIME, earliest_time);
2015
2016         if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
2017             GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
2018             lace_time <= earliest_stream_time) {
2019           /* find index entry (keyframe) <= earliest_stream_time */
2020           GstMatroskaIndex *entry =
2021               gst_util_array_binary_search (stream->index_table->data,
2022               stream->index_table->len, sizeof (GstMatroskaIndex),
2023               (GCompareDataFunc) gst_matroska_index_seek_find,
2024               GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
2025
2026           /* if that entry (keyframe) is after the current the current
2027              buffer, we can skip pushing (and thus decoding) all
2028              buffers until that keyframe. */
2029           if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
2030               entry->time > lace_time) {
2031             GST_LOG_OBJECT (parse, "Skipping lace before late keyframe");
2032             stream->set_discont = TRUE;
2033             goto next_lace;
2034           }
2035         }
2036       }
2037 #if 0
2038       sub = gst_buffer_create_sub (buf,
2039           GST_BUFFER_SIZE (buf) - size, lace_size[n]);
2040       GST_DEBUG_OBJECT (parse, "created subbuffer %p", sub);
2041
2042       if (delta_unit)
2043         GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
2044       else
2045         GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
2046
2047       if (stream->encodings != NULL && stream->encodings->len > 0)
2048         sub = gst_matroska_decode_buffer (stream, sub);
2049
2050       if (sub == NULL) {
2051         GST_WARNING_OBJECT (parse, "Decoding buffer failed");
2052         goto next_lace;
2053       }
2054
2055       GST_BUFFER_TIMESTAMP (sub) = lace_time;
2056
2057       if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
2058         GstClockTime last_stop_end;
2059
2060         /* Check if this stream is after segment stop */
2061         if (GST_CLOCK_TIME_IS_VALID (parse->common.segment.stop) &&
2062             lace_time >= parse->common.segment.stop) {
2063           GST_DEBUG_OBJECT (parse,
2064               "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
2065               GST_TIME_ARGS (parse->common.segment.stop));
2066           gst_buffer_unref (sub);
2067           goto eos;
2068         }
2069         if (offset >= stream->to_offset) {
2070           GST_DEBUG_OBJECT (parse, "Stream %d after playback section",
2071               stream->index);
2072           gst_buffer_unref (sub);
2073           goto eos;
2074         }
2075
2076         /* handle gaps, e.g. non-zero start-time, or an cue index entry
2077          * that landed us with timestamps not quite intended */
2078         if (GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop) &&
2079             parse->segment.rate > 0.0) {
2080           GstClockTimeDiff diff;
2081
2082           /* only send newsegments with increasing start times,
2083            * otherwise if these go back and forth downstream (sinks) increase
2084            * accumulated time and running_time */
2085           diff = GST_CLOCK_DIFF (parse->segment.last_stop, lace_time);
2086           if (diff > 2 * GST_SECOND && lace_time > parse->segment.start &&
2087               (!GST_CLOCK_TIME_IS_VALID (parse->segment.stop) ||
2088                   lace_time < parse->segment.stop)) {
2089             GST_DEBUG_OBJECT (parse,
2090                 "Gap of %" G_GINT64_FORMAT " ns detected in"
2091                 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
2092                 "Sending updated NEWSEGMENT events", diff,
2093                 stream->index, GST_TIME_ARGS (stream->pos),
2094                 GST_TIME_ARGS (lace_time));
2095             /* send newsegment events such that the gap is not accounted in
2096              * accum time, hence running_time */
2097             /* close ahead of gap */
2098             gst_matroska_parse_send_event (parse,
2099                 gst_event_new_new_segment (TRUE, parse->segment.rate,
2100                     parse->segment.format, parse->segment.last_stop,
2101                     parse->segment.last_stop, parse->segment.last_stop));
2102             /* skip gap */
2103             gst_matroska_parse_send_event (parse,
2104                 gst_event_new_new_segment (FALSE, parse->segment.rate,
2105                     parse->segment.format, lace_time, parse->segment.stop,
2106                     lace_time));
2107             /* align segment view with downstream,
2108              * prevents double-counting accum when closing segment */
2109             gst_segment_set_newsegment (&parse->segment, FALSE,
2110                 parse->segment.rate, parse->segment.format, lace_time,
2111                 parse->segment.stop, lace_time);
2112             parse->segment.last_stop = lace_time;
2113           }
2114         }
2115
2116         if (!GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop)
2117             || parse->segment.last_stop < lace_time) {
2118           parse->segment.last_stop = lace_time;
2119         }
2120
2121         last_stop_end = lace_time;
2122         if (duration) {
2123           GST_BUFFER_DURATION (sub) = duration / laces;
2124           last_stop_end += GST_BUFFER_DURATION (sub);
2125         }
2126
2127         if (!GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) ||
2128             parse->last_stop_end < last_stop_end)
2129           parse->last_stop_end = last_stop_end;
2130
2131         if (parse->segment.duration == -1 ||
2132             parse->segment.duration < lace_time) {
2133           gst_segment_set_duration (&parse->segment, GST_FORMAT_TIME,
2134               last_stop_end);
2135           gst_element_post_message (GST_ELEMENT_CAST (parse),
2136               gst_message_new_duration (GST_OBJECT_CAST (parse),
2137                   GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
2138         }
2139       }
2140
2141       stream->pos = lace_time;
2142
2143       gst_matroska_parse_sync_streams (parse);
2144
2145       if (stream->set_discont) {
2146         GST_DEBUG_OBJECT (parse, "marking DISCONT");
2147         GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
2148         stream->set_discont = FALSE;
2149       }
2150
2151       /* reverse playback book-keeping */
2152       if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
2153         stream->from_time = lace_time;
2154       if (stream->from_offset == -1)
2155         stream->from_offset = offset;
2156
2157       GST_DEBUG_OBJECT (parse,
2158           "Pushing lace %d, data of size %d for stream %d, time=%"
2159           GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
2160           GST_BUFFER_SIZE (sub), stream_num,
2161           GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
2162           GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
2163
2164       if (parse->element_index) {
2165         if (stream->index_writer_id == -1)
2166           gst_index_get_writer_id (parse->element_index,
2167               GST_OBJECT (stream->pad), &stream->index_writer_id);
2168
2169         GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
2170             G_GUINT64_FORMAT " for writer id %d",
2171             GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
2172             stream->index_writer_id);
2173         gst_index_add_association (parse->element_index,
2174             stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
2175                 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
2176             GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
2177             cluster_offset, NULL);
2178       }
2179
2180       gst_buffer_set_caps (sub, GST_PAD_CAPS (parse->srcpad));
2181
2182       /* Postprocess the buffers depending on the codec used */
2183       if (stream->postprocess_frame) {
2184         GST_LOG_OBJECT (parse, "running post process");
2185         ret = stream->postprocess_frame (GST_ELEMENT (parse), stream, &sub);
2186       }
2187
2188       ret = gst_pad_push (stream->pad, sub);
2189       if (parse->segment.rate < 0) {
2190         if (lace_time > parse->segment.stop && ret == GST_FLOW_UNEXPECTED) {
2191           /* In reverse playback we can get a GST_FLOW_UNEXPECTED when
2192            * we are at the end of the segment, so we just need to jump
2193            * back to the previous section. */
2194           GST_DEBUG_OBJECT (parse, "downstream has reached end of segment");
2195           ret = GST_FLOW_OK;
2196         }
2197       }
2198       /* combine flows */
2199       ret = gst_matroska_parse_combine_flows (parse, stream, ret);
2200 #endif
2201
2202     next_lace:
2203       size -= lace_size[n];
2204       if (lace_time != GST_CLOCK_TIME_NONE && duration)
2205         lace_time += duration / laces;
2206       else
2207         lace_time = GST_CLOCK_TIME_NONE;
2208     }
2209   }
2210
2211 done:
2212   if (buf)
2213     gst_buffer_unref (buf);
2214   g_free (lace_size);
2215
2216   return ret;
2217
2218   /* EXITS */
2219 invalid_lacing:
2220   {
2221     GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
2222     /* non-fatal, try next block(group) */
2223     ret = GST_FLOW_OK;
2224     goto done;
2225   }
2226 data_error:
2227   {
2228     GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Data error"));
2229     /* non-fatal, try next block(group) */
2230     ret = GST_FLOW_OK;
2231     goto done;
2232   }
2233 }
2234
2235 /* return FALSE if block(group) should be skipped (due to a seek) */
2236 static inline gboolean
2237 gst_matroska_parse_seek_block (GstMatroskaParse * parse)
2238 {
2239   if (G_UNLIKELY (parse->seek_block)) {
2240     if (!(--parse->seek_block)) {
2241       return TRUE;
2242     } else {
2243       GST_LOG_OBJECT (parse, "should skip block due to seek");
2244       return FALSE;
2245     }
2246   } else {
2247     return TRUE;
2248   }
2249 }
2250
2251 static GstFlowReturn
2252 gst_matroska_parse_parse_contents_seekentry (GstMatroskaParse * parse,
2253     GstEbmlRead * ebml)
2254 {
2255   GstFlowReturn ret;
2256   guint64 seek_pos = (guint64) - 1;
2257   guint32 seek_id = 0;
2258   guint32 id;
2259
2260   DEBUG_ELEMENT_START (parse, ebml, "Seek");
2261
2262   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2263     DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2264     return ret;
2265   }
2266
2267   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2268     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2269       break;
2270
2271     switch (id) {
2272       case GST_MATROSKA_ID_SEEKID:
2273       {
2274         guint64 t;
2275
2276         if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2277           break;
2278
2279         GST_DEBUG_OBJECT (parse, "SeekID: %" G_GUINT64_FORMAT, t);
2280         seek_id = t;
2281         break;
2282       }
2283
2284       case GST_MATROSKA_ID_SEEKPOSITION:
2285       {
2286         guint64 t;
2287
2288         if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2289           break;
2290
2291         if (t > G_MAXINT64) {
2292           GST_WARNING_OBJECT (parse,
2293               "Too large SeekPosition %" G_GUINT64_FORMAT, t);
2294           break;
2295         }
2296
2297         GST_DEBUG_OBJECT (parse, "SeekPosition: %" G_GUINT64_FORMAT, t);
2298         seek_pos = t;
2299         break;
2300       }
2301
2302       default:
2303         ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2304             "SeekHead", id);
2305         break;
2306     }
2307   }
2308
2309   if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
2310     return ret;
2311
2312   if (!seek_id || seek_pos == (guint64) - 1) {
2313     GST_WARNING_OBJECT (parse, "Incomplete seekhead entry (0x%x/%"
2314         G_GUINT64_FORMAT ")", seek_id, seek_pos);
2315     return GST_FLOW_OK;
2316   }
2317
2318   switch (seek_id) {
2319     case GST_MATROSKA_ID_SEEKHEAD:
2320     {
2321     }
2322     case GST_MATROSKA_ID_CUES:
2323     case GST_MATROSKA_ID_TAGS:
2324     case GST_MATROSKA_ID_TRACKS:
2325     case GST_MATROSKA_ID_SEGMENTINFO:
2326     case GST_MATROSKA_ID_ATTACHMENTS:
2327     case GST_MATROSKA_ID_CHAPTERS:
2328     {
2329       guint64 length;
2330
2331       /* remember */
2332       length = gst_matroska_read_common_get_length (&parse->common);
2333
2334       if (length == (guint64) - 1) {
2335         GST_DEBUG_OBJECT (parse, "no upstream length, skipping SeakHead entry");
2336         break;
2337       }
2338
2339       /* check for validity */
2340       if (seek_pos + parse->common.ebml_segment_start + 12 >= length) {
2341         GST_WARNING_OBJECT (parse,
2342             "SeekHead reference lies outside file!" " (%"
2343             G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
2344             G_GUINT64_FORMAT ")", seek_pos, parse->common.ebml_segment_start,
2345             length);
2346         break;
2347       }
2348
2349       /* only pick up index location when streaming */
2350       if (seek_id == GST_MATROSKA_ID_CUES) {
2351         parse->index_offset = seek_pos + parse->common.ebml_segment_start;
2352         GST_DEBUG_OBJECT (parse, "Cues located at offset %" G_GUINT64_FORMAT,
2353             parse->index_offset);
2354       }
2355       break;
2356     }
2357
2358     default:
2359       GST_DEBUG_OBJECT (parse, "Ignoring Seek entry for ID=0x%x", seek_id);
2360       break;
2361   }
2362   DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2363
2364   return ret;
2365 }
2366
2367 static GstFlowReturn
2368 gst_matroska_parse_parse_contents (GstMatroskaParse * parse, GstEbmlRead * ebml)
2369 {
2370   GstFlowReturn ret = GST_FLOW_OK;
2371   guint32 id;
2372
2373   DEBUG_ELEMENT_START (parse, ebml, "SeekHead");
2374
2375   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2376     DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2377     return ret;
2378   }
2379
2380   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2381     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2382       break;
2383
2384     switch (id) {
2385       case GST_MATROSKA_ID_SEEKENTRY:
2386       {
2387         ret = gst_matroska_parse_parse_contents_seekentry (parse, ebml);
2388         /* Ignore EOS and errors here */
2389         if (ret != GST_FLOW_OK) {
2390           GST_DEBUG_OBJECT (parse, "Ignoring %s", gst_flow_get_name (ret));
2391           ret = GST_FLOW_OK;
2392         }
2393         break;
2394       }
2395
2396       default:
2397         ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2398             "SeekHead", id);
2399         break;
2400     }
2401   }
2402
2403   DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2404
2405   return ret;
2406 }
2407
2408 #define GST_FLOW_OVERFLOW   GST_FLOW_CUSTOM_ERROR
2409
2410 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
2411
2412 static inline GstFlowReturn
2413 gst_matroska_parse_check_read_size (GstMatroskaParse * parse, guint64 bytes)
2414 {
2415   if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
2416     /* only a few blocks are expected/allowed to be large,
2417      * and will be recursed into, whereas others will be read and must fit */
2418     /* fatal in streaming case, as we can't step over easily */
2419     GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2420         ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
2421             "file might be corrupt.", bytes));
2422     return GST_FLOW_ERROR;
2423   } else {
2424     return GST_FLOW_OK;
2425   }
2426 }
2427
2428 /* returns TRUE if we truely are in error state, and should give up */
2429 static inline gboolean
2430 gst_matroska_parse_check_parse_error (GstMatroskaParse * parse)
2431 {
2432   gint64 pos;
2433
2434   /* sigh, one last attempt above and beyond call of duty ...;
2435    * search for cluster mark following current pos */
2436   pos = parse->common.offset;
2437   GST_WARNING_OBJECT (parse, "parse error, looking for next cluster");
2438   if (gst_matroska_parse_search_cluster (parse, &pos) != GST_FLOW_OK) {
2439     /* did not work, give up */
2440     return TRUE;
2441   } else {
2442     GST_DEBUG_OBJECT (parse, "... found at  %" G_GUINT64_FORMAT, pos);
2443     /* try that position */
2444     parse->common.offset = pos;
2445     return FALSE;
2446   }
2447 }
2448
2449 /* initializes @ebml with @bytes from input stream at current offset.
2450  * Returns UNEXPECTED if insufficient available,
2451  * ERROR if too much was attempted to read. */
2452 static inline GstFlowReturn
2453 gst_matroska_parse_take (GstMatroskaParse * parse, guint64 bytes,
2454     GstEbmlRead * ebml)
2455 {
2456   GstBuffer *buffer = NULL;
2457   GstFlowReturn ret = GST_FLOW_OK;
2458
2459   GST_LOG_OBJECT (parse, "taking %" G_GUINT64_FORMAT " bytes for parsing",
2460       bytes);
2461   ret = gst_matroska_parse_check_read_size (parse, bytes);
2462   if (G_UNLIKELY (ret != GST_FLOW_OK)) {
2463     /* otherwise fatal */
2464     ret = GST_FLOW_ERROR;
2465     goto exit;
2466   }
2467   if (gst_adapter_available (parse->common.adapter) >= bytes)
2468     buffer = gst_adapter_take_buffer (parse->common.adapter, bytes);
2469   else
2470     ret = GST_FLOW_UNEXPECTED;
2471   if (G_LIKELY (buffer)) {
2472     gst_ebml_read_init (ebml, GST_ELEMENT_CAST (parse), buffer,
2473         parse->common.offset);
2474     parse->common.offset += bytes;
2475   }
2476 exit:
2477   return ret;
2478 }
2479
2480 static void
2481 gst_matroska_parse_check_seekability (GstMatroskaParse * parse)
2482 {
2483   GstQuery *query;
2484   gboolean seekable = FALSE;
2485   gint64 start = -1, stop = -1;
2486
2487   query = gst_query_new_seeking (GST_FORMAT_BYTES);
2488   if (!gst_pad_peer_query (parse->common.sinkpad, query)) {
2489     GST_DEBUG_OBJECT (parse, "seeking query failed");
2490     goto done;
2491   }
2492
2493   gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
2494
2495   /* try harder to query upstream size if we didn't get it the first time */
2496   if (seekable && stop == -1) {
2497     GstFormat fmt = GST_FORMAT_BYTES;
2498
2499     GST_DEBUG_OBJECT (parse, "doing duration query to fix up unset stop");
2500     gst_pad_query_peer_duration (parse->common.sinkpad, &fmt, &stop);
2501   }
2502
2503   /* if upstream doesn't know the size, it's likely that it's not seekable in
2504    * practice even if it technically may be seekable */
2505   if (seekable && (start != 0 || stop <= start)) {
2506     GST_DEBUG_OBJECT (parse, "seekable but unknown start/stop -> disable");
2507     seekable = FALSE;
2508   }
2509
2510 done:
2511   GST_INFO_OBJECT (parse, "seekable: %d (%" G_GUINT64_FORMAT " - %"
2512       G_GUINT64_FORMAT ")", seekable, start, stop);
2513   parse->seekable = seekable;
2514
2515   gst_query_unref (query);
2516 }
2517
2518 #if 0
2519 static GstFlowReturn
2520 gst_matroska_parse_find_tracks (GstMatroskaParse * parse)
2521 {
2522   guint32 id;
2523   guint64 before_pos;
2524   guint64 length;
2525   guint needed;
2526   GstFlowReturn ret = GST_FLOW_OK;
2527
2528   GST_WARNING_OBJECT (parse,
2529       "Found Cluster element before Tracks, searching Tracks");
2530
2531   /* remember */
2532   before_pos = parse->common.offset;
2533
2534   /* Search Tracks element */
2535   while (TRUE) {
2536     ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2537         GST_ELEMENT_CAST (parse), &id, &length, &needed);
2538     if (ret != GST_FLOW_OK)
2539       break;
2540
2541     if (id != GST_MATROSKA_ID_TRACKS) {
2542       /* we may be skipping large cluster here, so forego size check etc */
2543       /* ... but we can't skip undefined size; force error */
2544       if (length == G_MAXUINT64) {
2545         ret = gst_matroska_parse_check_read_size (parse, length);
2546         break;
2547       } else {
2548         parse->common.offset += needed;
2549         parse->offset += length;
2550       }
2551       continue;
2552     }
2553
2554     /* will lead to track parsing ... */
2555     ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2556     break;
2557   }
2558
2559   /* seek back */
2560   parse->offset = before_pos;
2561
2562   return ret;
2563 }
2564 #endif
2565
2566 #define GST_READ_CHECK(stmt)  \
2567 G_STMT_START { \
2568   if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
2569     if (ret == GST_FLOW_OVERFLOW) { \
2570       ret = GST_FLOW_OK; \
2571     } \
2572     goto read_error; \
2573   } \
2574 } G_STMT_END
2575
2576 static void