matroska: refactor code common to matroskademux and matroskaparse
[gstreamer-omap: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->common.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_chapters (GstMatroskaParse * parse, GstEbmlRead * ebml)
1562 {
1563   guint32 id;
1564   GstFlowReturn ret = GST_FLOW_OK;
1565
1566   GST_WARNING_OBJECT (parse, "Parsing of chapters not implemented yet");
1567
1568   /* TODO: implement parsing of chapters */
1569
1570   DEBUG_ELEMENT_START (parse, ebml, "Chapters");
1571
1572   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1573     DEBUG_ELEMENT_STOP (parse, ebml, "Chapters", ret);
1574     return ret;
1575   }
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       default:
1583         ret = gst_ebml_read_skip (ebml);
1584         break;
1585     }
1586   }
1587
1588   DEBUG_ELEMENT_STOP (parse, ebml, "Chapters", ret);
1589   return ret;
1590 }
1591
1592 /*
1593  * Read signed/unsigned "EBML" numbers.
1594  * Return: number of bytes processed.
1595  */
1596
1597 static gint
1598 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
1599 {
1600   gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
1601   guint64 total;
1602
1603   if (size <= 0) {
1604     return -1;
1605   }
1606
1607   total = data[0];
1608   while (read <= 8 && !(total & len_mask)) {
1609     read++;
1610     len_mask >>= 1;
1611   }
1612   if (read > 8)
1613     return -1;
1614
1615   if ((total &= (len_mask - 1)) == len_mask - 1)
1616     num_ffs++;
1617   if (size < read)
1618     return -1;
1619   while (n < read) {
1620     if (data[n] == 0xff)
1621       num_ffs++;
1622     total = (total << 8) | data[n];
1623     n++;
1624   }
1625
1626   if (read == num_ffs && total != 0)
1627     *num = G_MAXUINT64;
1628   else
1629     *num = total;
1630
1631   return read;
1632 }
1633
1634 static gint
1635 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
1636 {
1637   guint64 unum;
1638   gint res;
1639
1640   /* read as unsigned number first */
1641   if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
1642     return -1;
1643
1644   /* make signed */
1645   if (unum == G_MAXUINT64)
1646     *num = G_MAXINT64;
1647   else
1648     *num = unum - ((1 << ((7 * res) - 1)) - 1);
1649
1650   return res;
1651 }
1652
1653 static GstFlowReturn
1654 gst_matroska_parse_parse_blockgroup_or_simpleblock (GstMatroskaParse * parse,
1655     GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
1656     gboolean is_simpleblock)
1657 {
1658   GstMatroskaTrackContext *stream = NULL;
1659   GstFlowReturn ret = GST_FLOW_OK;
1660   gboolean readblock = FALSE;
1661   guint32 id;
1662   guint64 block_duration = 0;
1663   GstBuffer *buf = NULL;
1664   gint stream_num = -1, n, laces = 0;
1665   guint size = 0;
1666   gint *lace_size = NULL;
1667   gint64 time = 0;
1668   gint flags = 0;
1669   gint64 referenceblock = 0;
1670
1671   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1672     if (!is_simpleblock) {
1673       if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
1674         goto data_error;
1675       }
1676     } else {
1677       id = GST_MATROSKA_ID_SIMPLEBLOCK;
1678     }
1679
1680     switch (id) {
1681         /* one block inside the group. Note, block parsing is one
1682          * of the harder things, so this code is a bit complicated.
1683          * See http://www.matroska.org/ for documentation. */
1684       case GST_MATROSKA_ID_SIMPLEBLOCK:
1685       case GST_MATROSKA_ID_BLOCK:
1686       {
1687         guint64 num;
1688         guint8 *data;
1689
1690         if (buf) {
1691           gst_buffer_unref (buf);
1692           buf = NULL;
1693         }
1694         if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
1695           break;
1696
1697         data = GST_BUFFER_DATA (buf);
1698         size = GST_BUFFER_SIZE (buf);
1699
1700         /* first byte(s): blocknum */
1701         if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1702           goto data_error;
1703         data += n;
1704         size -= n;
1705
1706         /* fetch stream from num */
1707         stream_num = gst_matroska_read_common_stream_from_num (&parse->common,
1708             num);
1709         if (G_UNLIKELY (size < 3)) {
1710           GST_WARNING_OBJECT (parse, "Invalid size %u", size);
1711           /* non-fatal, try next block(group) */
1712           ret = GST_FLOW_OK;
1713           goto done;
1714         } else if (G_UNLIKELY (stream_num < 0 ||
1715                 stream_num >= parse->common.num_streams)) {
1716           /* let's not give up on a stray invalid track number */
1717           GST_WARNING_OBJECT (parse,
1718               "Invalid stream %d for track number %" G_GUINT64_FORMAT
1719               "; ignoring block", stream_num, num);
1720           goto done;
1721         }
1722
1723         stream = g_ptr_array_index (parse->common.src, stream_num);
1724
1725         /* time (relative to cluster time) */
1726         time = ((gint16) GST_READ_UINT16_BE (data));
1727         data += 2;
1728         size -= 2;
1729         flags = GST_READ_UINT8 (data);
1730         data += 1;
1731         size -= 1;
1732
1733         GST_LOG_OBJECT (parse, "time %" G_GUINT64_FORMAT ", flags %d", time,
1734             flags);
1735
1736         switch ((flags & 0x06) >> 1) {
1737           case 0x0:            /* no lacing */
1738             laces = 1;
1739             lace_size = g_new (gint, 1);
1740             lace_size[0] = size;
1741             break;
1742
1743           case 0x1:            /* xiph lacing */
1744           case 0x2:            /* fixed-size lacing */
1745           case 0x3:            /* EBML lacing */
1746             if (size == 0)
1747               goto invalid_lacing;
1748             laces = GST_READ_UINT8 (data) + 1;
1749             data += 1;
1750             size -= 1;
1751             lace_size = g_new0 (gint, laces);
1752
1753             switch ((flags & 0x06) >> 1) {
1754               case 0x1:        /* xiph lacing */  {
1755                 guint temp, total = 0;
1756
1757                 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
1758                   while (1) {
1759                     if (size == 0)
1760                       goto invalid_lacing;
1761                     temp = GST_READ_UINT8 (data);
1762                     lace_size[n] += temp;
1763                     data += 1;
1764                     size -= 1;
1765                     if (temp != 0xff)
1766                       break;
1767                   }
1768                   total += lace_size[n];
1769                 }
1770                 lace_size[n] = size - total;
1771                 break;
1772               }
1773
1774               case 0x2:        /* fixed-size lacing */
1775                 for (n = 0; n < laces; n++)
1776                   lace_size[n] = size / laces;
1777                 break;
1778
1779               case 0x3:        /* EBML lacing */  {
1780                 guint total;
1781
1782                 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1783                   goto data_error;
1784                 data += n;
1785                 size -= n;
1786                 total = lace_size[0] = num;
1787                 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
1788                   gint64 snum;
1789                   gint r;
1790
1791                   if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
1792                     goto data_error;
1793                   data += r;
1794                   size -= r;
1795                   lace_size[n] = lace_size[n - 1] + snum;
1796                   total += lace_size[n];
1797                 }
1798                 if (n < laces)
1799                   lace_size[n] = size - total;
1800                 break;
1801               }
1802             }
1803             break;
1804         }
1805
1806         if (ret != GST_FLOW_OK)
1807           break;
1808
1809         readblock = TRUE;
1810         break;
1811       }
1812
1813       case GST_MATROSKA_ID_BLOCKDURATION:{
1814         ret = gst_ebml_read_uint (ebml, &id, &block_duration);
1815         GST_DEBUG_OBJECT (parse, "BlockDuration: %" G_GUINT64_FORMAT,
1816             block_duration);
1817         break;
1818       }
1819
1820       case GST_MATROSKA_ID_REFERENCEBLOCK:{
1821         ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
1822         GST_DEBUG_OBJECT (parse, "ReferenceBlock: %" G_GINT64_FORMAT,
1823             referenceblock);
1824         break;
1825       }
1826
1827       case GST_MATROSKA_ID_CODECSTATE:{
1828         guint8 *data;
1829         guint64 data_len = 0;
1830
1831         if ((ret =
1832                 gst_ebml_read_binary (ebml, &id, &data,
1833                     &data_len)) != GST_FLOW_OK)
1834           break;
1835
1836         if (G_UNLIKELY (stream == NULL)) {
1837           GST_WARNING_OBJECT (parse,
1838               "Unexpected CodecState subelement - ignoring");
1839           break;
1840         }
1841
1842         g_free (stream->codec_state);
1843         stream->codec_state = data;
1844         stream->codec_state_size = data_len;
1845
1846         break;
1847       }
1848
1849       default:
1850         ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1851             "BlockGroup", id);
1852         break;
1853
1854       case GST_MATROSKA_ID_BLOCKVIRTUAL:
1855       case GST_MATROSKA_ID_BLOCKADDITIONS:
1856       case GST_MATROSKA_ID_REFERENCEPRIORITY:
1857       case GST_MATROSKA_ID_REFERENCEVIRTUAL:
1858       case GST_MATROSKA_ID_SLICES:
1859         GST_DEBUG_OBJECT (parse,
1860             "Skipping BlockGroup subelement 0x%x - ignoring", id);
1861         ret = gst_ebml_read_skip (ebml);
1862         break;
1863     }
1864
1865     if (is_simpleblock)
1866       break;
1867   }
1868
1869   /* reading a number or so could have failed */
1870   if (ret != GST_FLOW_OK)
1871     goto data_error;
1872
1873   if (ret == GST_FLOW_OK && readblock) {
1874     guint64 duration = 0;
1875     gint64 lace_time = 0;
1876     gboolean delta_unit;
1877
1878     stream = g_ptr_array_index (parse->common.src, stream_num);
1879
1880     if (cluster_time != GST_CLOCK_TIME_NONE) {
1881       /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
1882        * Drop unless the lace contains timestamp 0? */
1883       if (time < 0 && (-time) > cluster_time) {
1884         lace_time = 0;
1885       } else {
1886         if (stream->timecodescale == 1.0)
1887           lace_time = (cluster_time + time) * parse->common.time_scale;
1888         else
1889           lace_time =
1890               gst_util_guint64_to_gdouble ((cluster_time + time) *
1891               parse->common.time_scale) * stream->timecodescale;
1892       }
1893     } else {
1894       lace_time = GST_CLOCK_TIME_NONE;
1895     }
1896
1897     if (lace_time != GST_CLOCK_TIME_NONE) {
1898       parse->last_timestamp = lace_time;
1899     }
1900     /* need to refresh segment info ASAP */
1901     if (GST_CLOCK_TIME_IS_VALID (lace_time) && parse->need_newsegment) {
1902       GST_DEBUG_OBJECT (parse,
1903           "generating segment starting at %" GST_TIME_FORMAT,
1904           GST_TIME_ARGS (lace_time));
1905       /* pretend we seeked here */
1906       gst_segment_set_seek (&parse->common.segment, parse->common.segment.rate,
1907           GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, lace_time,
1908           GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE, NULL);
1909       /* now convey our segment notion downstream */
1910       gst_matroska_parse_send_event (parse, gst_event_new_new_segment (FALSE,
1911               parse->common.segment.rate, parse->common.segment.format,
1912               parse->common.segment.start, parse->common.segment.stop,
1913               parse->common.segment.start));
1914       parse->need_newsegment = FALSE;
1915     }
1916
1917     if (block_duration) {
1918       if (stream->timecodescale == 1.0)
1919         duration = gst_util_uint64_scale (block_duration,
1920             parse->common.time_scale, 1);
1921       else
1922         duration =
1923             gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
1924             (gst_util_uint64_scale (block_duration, parse->common.time_scale,
1925                     1)) * stream->timecodescale);
1926     } else if (stream->default_duration) {
1927       duration = stream->default_duration * laces;
1928     }
1929     /* else duration is diff between timecode of this and next block */
1930
1931     /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
1932        a ReferenceBlock implies that this is not a keyframe. In either
1933        case, it only makes sense for video streams. */
1934     delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1935         ((is_simpleblock && !(flags & 0x80)) || referenceblock);
1936
1937     if (delta_unit && stream->set_discont) {
1938       /* When doing seeks or such, we need to restart on key frames or
1939        * decoders might choke. */
1940       GST_DEBUG_OBJECT (parse, "skipping delta unit");
1941       goto done;
1942     }
1943
1944     for (n = 0; n < laces; n++) {
1945       if (G_UNLIKELY (lace_size[n] > size)) {
1946         GST_WARNING_OBJECT (parse, "Invalid lace size");
1947         break;
1948       }
1949
1950       /* QoS for video track with an index. the assumption is that
1951          index entries point to keyframes, but if that is not true we
1952          will instad skip until the next keyframe. */
1953       if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1954           stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1955           stream->index_table && parse->common.segment.rate > 0.0) {
1956         GstMatroskaTrackVideoContext *videocontext =
1957             (GstMatroskaTrackVideoContext *) stream;
1958         GstClockTime earliest_time;
1959         GstClockTime earliest_stream_time;
1960
1961         GST_OBJECT_LOCK (parse);
1962         earliest_time = videocontext->earliest_time;
1963         GST_OBJECT_UNLOCK (parse);
1964         earliest_stream_time = gst_segment_to_position (&parse->common.segment,
1965             GST_FORMAT_TIME, earliest_time);
1966
1967         if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1968             GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
1969             lace_time <= earliest_stream_time) {
1970           /* find index entry (keyframe) <= earliest_stream_time */
1971           GstMatroskaIndex *entry =
1972               gst_util_array_binary_search (stream->index_table->data,
1973               stream->index_table->len, sizeof (GstMatroskaIndex),
1974               (GCompareDataFunc) gst_matroska_index_seek_find,
1975               GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
1976
1977           /* if that entry (keyframe) is after the current the current
1978              buffer, we can skip pushing (and thus decoding) all
1979              buffers until that keyframe. */
1980           if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
1981               entry->time > lace_time) {
1982             GST_LOG_OBJECT (parse, "Skipping lace before late keyframe");
1983             stream->set_discont = TRUE;
1984             goto next_lace;
1985           }
1986         }
1987       }
1988 #if 0
1989       sub = gst_buffer_create_sub (buf,
1990           GST_BUFFER_SIZE (buf) - size, lace_size[n]);
1991       GST_DEBUG_OBJECT (parse, "created subbuffer %p", sub);
1992
1993       if (delta_unit)
1994         GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1995       else
1996         GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1997
1998       if (stream->encodings != NULL && stream->encodings->len > 0)
1999         sub = gst_matroska_decode_buffer (stream, sub);
2000
2001       if (sub == NULL) {
2002         GST_WARNING_OBJECT (parse, "Decoding buffer failed");
2003         goto next_lace;
2004       }
2005
2006       GST_BUFFER_TIMESTAMP (sub) = lace_time;
2007
2008       if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
2009         GstClockTime last_stop_end;
2010
2011         /* Check if this stream is after segment stop */
2012         if (GST_CLOCK_TIME_IS_VALID (parse->common.segment.stop) &&
2013             lace_time >= parse->common.segment.stop) {
2014           GST_DEBUG_OBJECT (parse,
2015               "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
2016               GST_TIME_ARGS (parse->common.segment.stop));
2017           gst_buffer_unref (sub);
2018           goto eos;
2019         }
2020         if (offset >= stream->to_offset) {
2021           GST_DEBUG_OBJECT (parse, "Stream %d after playback section",
2022               stream->index);
2023           gst_buffer_unref (sub);
2024           goto eos;
2025         }
2026
2027         /* handle gaps, e.g. non-zero start-time, or an cue index entry
2028          * that landed us with timestamps not quite intended */
2029         if (GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop) &&
2030             parse->segment.rate > 0.0) {
2031           GstClockTimeDiff diff;
2032
2033           /* only send newsegments with increasing start times,
2034            * otherwise if these go back and forth downstream (sinks) increase
2035            * accumulated time and running_time */
2036           diff = GST_CLOCK_DIFF (parse->segment.last_stop, lace_time);
2037           if (diff > 2 * GST_SECOND && lace_time > parse->segment.start &&
2038               (!GST_CLOCK_TIME_IS_VALID (parse->segment.stop) ||
2039                   lace_time < parse->segment.stop)) {
2040             GST_DEBUG_OBJECT (parse,
2041                 "Gap of %" G_GINT64_FORMAT " ns detected in"
2042                 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
2043                 "Sending updated NEWSEGMENT events", diff,
2044                 stream->index, GST_TIME_ARGS (stream->pos),
2045                 GST_TIME_ARGS (lace_time));
2046             /* send newsegment events such that the gap is not accounted in
2047              * accum time, hence running_time */
2048             /* close ahead of gap */
2049             gst_matroska_parse_send_event (parse,
2050                 gst_event_new_new_segment (TRUE, parse->segment.rate,
2051                     parse->segment.format, parse->segment.last_stop,
2052                     parse->segment.last_stop, parse->segment.last_stop));
2053             /* skip gap */
2054             gst_matroska_parse_send_event (parse,
2055                 gst_event_new_new_segment (FALSE, parse->segment.rate,
2056                     parse->segment.format, lace_time, parse->segment.stop,
2057                     lace_time));
2058             /* align segment view with downstream,
2059              * prevents double-counting accum when closing segment */
2060             gst_segment_set_newsegment (&parse->segment, FALSE,
2061                 parse->segment.rate, parse->segment.format, lace_time,
2062                 parse->segment.stop, lace_time);
2063             parse->segment.last_stop = lace_time;
2064           }
2065         }
2066
2067         if (!GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop)
2068             || parse->segment.last_stop < lace_time) {
2069           parse->segment.last_stop = lace_time;
2070         }
2071
2072         last_stop_end = lace_time;
2073         if (duration) {
2074           GST_BUFFER_DURATION (sub) = duration / laces;
2075           last_stop_end += GST_BUFFER_DURATION (sub);
2076         }
2077
2078         if (!GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) ||
2079             parse->last_stop_end < last_stop_end)
2080           parse->last_stop_end = last_stop_end;
2081
2082         if (parse->segment.duration == -1 ||
2083             parse->segment.duration < lace_time) {
2084           gst_segment_set_duration (&parse->segment, GST_FORMAT_TIME,
2085               last_stop_end);
2086           gst_element_post_message (GST_ELEMENT_CAST (parse),
2087               gst_message_new_duration (GST_OBJECT_CAST (parse),
2088                   GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
2089         }
2090       }
2091
2092       stream->pos = lace_time;
2093
2094       gst_matroska_parse_sync_streams (parse);
2095
2096       if (stream->set_discont) {
2097         GST_DEBUG_OBJECT (parse, "marking DISCONT");
2098         GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
2099         stream->set_discont = FALSE;
2100       }
2101
2102       /* reverse playback book-keeping */
2103       if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
2104         stream->from_time = lace_time;
2105       if (stream->from_offset == -1)
2106         stream->from_offset = offset;
2107
2108       GST_DEBUG_OBJECT (parse,
2109           "Pushing lace %d, data of size %d for stream %d, time=%"
2110           GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
2111           GST_BUFFER_SIZE (sub), stream_num,
2112           GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
2113           GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
2114
2115       if (parse->element_index) {
2116         if (stream->index_writer_id == -1)
2117           gst_index_get_writer_id (parse->element_index,
2118               GST_OBJECT (stream->pad), &stream->index_writer_id);
2119
2120         GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
2121             G_GUINT64_FORMAT " for writer id %d",
2122             GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
2123             stream->index_writer_id);
2124         gst_index_add_association (parse->element_index,
2125             stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
2126                 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
2127             GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
2128             cluster_offset, NULL);
2129       }
2130
2131       gst_buffer_set_caps (sub, GST_PAD_CAPS (parse->srcpad));
2132
2133       /* Postprocess the buffers depending on the codec used */
2134       if (stream->postprocess_frame) {
2135         GST_LOG_OBJECT (parse, "running post process");
2136         ret = stream->postprocess_frame (GST_ELEMENT (parse), stream, &sub);
2137       }
2138
2139       ret = gst_pad_push (stream->pad, sub);
2140       if (parse->segment.rate < 0) {
2141         if (lace_time > parse->segment.stop && ret == GST_FLOW_UNEXPECTED) {
2142           /* In reverse playback we can get a GST_FLOW_UNEXPECTED when
2143            * we are at the end of the segment, so we just need to jump
2144            * back to the previous section. */
2145           GST_DEBUG_OBJECT (parse, "downstream has reached end of segment");
2146           ret = GST_FLOW_OK;
2147         }
2148       }
2149       /* combine flows */
2150       ret = gst_matroska_parse_combine_flows (parse, stream, ret);
2151 #endif
2152
2153     next_lace:
2154       size -= lace_size[n];
2155       if (lace_time != GST_CLOCK_TIME_NONE && duration)
2156         lace_time += duration / laces;
2157       else
2158         lace_time = GST_CLOCK_TIME_NONE;
2159     }
2160   }
2161
2162 done:
2163   if (buf)
2164     gst_buffer_unref (buf);
2165   g_free (lace_size);
2166
2167   return ret;
2168
2169   /* EXITS */
2170 invalid_lacing:
2171   {
2172     GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
2173     /* non-fatal, try next block(group) */
2174     ret = GST_FLOW_OK;
2175     goto done;
2176   }
2177 data_error:
2178   {
2179     GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Data error"));
2180     /* non-fatal, try next block(group) */
2181     ret = GST_FLOW_OK;
2182     goto done;
2183   }
2184 }
2185
2186 /* return FALSE if block(group) should be skipped (due to a seek) */
2187 static inline gboolean
2188 gst_matroska_parse_seek_block (GstMatroskaParse * parse)
2189 {
2190   if (G_UNLIKELY (parse->seek_block)) {
2191     if (!(--parse->seek_block)) {
2192       return TRUE;
2193     } else {
2194       GST_LOG_OBJECT (parse, "should skip block due to seek");
2195       return FALSE;
2196     }
2197   } else {
2198     return TRUE;
2199   }
2200 }
2201
2202 static GstFlowReturn
2203 gst_matroska_parse_parse_contents_seekentry (GstMatroskaParse * parse,
2204     GstEbmlRead * ebml)
2205 {
2206   GstFlowReturn ret;
2207   guint64 seek_pos = (guint64) - 1;
2208   guint32 seek_id = 0;
2209   guint32 id;
2210
2211   DEBUG_ELEMENT_START (parse, ebml, "Seek");
2212
2213   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2214     DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2215     return ret;
2216   }
2217
2218   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2219     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2220       break;
2221
2222     switch (id) {
2223       case GST_MATROSKA_ID_SEEKID:
2224       {
2225         guint64 t;
2226
2227         if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2228           break;
2229
2230         GST_DEBUG_OBJECT (parse, "SeekID: %" G_GUINT64_FORMAT, t);
2231         seek_id = t;
2232         break;
2233       }
2234
2235       case GST_MATROSKA_ID_SEEKPOSITION:
2236       {
2237         guint64 t;
2238
2239         if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2240           break;
2241
2242         if (t > G_MAXINT64) {
2243           GST_WARNING_OBJECT (parse,
2244               "Too large SeekPosition %" G_GUINT64_FORMAT, t);
2245           break;
2246         }
2247
2248         GST_DEBUG_OBJECT (parse, "SeekPosition: %" G_GUINT64_FORMAT, t);
2249         seek_pos = t;
2250         break;
2251       }
2252
2253       default:
2254         ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2255             "SeekHead", id);
2256         break;
2257     }
2258   }
2259
2260   if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
2261     return ret;
2262
2263   if (!seek_id || seek_pos == (guint64) - 1) {
2264     GST_WARNING_OBJECT (parse, "Incomplete seekhead entry (0x%x/%"
2265         G_GUINT64_FORMAT ")", seek_id, seek_pos);
2266     return GST_FLOW_OK;
2267   }
2268
2269   switch (seek_id) {
2270     case GST_MATROSKA_ID_SEEKHEAD:
2271     {
2272     }
2273     case GST_MATROSKA_ID_CUES:
2274     case GST_MATROSKA_ID_TAGS:
2275     case GST_MATROSKA_ID_TRACKS:
2276     case GST_MATROSKA_ID_SEGMENTINFO:
2277     case GST_MATROSKA_ID_ATTACHMENTS:
2278     case GST_MATROSKA_ID_CHAPTERS:
2279     {
2280       guint64 length;
2281
2282       /* remember */
2283       length = gst_matroska_read_common_get_length (&parse->common);
2284
2285       if (length == (guint64) - 1) {
2286         GST_DEBUG_OBJECT (parse, "no upstream length, skipping SeakHead entry");
2287         break;
2288       }
2289
2290       /* check for validity */
2291       if (seek_pos + parse->common.ebml_segment_start + 12 >= length) {
2292         GST_WARNING_OBJECT (parse,
2293             "SeekHead reference lies outside file!" " (%"
2294             G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
2295             G_GUINT64_FORMAT ")", seek_pos, parse->common.ebml_segment_start,
2296             length);
2297         break;
2298       }
2299
2300       /* only pick up index location when streaming */
2301       if (seek_id == GST_MATROSKA_ID_CUES) {
2302         parse->index_offset = seek_pos + parse->common.ebml_segment_start;
2303         GST_DEBUG_OBJECT (parse, "Cues located at offset %" G_GUINT64_FORMAT,
2304             parse->index_offset);
2305       }
2306       break;
2307     }
2308
2309     default:
2310       GST_DEBUG_OBJECT (parse, "Ignoring Seek entry for ID=0x%x", seek_id);
2311       break;
2312   }
2313   DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2314
2315   return ret;
2316 }
2317
2318 static GstFlowReturn
2319 gst_matroska_parse_parse_contents (GstMatroskaParse * parse, GstEbmlRead * ebml)
2320 {
2321   GstFlowReturn ret = GST_FLOW_OK;
2322   guint32 id;
2323
2324   DEBUG_ELEMENT_START (parse, ebml, "SeekHead");
2325
2326   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2327     DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2328     return ret;
2329   }
2330
2331   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2332     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2333       break;
2334
2335     switch (id) {
2336       case GST_MATROSKA_ID_SEEKENTRY:
2337       {
2338         ret = gst_matroska_parse_parse_contents_seekentry (parse, ebml);
2339         /* Ignore EOS and errors here */
2340         if (ret != GST_FLOW_OK) {
2341           GST_DEBUG_OBJECT (parse, "Ignoring %s", gst_flow_get_name (ret));
2342           ret = GST_FLOW_OK;
2343         }
2344         break;
2345       }
2346
2347       default:
2348         ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2349             "SeekHead", id);
2350         break;
2351     }
2352   }
2353
2354   DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2355
2356   return ret;
2357 }
2358
2359 #define GST_FLOW_OVERFLOW   GST_FLOW_CUSTOM_ERROR
2360
2361 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
2362
2363 static inline GstFlowReturn
2364 gst_matroska_parse_check_read_size (GstMatroskaParse * parse, guint64 bytes)
2365 {
2366   if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
2367     /* only a few blocks are expected/allowed to be large,
2368      * and will be recursed into, whereas others will be read and must fit */
2369     /* fatal in streaming case, as we can't step over easily */
2370     GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2371         ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
2372             "file might be corrupt.", bytes));
2373     return GST_FLOW_ERROR;
2374   } else {
2375     return GST_FLOW_OK;
2376   }
2377 }
2378
2379 /* returns TRUE if we truely are in error state, and should give up */
2380 static inline gboolean
2381 gst_matroska_parse_check_parse_error (GstMatroskaParse * parse)
2382 {
2383   gint64 pos;
2384
2385   /* sigh, one last attempt above and beyond call of duty ...;
2386    * search for cluster mark following current pos */
2387   pos = parse->common.offset;
2388   GST_WARNING_OBJECT (parse, "parse error, looking for next cluster");
2389   if (gst_matroska_parse_search_cluster (parse, &pos) != GST_FLOW_OK) {
2390     /* did not work, give up */
2391     return TRUE;
2392   } else {
2393     GST_DEBUG_OBJECT (parse, "... found at  %" G_GUINT64_FORMAT, pos);
2394     /* try that position */
2395     parse->common.offset = pos;
2396     return FALSE;
2397   }
2398 }
2399
2400 /* initializes @ebml with @bytes from input stream at current offset.
2401  * Returns UNEXPECTED if insufficient available,
2402  * ERROR if too much was attempted to read. */
2403 static inline GstFlowReturn
2404 gst_matroska_parse_take (GstMatroskaParse * parse, guint64 bytes,
2405     GstEbmlRead * ebml)
2406 {
2407   GstBuffer *buffer = NULL;
2408   GstFlowReturn ret = GST_FLOW_OK;
2409
2410   GST_LOG_OBJECT (parse, "taking %" G_GUINT64_FORMAT " bytes for parsing",
2411       bytes);
2412   ret = gst_matroska_parse_check_read_size (parse, bytes);
2413   if (G_UNLIKELY (ret != GST_FLOW_OK)) {
2414     /* otherwise fatal */
2415     ret = GST_FLOW_ERROR;
2416     goto exit;
2417   }
2418   if (gst_adapter_available (parse->common.adapter) >= bytes)
2419     buffer = gst_adapter_take_buffer (parse->common.adapter, bytes);
2420   else
2421     ret = GST_FLOW_UNEXPECTED;
2422   if (G_LIKELY (buffer)) {
2423     gst_ebml_read_init (ebml, GST_ELEMENT_CAST (parse), buffer,
2424         parse->common.offset);
2425     parse->common.offset += bytes;
2426   }
2427 exit:
2428   return ret;
2429 }
2430
2431 static void
2432 gst_matroska_parse_check_seekability (GstMatroskaParse * parse)
2433 {
2434   GstQuery *query;
2435   gboolean seekable = FALSE;
2436   gint64 start = -1, stop = -1;
2437
2438   query = gst_query_new_seeking (GST_FORMAT_BYTES);
2439   if (!gst_pad_peer_query (parse->common.sinkpad, query)) {
2440     GST_DEBUG_OBJECT (parse, "seeking query failed");
2441     goto done;
2442   }
2443
2444   gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
2445
2446   /* try harder to query upstream size if we didn't get it the first time */
2447   if (seekable && stop == -1) {
2448     GstFormat fmt = GST_FORMAT_BYTES;
2449
2450     GST_DEBUG_OBJECT (parse, "doing duration query to fix up unset stop");
2451     gst_pad_query_peer_duration (parse->common.sinkpad, &fmt, &stop);
2452   }
2453
2454   /* if upstream doesn't know the size, it's likely that it's not seekable in
2455    * practice even if it technically may be seekable */
2456   if (seekable && (start != 0 || stop <= start)) {
2457     GST_DEBUG_OBJECT (parse, "seekable but unknown start/stop -> disable");
2458     seekable = FALSE;
2459   }
2460
2461 done:
2462   GST_INFO_OBJECT (parse, "seekable: %d (%" G_GUINT64_FORMAT " - %"
2463       G_GUINT64_FORMAT ")", seekable, start, stop);
2464   parse->seekable = seekable;
2465
2466   gst_query_unref (query);
2467 }
2468
2469 #if 0
2470 static GstFlowReturn
2471 gst_matroska_parse_find_tracks (GstMatroskaParse * parse)
2472 {
2473   guint32 id;
2474   guint64 before_pos;
2475   guint64 length;
2476   guint needed;
2477   GstFlowReturn ret = GST_FLOW_OK;
2478
2479   GST_WARNING_OBJECT (parse,
2480       "Found Cluster element before Tracks, searching Tracks");
2481
2482   /* remember */
2483   before_pos = parse->common.offset;
2484
2485   /* Search Tracks element */
2486   while (TRUE) {
2487     ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2488         GST_ELEMENT_CAST (parse), &id, &length, &needed);
2489     if (ret != GST_FLOW_OK)
2490       break;
2491
2492     if (id != GST_MATROSKA_ID_TRACKS) {
2493       /* we may be skipping large cluster here, so forego size check etc */
2494       /* ... but we can't skip undefined size; force error */
2495       if (length == G_MAXUINT64) {
2496         ret = gst_matroska_parse_check_read_size (parse, length);
2497         break;
2498       } else {
2499         parse->common.offset += needed;
2500         parse->offset += length;
2501       }
2502       continue;
2503     }
2504
2505     /* will lead to track parsing ... */
2506     ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2507     break;
2508   }
2509
2510   /* seek back */
2511   parse->offset = before_pos;
2512
2513   return ret;
2514 }
2515 #endif
2516
2517 #define GST_READ_CHECK(stmt)  \
2518 G_STMT_START { \
2519   if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
2520     if (ret == GST_FLOW_OVERFLOW) { \
2521       ret = GST_FLOW_OK; \
2522     } \
2523     goto read_error; \
2524   } \
2525 } G_STMT_END
2526
2527 static void
2528 gst_matroska_parse_accumulate_streamheader (GstMatroskaParse * parse,
2529     GstBuffer * buffer)
2530 {
2531   if (parse->streamheader) {
2532     GstBuffer *buf;
2533
2534     buf = gst_buffer_span (parse->streamheader, 0, buffer,
2535         GST_BUFFER_SIZE (parse->streamheader) + GST_BUFFER_SIZE (buffer));
2536     gst_buffer_unref (parse->streamheader);
2537     parse->streamheader = buf;
2538   } else {
2539     parse->streamheader = gst_buffer_ref (buffer);
2540   }
2541
2542   GST_DEBUG ("%d", GST_BUFFER_SIZE (parse->streamheader));
2543 }
2544
2545 static GstFlowReturn
2546 gst_matroska_parse_output (GstMatroskaParse * parse, GstBuffer * buffer,
2547     gboolean keyframe)
2548 {
2549   GstFlowReturn ret = GST_FLOW_OK;
2550
2551   if (!parse->pushed_headers) {
2552     GstCaps *caps;
2553     GstStructure *s;
2554     GValue streamheader = { 0 };
2555     GValue bufval = { 0 };
2556     GstBuffer *buf;
2557
2558     caps = gst_caps_new_simple ("video/x-matroska", NULL);
2559     s = gst_caps_get_structure (caps, 0);
2560     g_value_init (&streamheader, GST_TYPE_ARRAY);
2561     g_value_init (&bufval, GST_TYPE_BUFFER);
2562     GST_BUFFER_FLAG_SET (parse->streamheader, GST_BUFFER_FLAG_IN_CAPS);
2563     gst_value_set_buffer (&bufval, parse->streamheader);
2564     gst_value_array_append_value (&streamheader, &bufval);
2565     g_value_unset (&bufval);
2566     gst_structure_set_value (s, "streamheader", &streamheader);
2567     g_value_unset (&streamheader);
2568     //gst_caps_replace (parse->caps, caps);
2569     gst_pad_set_caps (parse->srcpad, caps);
2570
2571     buf = gst_buffer_make_metadata_writable (parse->streamheader);
2572     gst_buffer_set_caps (buf, caps);
2573     gst_caps_unref (caps);
2574
2575     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2576     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
2577     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
2578
2579     ret = gst_pad_push (parse->srcpad, buf);
2580
2581     parse->pushed_headers = TRUE;
2582   }
2583
2584   if (!keyframe) {
2585     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2586   } else {
2587     GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2588   }
2589   if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE) {
2590     parse->last_timestamp = GST_BUFFER_TIMESTAMP (buffer);
2591   } else {
2592     GST_BUFFER_TIMESTAMP (buffer) = parse->last_timestamp;
2593   }
2594   gst_buffer_set_caps (buffer, GST_PAD_CAPS (parse->srcpad));
2595   ret = gst_pad_push (parse->srcpad, gst_buffer_ref (buffer));
2596
2597   return ret;
2598 }
2599
2600 static GstFlowReturn
2601 gst_matroska_parse_parse_id (GstMatroskaParse * parse, guint32 id,
2602     guint64 length, guint needed)
2603 {
2604   GstEbmlRead ebml = { 0, };
2605   GstFlowReturn ret = GST_FLOW_OK;
2606   guint64 read;
2607   //GstBuffer *buffer;
2608
2609   GST_DEBUG_OBJECT (parse, "Parsing Element id 0x%x, "
2610       "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
2611
2612 #if 0
2613   if (gst_adapter_available (parse->adapter) >= length + needed) {
2614     buffer = gst_adapter_take_buffer (parse->adapter, length + needed);
2615     gst_pad_push (parse->srcpad, buffer);
2616   } else {
2617     ret = GST_FLOW_UNEXPECTED;
2618   }
2619   //GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2620
2621   return ret;
2622 #endif
2623
2624
2625
2626   /* if we plan to read and parse this element, we need prefix (id + length)
2627    * and the contents */
2628   /* mind about overflow wrap-around when dealing with undefined size */
2629   read = length;
2630   if (G_LIKELY (length != G_MAXUINT64))
2631     read += needed;
2632
2633   switch (parse->common.state) {
2634     case GST_MATROSKA_READ_STATE_START:
2635       switch (id) {
2636         case GST_EBML_ID_HEADER:
2637           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2638           ret = gst_matroska_read_common_parse_header (&parse->common, &ebml);
2639           if (ret != GST_FLOW_OK)
2640             goto parse_failed;
2641           parse->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
2642           gst_matroska_parse_check_seekability (parse);
2643           gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2644           break;
2645         default:
2646           goto invalid_header;
2647           break;
2648       }
2649       break;
2650     case GST_MATROSKA_READ_STATE_SEGMENT:
2651       switch (id) {
2652         case GST_MATROSKA_ID_SEGMENT:
2653           /* eat segment prefix */
2654           GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2655           GST_DEBUG_OBJECT (parse,
2656               "Found Segment start at offset %" G_GUINT64_FORMAT,
2657               parse->common.offset);
2658           /* seeks are from the beginning of the segment,
2659            * after the segment ID/length */
2660           parse->common.ebml_segment_start = parse->common.offset;
2661           parse->common.state = GST_MATROSKA_READ_STATE_HEADER;
2662           gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2663           break;
2664         default:
2665           GST_WARNING_OBJECT (parse,
2666               "Expected a Segment ID (0x%x), but received 0x%x!",
2667               GST_MATROSKA_ID_SEGMENT, id);
2668           GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2669           gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2670           break;
2671       }
2672       break;
2673     case GST_MATROSKA_READ_STATE_SCANNING:
2674       if (id != GST_MATROSKA_ID_CLUSTER &&
2675           id != GST_MATROSKA_ID_CLUSTERTIMECODE)
2676         goto skip;
2677       /* fall-through */
2678     case GST_MATROSKA_READ_STATE_HEADER:
2679     case GST_MATROSKA_READ_STATE_DATA:
2680     case GST_MATROSKA_READ_STATE_SEEK: