matroska: implement forward snapping keyframe seeking
[platform/upstream/gstreamer.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 ("audio/x-matroska; video/x-matroska; "
91         "video/x-matroska-3d; audio/webm; video/webm")
92     );
93
94 static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
95     GST_PAD_SRC,
96     GST_PAD_ALWAYS,
97     GST_STATIC_CAPS ("audio/x-matroska; video/x-matroska; "
98         "video/x-matroska-3d; audio/webm; video/webm")
99     );
100
101 static GstFlowReturn gst_matroska_parse_parse_id (GstMatroskaParse * parse,
102     guint32 id, guint64 length, guint needed);
103
104 /* element functions */
105 //static void gst_matroska_parse_loop (GstPad * pad);
106
107 static gboolean gst_matroska_parse_element_send_event (GstElement * element,
108     GstEvent * event);
109 static gboolean gst_matroska_parse_element_query (GstElement * element,
110     GstQuery * query);
111
112 /* pad functions */
113 static gboolean gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
114     GstPad * pad, GstEvent * event);
115 static gboolean gst_matroska_parse_handle_src_event (GstPad * pad,
116     GstObject * parent, GstEvent * event);
117 static gboolean gst_matroska_parse_handle_src_query (GstPad * pad,
118     GstObject * parent, GstQuery * query);
119
120 static gboolean gst_matroska_parse_handle_sink_event (GstPad * pad,
121     GstObject * parent, GstEvent * event);
122 static GstFlowReturn gst_matroska_parse_chain (GstPad * pad,
123     GstObject * parent, GstBuffer * buffer);
124
125 static GstStateChangeReturn
126 gst_matroska_parse_change_state (GstElement * element,
127     GstStateChange transition);
128 #if 0
129 static void
130 gst_matroska_parse_set_index (GstElement * element, GstIndex * index);
131 static GstIndex *gst_matroska_parse_get_index (GstElement * element);
132 #endif
133
134 /* stream methods */
135 static void gst_matroska_parse_reset (GstElement * element);
136 static gboolean perform_seek_to_offset (GstMatroskaParse * parse,
137     guint64 offset);
138
139 GType gst_matroska_parse_get_type (void);
140 #define parent_class gst_matroska_parse_parent_class
141 G_DEFINE_TYPE (GstMatroskaParse, gst_matroska_parse, GST_TYPE_ELEMENT);
142
143 static void
144 gst_matroska_parse_finalize (GObject * object)
145 {
146   GstMatroskaParse *parse = GST_MATROSKA_PARSE (object);
147
148   if (parse->common.src) {
149     g_ptr_array_free (parse->common.src, TRUE);
150     parse->common.src = NULL;
151   }
152
153   if (parse->common.global_tags) {
154     gst_tag_list_free (parse->common.global_tags);
155     parse->common.global_tags = NULL;
156   }
157
158   g_object_unref (parse->common.adapter);
159
160   G_OBJECT_CLASS (parent_class)->finalize (object);
161 }
162
163 static void
164 gst_matroska_parse_class_init (GstMatroskaParseClass * klass)
165 {
166   GObjectClass *gobject_class = (GObjectClass *) klass;
167   GstElementClass *gstelement_class = (GstElementClass *) klass;
168
169   GST_DEBUG_CATEGORY_INIT (matroskaparse_debug, "matroskaparse", 0,
170       "Matroska parser");
171
172   gobject_class->finalize = gst_matroska_parse_finalize;
173
174   gstelement_class->change_state =
175       GST_DEBUG_FUNCPTR (gst_matroska_parse_change_state);
176   gstelement_class->send_event =
177       GST_DEBUG_FUNCPTR (gst_matroska_parse_element_send_event);
178   gstelement_class->query =
179       GST_DEBUG_FUNCPTR (gst_matroska_parse_element_query);
180
181 #if 0
182   gstelement_class->set_index =
183       GST_DEBUG_FUNCPTR (gst_matroska_parse_set_index);
184   gstelement_class->get_index =
185       GST_DEBUG_FUNCPTR (gst_matroska_parse_get_index);
186 #endif
187
188   gst_element_class_add_pad_template (gstelement_class,
189       gst_static_pad_template_get (&src_templ));
190   gst_element_class_add_pad_template (gstelement_class,
191       gst_static_pad_template_get (&sink_templ));
192
193   gst_element_class_set_static_metadata (gstelement_class,
194       "Matroska parser", "Codec/Parser",
195       "Parses Matroska/WebM streams into video/audio/subtitles",
196       "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
197 }
198
199 static void
200 gst_matroska_parse_init (GstMatroskaParse * parse)
201 {
202   parse->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
203       "sink");
204   gst_pad_set_chain_function (parse->common.sinkpad,
205       GST_DEBUG_FUNCPTR (gst_matroska_parse_chain));
206   gst_pad_set_event_function (parse->common.sinkpad,
207       GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_sink_event));
208   gst_element_add_pad (GST_ELEMENT (parse), parse->common.sinkpad);
209
210   parse->srcpad = gst_pad_new_from_static_template (&src_templ, "src");
211   gst_pad_set_event_function (parse->srcpad,
212       GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_event));
213   gst_pad_set_query_function (parse->srcpad,
214       GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_query));
215   gst_pad_use_fixed_caps (parse->srcpad);
216
217   gst_element_add_pad (GST_ELEMENT (parse), parse->srcpad);
218
219   /* initial stream no. */
220   parse->common.src = NULL;
221
222   parse->common.writing_app = NULL;
223   parse->common.muxing_app = NULL;
224   parse->common.index = NULL;
225   parse->common.global_tags = NULL;
226
227   parse->common.adapter = gst_adapter_new ();
228
229   GST_OBJECT_FLAG_SET (parse, GST_ELEMENT_FLAG_INDEXABLE);
230
231   /* finish off */
232   gst_matroska_parse_reset (GST_ELEMENT (parse));
233 }
234
235 static void
236 gst_matroska_track_free (GstMatroskaTrackContext * track)
237 {
238   g_free (track->codec_id);
239   g_free (track->codec_name);
240   g_free (track->name);
241   g_free (track->language);
242   g_free (track->codec_priv);
243   g_free (track->codec_state);
244
245   if (track->encodings != NULL) {
246     int i;
247
248     for (i = 0; i < track->encodings->len; ++i) {
249       GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
250           GstMatroskaTrackEncoding,
251           i);
252
253       g_free (enc->comp_settings);
254     }
255     g_array_free (track->encodings, TRUE);
256   }
257
258   if (track->pending_tags)
259     gst_tag_list_free (track->pending_tags);
260
261   if (track->index_table)
262     g_array_free (track->index_table, TRUE);
263
264   g_free (track);
265 }
266
267 static void
268 gst_matroska_parse_free_parsed_el (gpointer mem, gpointer user_data)
269 {
270   g_slice_free (guint64, mem);
271 }
272
273 static void
274 gst_matroska_parse_reset (GstElement * element)
275 {
276   GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
277   guint i;
278
279   GST_DEBUG_OBJECT (parse, "Resetting state");
280
281   /* reset input */
282   parse->common.state = GST_MATROSKA_READ_STATE_START;
283
284   /* clean up existing streams */
285   if (parse->common.src) {
286     g_assert (parse->common.src->len == parse->common.num_streams);
287     for (i = 0; i < parse->common.src->len; i++) {
288       GstMatroskaTrackContext *context = g_ptr_array_index (parse->common.src,
289           i);
290
291       gst_caps_replace (&context->caps, NULL);
292       gst_matroska_track_free (context);
293     }
294     g_ptr_array_free (parse->common.src, TRUE);
295   }
296   parse->common.src = g_ptr_array_new ();
297
298   parse->common.num_streams = 0;
299   parse->num_a_streams = 0;
300   parse->num_t_streams = 0;
301   parse->num_v_streams = 0;
302
303   /* reset media info */
304   g_free (parse->common.writing_app);
305   parse->common.writing_app = NULL;
306   g_free (parse->common.muxing_app);
307   parse->common.muxing_app = NULL;
308
309   /* reset indexes */
310   if (parse->common.index) {
311     g_array_free (parse->common.index, TRUE);
312     parse->common.index = NULL;
313   }
314
315   /* reset timers */
316   parse->clock = NULL;
317   parse->common.time_scale = 1000000;
318   parse->common.created = G_MININT64;
319
320   parse->common.index_parsed = FALSE;
321   parse->tracks_parsed = FALSE;
322   parse->common.segmentinfo_parsed = FALSE;
323   parse->common.attachments_parsed = FALSE;
324
325   g_list_foreach (parse->common.tags_parsed,
326       (GFunc) gst_matroska_parse_free_parsed_el, NULL);
327   g_list_free (parse->common.tags_parsed);
328   parse->common.tags_parsed = NULL;
329
330   g_list_foreach (parse->seek_parsed,
331       (GFunc) gst_matroska_parse_free_parsed_el, NULL);
332   g_list_free (parse->seek_parsed);
333   parse->seek_parsed = NULL;
334
335   gst_segment_init (&parse->common.segment, GST_FORMAT_TIME);
336   parse->last_stop_end = GST_CLOCK_TIME_NONE;
337   parse->seek_block = 0;
338
339   parse->common.offset = 0;
340   parse->cluster_time = GST_CLOCK_TIME_NONE;
341   parse->cluster_offset = 0;
342   parse->next_cluster_offset = 0;
343   parse->index_offset = 0;
344   parse->seekable = FALSE;
345   parse->need_newsegment = FALSE;
346   parse->building_index = FALSE;
347   if (parse->seek_event) {
348     gst_event_unref (parse->seek_event);
349     parse->seek_event = NULL;
350   }
351
352   parse->seek_index = NULL;
353   parse->seek_entry = 0;
354
355   if (parse->close_segment) {
356     gst_event_unref (parse->close_segment);
357     parse->close_segment = NULL;
358   }
359
360   if (parse->new_segment) {
361     gst_event_unref (parse->new_segment);
362     parse->new_segment = NULL;
363   }
364 #if 0
365   if (parse->common.element_index) {
366     gst_object_unref (parse->common.element_index);
367     parse->common.element_index = NULL;
368   }
369   parse->common.element_index_writer_id = -1;
370 #endif
371
372   if (parse->common.global_tags) {
373     gst_tag_list_free (parse->common.global_tags);
374   }
375   parse->common.global_tags = gst_tag_list_new_empty ();
376
377   if (parse->common.cached_buffer) {
378     gst_buffer_unref (parse->common.cached_buffer);
379     parse->common.cached_buffer = NULL;
380   }
381
382   if (parse->streamheader != NULL) {
383     gst_buffer_unref (parse->streamheader);
384     parse->streamheader = NULL;
385   }
386 }
387
388 static GstFlowReturn
389 gst_matroska_parse_add_stream (GstMatroskaParse * parse, GstEbmlRead * ebml)
390 {
391   GstMatroskaTrackContext *context;
392   GstFlowReturn ret;
393   guint32 id;
394
395   DEBUG_ELEMENT_START (parse, ebml, "TrackEntry");
396
397   /* start with the master */
398   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
399     DEBUG_ELEMENT_STOP (parse, ebml, "TrackEntry", ret);
400     return ret;
401   }
402
403   /* allocate generic... if we know the type, we'll g_renew()
404    * with the precise type */
405   context = g_new0 (GstMatroskaTrackContext, 1);
406   g_ptr_array_add (parse->common.src, context);
407   context->index = parse->common.num_streams;
408   context->index_writer_id = -1;
409   context->type = 0;            /* no type yet */
410   context->default_duration = 0;
411   context->pos = 0;
412   context->set_discont = TRUE;
413   context->timecodescale = 1.0;
414   context->flags =
415       GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
416       GST_MATROSKA_TRACK_LACING;
417   context->last_flow = GST_FLOW_OK;
418   context->to_offset = G_MAXINT64;
419   context->alignment = 1;
420   parse->common.num_streams++;
421   g_assert (parse->common.src->len == parse->common.num_streams);
422
423   GST_DEBUG_OBJECT (parse, "Stream number %d", context->index);
424
425   /* try reading the trackentry headers */
426   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
427     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
428       break;
429
430     switch (id) {
431         /* track number (unique stream ID) */
432       case GST_MATROSKA_ID_TRACKNUMBER:{
433         guint64 num;
434
435         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
436           break;
437
438         if (num == 0) {
439           GST_ERROR_OBJECT (parse, "Invalid TrackNumber 0");
440           ret = GST_FLOW_ERROR;
441           break;
442         } else if (!gst_matroska_read_common_tracknumber_unique (&parse->common,
443                 num)) {
444           GST_ERROR_OBJECT (parse, "TrackNumber %" G_GUINT64_FORMAT
445               " is not unique", num);
446           ret = GST_FLOW_ERROR;
447           break;
448         }
449
450         GST_DEBUG_OBJECT (parse, "TrackNumber: %" G_GUINT64_FORMAT, num);
451         context->num = num;
452         break;
453       }
454         /* track UID (unique identifier) */
455       case GST_MATROSKA_ID_TRACKUID:{
456         guint64 num;
457
458         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
459           break;
460
461         if (num == 0) {
462           GST_ERROR_OBJECT (parse, "Invalid TrackUID 0");
463           ret = GST_FLOW_ERROR;
464           break;
465         }
466
467         GST_DEBUG_OBJECT (parse, "TrackUID: %" G_GUINT64_FORMAT, num);
468         context->uid = num;
469         break;
470       }
471
472         /* track type (video, audio, combined, subtitle, etc.) */
473       case GST_MATROSKA_ID_TRACKTYPE:{
474         guint64 track_type;
475
476         if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
477           break;
478         }
479
480         if (context->type != 0 && context->type != track_type) {
481           GST_WARNING_OBJECT (parse,
482               "More than one tracktype defined in a TrackEntry - skipping");
483           break;
484         } else if (track_type < 1 || track_type > 254) {
485           GST_WARNING_OBJECT (parse, "Invalid TrackType %" G_GUINT64_FORMAT,
486               track_type);
487           break;
488         }
489
490         GST_DEBUG_OBJECT (parse, "TrackType: %" G_GUINT64_FORMAT, track_type);
491
492         /* ok, so we're actually going to reallocate this thing */
493         switch (track_type) {
494           case GST_MATROSKA_TRACK_TYPE_VIDEO:
495             gst_matroska_track_init_video_context (&context);
496             break;
497           case GST_MATROSKA_TRACK_TYPE_AUDIO:
498             gst_matroska_track_init_audio_context (&context);
499             break;
500           case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
501             gst_matroska_track_init_subtitle_context (&context);
502             break;
503           case GST_MATROSKA_TRACK_TYPE_COMPLEX:
504           case GST_MATROSKA_TRACK_TYPE_LOGO:
505           case GST_MATROSKA_TRACK_TYPE_BUTTONS:
506           case GST_MATROSKA_TRACK_TYPE_CONTROL:
507           default:
508             GST_WARNING_OBJECT (parse,
509                 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
510                 track_type);
511             context->type = 0;
512             break;
513         }
514         g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
515             = context;
516         break;
517       }
518
519         /* tracktype specific stuff for video */
520       case GST_MATROSKA_ID_TRACKVIDEO:{
521         GstMatroskaTrackVideoContext *videocontext;
522
523         DEBUG_ELEMENT_START (parse, ebml, "TrackVideo");
524
525         if (!gst_matroska_track_init_video_context (&context)) {
526           GST_WARNING_OBJECT (parse,
527               "TrackVideo element in non-video track - ignoring track");
528           ret = GST_FLOW_ERROR;
529           break;
530         } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
531           break;
532         }
533         videocontext = (GstMatroskaTrackVideoContext *) context;
534         g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
535             = context;
536
537         while (ret == GST_FLOW_OK &&
538             gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
539           if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
540             break;
541
542           switch (id) {
543               /* Should be one level up but some broken muxers write it here. */
544             case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
545               guint64 num;
546
547               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
548                 break;
549
550               if (num == 0) {
551                 GST_WARNING_OBJECT (parse, "Invalid TrackDefaultDuration 0");
552                 break;
553               }
554
555               GST_DEBUG_OBJECT (parse,
556                   "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
557               context->default_duration = num;
558               break;
559             }
560
561               /* video framerate */
562               /* NOTE: This one is here only for backward compatibility.
563                * Use _TRACKDEFAULDURATION one level up. */
564             case GST_MATROSKA_ID_VIDEOFRAMERATE:{
565               gdouble num;
566
567               if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
568                 break;
569
570               if (num <= 0.0) {
571                 GST_WARNING_OBJECT (parse, "Invalid TrackVideoFPS %lf", num);
572                 break;
573               }
574
575               GST_DEBUG_OBJECT (parse, "TrackVideoFrameRate: %lf", num);
576               if (context->default_duration == 0)
577                 context->default_duration =
578                     gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
579               videocontext->default_fps = num;
580               break;
581             }
582
583               /* width of the size to display the video at */
584             case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
585               guint64 num;
586
587               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
588                 break;
589
590               if (num == 0) {
591                 GST_WARNING_OBJECT (parse, "Invalid TrackVideoDisplayWidth 0");
592                 break;
593               }
594
595               GST_DEBUG_OBJECT (parse,
596                   "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
597               videocontext->display_width = num;
598               break;
599             }
600
601               /* height of the size to display the video at */
602             case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
603               guint64 num;
604
605               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
606                 break;
607
608               if (num == 0) {
609                 GST_WARNING_OBJECT (parse, "Invalid TrackVideoDisplayHeight 0");
610                 break;
611               }
612
613               GST_DEBUG_OBJECT (parse,
614                   "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
615               videocontext->display_height = num;
616               break;
617             }
618
619               /* width of the video in the file */
620             case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
621               guint64 num;
622
623               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
624                 break;
625
626               if (num == 0) {
627                 GST_WARNING_OBJECT (parse, "Invalid TrackVideoPixelWidth 0");
628                 break;
629               }
630
631               GST_DEBUG_OBJECT (parse,
632                   "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
633               videocontext->pixel_width = num;
634               break;
635             }
636
637               /* height of the video in the file */
638             case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
639               guint64 num;
640
641               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
642                 break;
643
644               if (num == 0) {
645                 GST_WARNING_OBJECT (parse, "Invalid TrackVideoPixelHeight 0");
646                 break;
647               }
648
649               GST_DEBUG_OBJECT (parse,
650                   "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
651               videocontext->pixel_height = num;
652               break;
653             }
654
655               /* whether the video is interlaced */
656             case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
657               guint64 num;
658
659               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
660                 break;
661
662               if (num)
663                 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
664               else
665                 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
666               GST_DEBUG_OBJECT (parse, "TrackVideoInterlaced: %d",
667                   (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
668                   0);
669               break;
670             }
671
672               /* aspect ratio behaviour */
673             case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
674               guint64 num;
675
676               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
677                 break;
678
679               if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
680                   num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
681                   num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
682                 GST_WARNING_OBJECT (parse,
683                     "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
684                 break;
685               }
686               GST_DEBUG_OBJECT (parse,
687                   "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
688               videocontext->asr_mode = num;
689               break;
690             }
691
692               /* colourspace (only matters for raw video) fourcc */
693             case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
694               guint8 *data;
695               guint64 datalen;
696
697               if ((ret =
698                       gst_ebml_read_binary (ebml, &id, &data,
699                           &datalen)) != GST_FLOW_OK)
700                 break;
701
702               if (datalen != 4) {
703                 g_free (data);
704                 GST_WARNING_OBJECT (parse,
705                     "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
706                     datalen);
707                 break;
708               }
709
710               memcpy (&videocontext->fourcc, data, 4);
711               GST_DEBUG_OBJECT (parse,
712                   "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
713                   GST_FOURCC_ARGS (videocontext->fourcc));
714               g_free (data);
715               break;
716             }
717
718             default:
719               GST_WARNING_OBJECT (parse,
720                   "Unknown TrackVideo subelement 0x%x - ignoring", id);
721               /* fall through */
722             case GST_MATROSKA_ID_VIDEOSTEREOMODE:
723             case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
724             case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
725             case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
726             case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
727             case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
728             case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
729               ret = gst_ebml_read_skip (ebml);
730               break;
731           }
732         }
733
734         DEBUG_ELEMENT_STOP (parse, ebml, "TrackVideo", ret);
735         break;
736       }
737
738         /* tracktype specific stuff for audio */
739       case GST_MATROSKA_ID_TRACKAUDIO:{
740         GstMatroskaTrackAudioContext *audiocontext;
741
742         DEBUG_ELEMENT_START (parse, ebml, "TrackAudio");
743
744         if (!gst_matroska_track_init_audio_context (&context)) {
745           GST_WARNING_OBJECT (parse,
746               "TrackAudio element in non-audio track - ignoring track");
747           ret = GST_FLOW_ERROR;
748           break;
749         }
750
751         if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
752           break;
753
754         audiocontext = (GstMatroskaTrackAudioContext *) context;
755         g_ptr_array_index (parse->common.src, parse->common.num_streams - 1)
756             = context;
757
758         while (ret == GST_FLOW_OK &&
759             gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
760           if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
761             break;
762
763           switch (id) {
764               /* samplerate */
765             case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
766               gdouble num;
767
768               if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
769                 break;
770
771
772               if (num <= 0.0) {
773                 GST_WARNING_OBJECT (parse,
774                     "Invalid TrackAudioSamplingFrequency %lf", num);
775                 break;
776               }
777
778               GST_DEBUG_OBJECT (parse, "TrackAudioSamplingFrequency: %lf", num);
779               audiocontext->samplerate = num;
780               break;
781             }
782
783               /* bitdepth */
784             case GST_MATROSKA_ID_AUDIOBITDEPTH:{
785               guint64 num;
786
787               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
788                 break;
789
790               if (num == 0) {
791                 GST_WARNING_OBJECT (parse, "Invalid TrackAudioBitDepth 0");
792                 break;
793               }
794
795               GST_DEBUG_OBJECT (parse, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
796                   num);
797               audiocontext->bitdepth = num;
798               break;
799             }
800
801               /* channels */
802             case GST_MATROSKA_ID_AUDIOCHANNELS:{
803               guint64 num;
804
805               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
806                 break;
807
808               if (num == 0) {
809                 GST_WARNING_OBJECT (parse, "Invalid TrackAudioChannels 0");
810                 break;
811               }
812
813               GST_DEBUG_OBJECT (parse, "TrackAudioChannels: %" G_GUINT64_FORMAT,
814                   num);
815               audiocontext->channels = num;
816               break;
817             }
818
819             default:
820               GST_WARNING_OBJECT (parse,
821                   "Unknown TrackAudio subelement 0x%x - ignoring", id);
822               /* fall through */
823             case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
824             case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
825               ret = gst_ebml_read_skip (ebml);
826               break;
827           }
828         }
829
830         DEBUG_ELEMENT_STOP (parse, ebml, "TrackAudio", ret);
831
832         break;
833       }
834
835         /* codec identifier */
836       case GST_MATROSKA_ID_CODECID:{
837         gchar *text;
838
839         if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
840           break;
841
842         GST_DEBUG_OBJECT (parse, "CodecID: %s", GST_STR_NULL (text));
843         context->codec_id = text;
844         break;
845       }
846
847         /* codec private data */
848       case GST_MATROSKA_ID_CODECPRIVATE:{
849         guint8 *data;
850         guint64 size;
851
852         if ((ret =
853                 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
854           break;
855
856         context->codec_priv = data;
857         context->codec_priv_size = size;
858
859         GST_DEBUG_OBJECT (parse, "CodecPrivate of size %" G_GUINT64_FORMAT,
860             size);
861         break;
862       }
863
864         /* name of the codec */
865       case GST_MATROSKA_ID_CODECNAME:{
866         gchar *text;
867
868         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
869           break;
870
871         GST_DEBUG_OBJECT (parse, "CodecName: %s", GST_STR_NULL (text));
872         context->codec_name = text;
873         break;
874       }
875
876         /* name of this track */
877       case GST_MATROSKA_ID_TRACKNAME:{
878         gchar *text;
879
880         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
881           break;
882
883         context->name = text;
884         GST_DEBUG_OBJECT (parse, "TrackName: %s", GST_STR_NULL (text));
885         break;
886       }
887
888         /* language (matters for audio/subtitles, mostly) */
889       case GST_MATROSKA_ID_TRACKLANGUAGE:{
890         gchar *text;
891
892         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
893           break;
894
895
896         context->language = text;
897
898         /* fre-ca => fre */
899         if (strlen (context->language) >= 4 && context->language[3] == '-')
900           context->language[3] = '\0';
901
902         GST_DEBUG_OBJECT (parse, "TrackLanguage: %s",
903             GST_STR_NULL (context->language));
904         break;
905       }
906
907         /* whether this is actually used */
908       case GST_MATROSKA_ID_TRACKFLAGENABLED:{
909         guint64 num;
910
911         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
912           break;
913
914         if (num)
915           context->flags |= GST_MATROSKA_TRACK_ENABLED;
916         else
917           context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
918
919         GST_DEBUG_OBJECT (parse, "TrackEnabled: %d",
920             (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
921         break;
922       }
923
924         /* whether it's the default for this track type */
925       case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
926         guint64 num;
927
928         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
929           break;
930
931         if (num)
932           context->flags |= GST_MATROSKA_TRACK_DEFAULT;
933         else
934           context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
935
936         GST_DEBUG_OBJECT (parse, "TrackDefault: %d",
937             (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
938         break;
939       }
940
941         /* whether the track must be used during playback */
942       case GST_MATROSKA_ID_TRACKFLAGFORCED:{
943         guint64 num;
944
945         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
946           break;
947
948         if (num)
949           context->flags |= GST_MATROSKA_TRACK_FORCED;
950         else
951           context->flags &= ~GST_MATROSKA_TRACK_FORCED;
952
953         GST_DEBUG_OBJECT (parse, "TrackForced: %d",
954             (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
955         break;
956       }
957
958         /* lacing (like MPEG, where blocks don't end/start on frame
959          * boundaries) */
960       case GST_MATROSKA_ID_TRACKFLAGLACING:{
961         guint64 num;
962
963         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
964           break;
965
966         if (num)
967           context->flags |= GST_MATROSKA_TRACK_LACING;
968         else
969           context->flags &= ~GST_MATROSKA_TRACK_LACING;
970
971         GST_DEBUG_OBJECT (parse, "TrackLacing: %d",
972             (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
973         break;
974       }
975
976         /* default length (in time) of one data block in this track */
977       case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
978         guint64 num;
979
980         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
981           break;
982
983
984         if (num == 0) {
985           GST_WARNING_OBJECT (parse, "Invalid TrackDefaultDuration 0");
986           break;
987         }
988
989         GST_DEBUG_OBJECT (parse, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
990             num);
991         context->default_duration = num;
992         break;
993       }
994
995       case GST_MATROSKA_ID_CONTENTENCODINGS:{
996         ret = gst_matroska_read_common_read_track_encodings (&parse->common,
997             ebml, context);
998         break;
999       }
1000
1001       case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1002         gdouble num;
1003
1004         if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1005           break;
1006
1007         if (num <= 0.0) {
1008           GST_WARNING_OBJECT (parse, "Invalid TrackTimeCodeScale %lf", num);
1009           break;
1010         }
1011
1012         GST_DEBUG_OBJECT (parse, "TrackTimeCodeScale: %lf", num);
1013         context->timecodescale = num;
1014         break;
1015       }
1016
1017       default:
1018         GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1019         /* pass-through */
1020
1021         /* we ignore these because they're nothing useful (i.e. crap)
1022          * or simply not implemented yet. */
1023       case GST_MATROSKA_ID_TRACKMINCACHE:
1024       case GST_MATROSKA_ID_TRACKMAXCACHE:
1025       case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1026       case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1027       case GST_MATROSKA_ID_TRACKOVERLAY:
1028       case GST_MATROSKA_ID_TRACKTRANSLATE:
1029       case GST_MATROSKA_ID_TRACKOFFSET:
1030       case GST_MATROSKA_ID_CODECSETTINGS:
1031       case GST_MATROSKA_ID_CODECINFOURL:
1032       case GST_MATROSKA_ID_CODECDOWNLOADURL:
1033       case GST_MATROSKA_ID_CODECDECODEALL:
1034         ret = gst_ebml_read_skip (ebml);
1035         break;
1036     }
1037   }
1038
1039   DEBUG_ELEMENT_STOP (parse, ebml, "TrackEntry", ret);
1040
1041   /* Decode codec private data if necessary */
1042   if (context->encodings && context->encodings->len > 0 && context->codec_priv
1043       && context->codec_priv_size > 0) {
1044     if (!gst_matroska_decode_data (context->encodings,
1045             &context->codec_priv, &context->codec_priv_size,
1046             GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1047       GST_WARNING_OBJECT (parse, "Decoding codec private data failed");
1048       ret = GST_FLOW_ERROR;
1049     }
1050   }
1051
1052   if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1053           && ret != GST_FLOW_EOS)) {
1054     if (ret == GST_FLOW_OK || ret == GST_FLOW_EOS)
1055       GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1056
1057     parse->common.num_streams--;
1058     g_ptr_array_remove_index (parse->common.src, parse->common.num_streams);
1059     g_assert (parse->common.src->len == parse->common.num_streams);
1060     if (context) {
1061       gst_matroska_track_free (context);
1062     }
1063
1064     return ret;
1065   }
1066
1067   if ((context->language == NULL || *context->language == '\0') &&
1068       (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1069           context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1070     GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1071     context->language = g_strdup ("eng");
1072   }
1073
1074
1075   /* tadaah! */
1076   return ret;
1077 }
1078
1079 static gboolean
1080 gst_matroska_parse_query (GstMatroskaParse * parse, GstPad * pad,
1081     GstQuery * query)
1082 {
1083   gboolean res = FALSE;
1084   GstMatroskaTrackContext *context = NULL;
1085
1086   if (pad) {
1087     context = gst_pad_get_element_private (pad);
1088   }
1089
1090   switch (GST_QUERY_TYPE (query)) {
1091     case GST_QUERY_POSITION:
1092     {
1093       GstFormat format;
1094
1095       gst_query_parse_position (query, &format, NULL);
1096
1097       if (format == GST_FORMAT_TIME) {
1098         GST_OBJECT_LOCK (parse);
1099         if (context)
1100           gst_query_set_position (query, GST_FORMAT_TIME, context->pos);
1101         else
1102           gst_query_set_position (query, GST_FORMAT_TIME,
1103               parse->common.segment.position);
1104         GST_OBJECT_UNLOCK (parse);
1105       } else if (format == GST_FORMAT_DEFAULT && context
1106           && context->default_duration) {
1107         GST_OBJECT_LOCK (parse);
1108         gst_query_set_position (query, GST_FORMAT_DEFAULT,
1109             context->pos / context->default_duration);
1110         GST_OBJECT_UNLOCK (parse);
1111       } else {
1112         GST_DEBUG_OBJECT (parse,
1113             "only position query in TIME and DEFAULT format is supported");
1114       }
1115
1116       res = TRUE;
1117       break;
1118     }
1119     case GST_QUERY_DURATION:
1120     {
1121       GstFormat format;
1122
1123       gst_query_parse_duration (query, &format, NULL);
1124
1125       if (format == GST_FORMAT_TIME) {
1126         GST_OBJECT_LOCK (parse);
1127         gst_query_set_duration (query, GST_FORMAT_TIME,
1128             parse->common.segment.duration);
1129         GST_OBJECT_UNLOCK (parse);
1130       } else if (format == GST_FORMAT_DEFAULT && context
1131           && context->default_duration) {
1132         GST_OBJECT_LOCK (parse);
1133         gst_query_set_duration (query, GST_FORMAT_DEFAULT,
1134             parse->common.segment.duration / context->default_duration);
1135         GST_OBJECT_UNLOCK (parse);
1136       } else {
1137         GST_DEBUG_OBJECT (parse,
1138             "only duration query in TIME and DEFAULT format is supported");
1139       }
1140
1141       res = TRUE;
1142       break;
1143     }
1144
1145     case GST_QUERY_SEEKING:
1146     {
1147       GstFormat fmt;
1148
1149       gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1150       if (fmt == GST_FORMAT_TIME) {
1151         gboolean seekable;
1152
1153         /* assuming we'll be able to get an index ... */
1154         seekable = parse->seekable;
1155
1156         gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
1157             0, parse->common.segment.duration);
1158         res = TRUE;
1159       }
1160       break;
1161     }
1162     default:
1163       res = gst_pad_query_default (pad, (GstObject *) parse, query);
1164       break;
1165   }
1166
1167   return res;
1168 }
1169
1170 static gboolean
1171 gst_matroska_parse_element_query (GstElement * element, GstQuery * query)
1172 {
1173   return gst_matroska_parse_query (GST_MATROSKA_PARSE (element), NULL, query);
1174 }
1175
1176 static gboolean
1177 gst_matroska_parse_handle_src_query (GstPad * pad, GstObject * parent,
1178     GstQuery * query)
1179 {
1180   gboolean ret;
1181   GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
1182
1183   ret = gst_matroska_parse_query (parse, pad, query);
1184
1185   return ret;
1186 }
1187
1188 /* returns FALSE if there are no pads to deliver event to,
1189  * otherwise TRUE (whatever the outcome of event sending),
1190  * takes ownership of the passed event! */
1191 static gboolean
1192 gst_matroska_parse_send_event (GstMatroskaParse * parse, GstEvent * event)
1193 {
1194   gboolean ret = FALSE;
1195
1196   g_return_val_if_fail (event != NULL, FALSE);
1197
1198   GST_DEBUG_OBJECT (parse, "Sending event of type %s to all source pads",
1199       GST_EVENT_TYPE_NAME (event));
1200
1201   gst_pad_push_event (parse->srcpad, event);
1202
1203   return ret;
1204 }
1205
1206 static gboolean
1207 gst_matroska_parse_element_send_event (GstElement * element, GstEvent * event)
1208 {
1209   GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
1210   gboolean res;
1211
1212   g_return_val_if_fail (event != NULL, FALSE);
1213
1214   if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
1215     res = gst_matroska_parse_handle_seek_event (parse, NULL, event);
1216   } else {
1217     GST_WARNING_OBJECT (parse, "Unhandled event of type %s",
1218         GST_EVENT_TYPE_NAME (event));
1219     res = FALSE;
1220   }
1221   gst_event_unref (event);
1222   return res;
1223 }
1224
1225 /* searches for a cluster start from @pos,
1226  * return GST_FLOW_OK and cluster position in @pos if found */
1227 static GstFlowReturn
1228 gst_matroska_parse_search_cluster (GstMatroskaParse * parse, gint64 * pos)
1229 {
1230   gint64 newpos = *pos;
1231   gint64 orig_offset;
1232   GstFlowReturn ret = GST_FLOW_OK;
1233   const guint chunk = 64 * 1024;
1234   GstBuffer *buf;
1235   GstMapInfo map;
1236   gpointer data;
1237   gsize size;
1238   guint64 length;
1239   guint32 id;
1240   guint needed;
1241
1242   orig_offset = parse->common.offset;
1243
1244   /* read in at newpos and scan for ebml cluster id */
1245   while (1) {
1246     GstByteReader reader;
1247     gint cluster_pos;
1248
1249     buf = NULL;
1250     ret = gst_pad_pull_range (parse->common.sinkpad, newpos, chunk, &buf);
1251     if (ret != GST_FLOW_OK)
1252       break;
1253     GST_DEBUG_OBJECT (parse,
1254         "read buffer size %" G_GSIZE_FORMAT " at offset %" G_GINT64_FORMAT,
1255         gst_buffer_get_size (buf), newpos);
1256     gst_buffer_map (buf, &map, GST_MAP_READ);
1257     data = map.data;
1258     size = map.size;
1259     gst_byte_reader_init (&reader, data, size);
1260     cluster_pos = 0;
1261   resume:
1262     cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
1263         GST_MATROSKA_ID_CLUSTER, cluster_pos, size - cluster_pos);
1264     if (cluster_pos >= 0) {
1265       newpos += cluster_pos;
1266       GST_DEBUG_OBJECT (parse,
1267           "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
1268       /* extra checks whether we really sync'ed to a cluster:
1269        * - either it is the first and only cluster
1270        * - either there is a cluster after this one
1271        * - either cluster length is undefined
1272        */
1273       /* ok if first cluster (there may not a subsequent one) */
1274       if (newpos == parse->first_cluster_offset) {
1275         GST_DEBUG_OBJECT (parse, "cluster is first cluster -> OK");
1276         break;
1277       }
1278       parse->common.offset = newpos;
1279       ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1280           GST_ELEMENT_CAST (parse), &id, &length, &needed);
1281       if (ret != GST_FLOW_OK)
1282         goto resume;
1283       g_assert (id == GST_MATROSKA_ID_CLUSTER);
1284       GST_DEBUG_OBJECT (parse, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
1285           length, needed);
1286       /* ok if undefined length or first cluster */
1287       if (length == G_MAXUINT64) {
1288         GST_DEBUG_OBJECT (parse, "cluster has undefined length -> OK");
1289         break;
1290       }
1291       /* skip cluster */
1292       parse->common.offset += length + needed;
1293       ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
1294           GST_ELEMENT_CAST (parse), &id, &length, &needed);
1295       if (ret != GST_FLOW_OK)
1296         goto resume;
1297       GST_DEBUG_OBJECT (parse, "next element is %scluster",
1298           id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
1299       if (id == GST_MATROSKA_ID_CLUSTER)
1300         break;
1301       /* not ok, resume */
1302       goto resume;
1303     } else {
1304       /* partial cluster id may have been in tail of buffer */
1305       newpos += MAX (size, 4) - 3;
1306       gst_buffer_unmap (buf, &map);
1307       gst_buffer_unref (buf);
1308       buf = NULL;
1309     }
1310   }
1311
1312   if (buf) {
1313     gst_buffer_unmap (buf, &map);
1314     gst_buffer_unref (buf);
1315     buf = NULL;
1316   }
1317
1318   parse->common.offset = orig_offset;
1319   *pos = newpos;
1320   return ret;
1321 }
1322
1323
1324 static gboolean
1325 gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
1326     GstPad * pad, GstEvent * event)
1327 {
1328   GstMatroskaIndex *entry = NULL;
1329   GstSeekFlags flags;
1330   GstSeekType cur_type, stop_type;
1331   GstFormat format;
1332   gdouble rate;
1333   gint64 cur, stop;
1334   GstMatroskaTrackContext *track = NULL;
1335   GstSegment seeksegment = { 0, };
1336   gboolean update;
1337
1338   if (pad)
1339     track = gst_pad_get_element_private (pad);
1340
1341   track = gst_matroska_read_common_get_seek_track (&parse->common, track);
1342
1343   gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1344       &stop_type, &stop);
1345
1346   /* we can only seek on time */
1347   if (format != GST_FORMAT_TIME) {
1348     GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1349     return FALSE;
1350   }
1351
1352   /* copy segment, we need this because we still need the old
1353    * segment when we close the current segment. */
1354   memcpy (&seeksegment, &parse->common.segment, sizeof (GstSegment));
1355
1356   if (event) {
1357     GST_DEBUG_OBJECT (parse, "configuring seek");
1358     gst_segment_do_seek (&seeksegment, rate, format, flags,
1359         cur_type, cur, stop_type, stop, &update);
1360   }
1361
1362   GST_DEBUG_OBJECT (parse, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
1363
1364   /* check sanity before we start flushing and all that */
1365   GST_OBJECT_LOCK (parse);
1366   if ((entry = gst_matroska_read_common_do_index_seek (&parse->common, track,
1367               seeksegment.position, &parse->seek_index, &parse->seek_entry,
1368               FALSE)) == NULL) {
1369     /* pull mode without index can scan later on */
1370     GST_DEBUG_OBJECT (parse, "No matching seek entry in index");
1371     GST_OBJECT_UNLOCK (parse);
1372     return FALSE;
1373   }
1374   GST_DEBUG_OBJECT (parse, "Seek position looks sane");
1375   GST_OBJECT_UNLOCK (parse);
1376
1377   /* need to seek to cluster start to pick up cluster time */
1378   /* upstream takes care of flushing and all that
1379    * ... and newsegment event handling takes care of the rest */
1380   return perform_seek_to_offset (parse, entry->pos
1381       + parse->common.ebml_segment_start);
1382 }
1383
1384 /*
1385  * Handle whether we can perform the seek event or if we have to let the chain
1386  * function handle seeks to build the seek indexes first.
1387  */
1388 static gboolean
1389 gst_matroska_parse_handle_seek_push (GstMatroskaParse * parse, GstPad * pad,
1390     GstEvent * event)
1391 {
1392   GstSeekFlags flags;
1393   GstSeekType cur_type, stop_type;
1394   GstFormat format;
1395   gdouble rate;
1396   gint64 cur, stop;
1397
1398   gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1399       &stop_type, &stop);
1400
1401   /* sanity checks */
1402
1403   /* we can only seek on time */
1404   if (format != GST_FORMAT_TIME) {
1405     GST_DEBUG_OBJECT (parse, "Can only seek on TIME");
1406     return FALSE;
1407   }
1408
1409   if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
1410     GST_DEBUG_OBJECT (parse, "Seek end-time not supported in streaming mode");
1411     return FALSE;
1412   }
1413
1414   if (!(flags & GST_SEEK_FLAG_FLUSH)) {
1415     GST_DEBUG_OBJECT (parse,
1416         "Non-flushing seek not supported in streaming mode");
1417     return FALSE;
1418   }
1419
1420   if (flags & GST_SEEK_FLAG_SEGMENT) {
1421     GST_DEBUG_OBJECT (parse, "Segment seek not supported in streaming mode");
1422     return FALSE;
1423   }
1424
1425   /* check for having parsed index already */
1426   if (!parse->common.index_parsed) {
1427     gboolean building_index;
1428     guint64 offset = 0;
1429
1430     if (!parse->index_offset) {
1431       GST_DEBUG_OBJECT (parse, "no index (location); no seek in push mode");
1432       return FALSE;
1433     }
1434
1435     GST_OBJECT_LOCK (parse);
1436     /* handle the seek event in the chain function */
1437     parse->common.state = GST_MATROSKA_READ_STATE_SEEK;
1438     /* no more seek can be issued until state reset to _DATA */
1439
1440     /* copy the event */
1441     if (parse->seek_event)
1442       gst_event_unref (parse->seek_event);
1443     parse->seek_event = gst_event_ref (event);
1444
1445     /* set the building_index flag so that only one thread can setup the
1446      * structures for index seeking. */
1447     building_index = parse->building_index;
1448     if (!building_index) {
1449       parse->building_index = TRUE;
1450       offset = parse->index_offset;
1451     }
1452     GST_OBJECT_UNLOCK (parse);
1453
1454     if (!building_index) {
1455       /* seek to the first subindex or legacy index */
1456       GST_INFO_OBJECT (parse, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
1457       return perform_seek_to_offset (parse, offset);
1458     }
1459
1460     /* well, we are handling it already */
1461     return TRUE;
1462   }
1463
1464   /* delegate to tweaked regular seek */
1465   return gst_matroska_parse_handle_seek_event (parse, pad, event);
1466 }
1467
1468 static gboolean
1469 gst_matroska_parse_handle_src_event (GstPad * pad, GstObject * parent,
1470     GstEvent * event)
1471 {
1472   GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
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, NULL, &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   return res;
1520 }
1521
1522 static GstFlowReturn
1523 gst_matroska_parse_parse_tracks (GstMatroskaParse * parse, GstEbmlRead * ebml)
1524 {
1525   GstFlowReturn ret = GST_FLOW_OK;
1526   guint32 id;
1527
1528   DEBUG_ELEMENT_START (parse, ebml, "Tracks");
1529
1530   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1531     DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1532     return ret;
1533   }
1534
1535   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1536     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1537       break;
1538
1539     switch (id) {
1540         /* one track within the "all-tracks" header */
1541       case GST_MATROSKA_ID_TRACKENTRY:
1542         ret = gst_matroska_parse_add_stream (parse, ebml);
1543         break;
1544
1545       default:
1546         ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1547             "Track", id);
1548         break;
1549     }
1550   }
1551   DEBUG_ELEMENT_STOP (parse, ebml, "Tracks", ret);
1552
1553   parse->tracks_parsed = TRUE;
1554
1555   return ret;
1556 }
1557
1558 /*
1559  * Read signed/unsigned "EBML" numbers.
1560  * Return: number of bytes processed.
1561  */
1562
1563 static gint
1564 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
1565 {
1566   gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
1567   guint64 total;
1568
1569   if (size <= 0) {
1570     return -1;
1571   }
1572
1573   total = data[0];
1574   while (read <= 8 && !(total & len_mask)) {
1575     read++;
1576     len_mask >>= 1;
1577   }
1578   if (read > 8)
1579     return -1;
1580
1581   if ((total &= (len_mask - 1)) == len_mask - 1)
1582     num_ffs++;
1583   if (size < read)
1584     return -1;
1585   while (n < read) {
1586     if (data[n] == 0xff)
1587       num_ffs++;
1588     total = (total << 8) | data[n];
1589     n++;
1590   }
1591
1592   if (read == num_ffs && total != 0)
1593     *num = G_MAXUINT64;
1594   else
1595     *num = total;
1596
1597   return read;
1598 }
1599
1600 static gint
1601 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
1602 {
1603   guint64 unum;
1604   gint res;
1605
1606   /* read as unsigned number first */
1607   if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
1608     return -1;
1609
1610   /* make signed */
1611   if (unum == G_MAXUINT64)
1612     *num = G_MAXINT64;
1613   else
1614     *num = unum - ((1 << ((7 * res) - 1)) - 1);
1615
1616   return res;
1617 }
1618
1619 static GstFlowReturn
1620 gst_matroska_parse_parse_blockgroup_or_simpleblock (GstMatroskaParse * parse,
1621     GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
1622     gboolean is_simpleblock)
1623 {
1624   GstMatroskaTrackContext *stream = NULL;
1625   GstFlowReturn ret = GST_FLOW_OK;
1626   gboolean readblock = FALSE;
1627   guint32 id;
1628   guint64 block_duration = 0;
1629   GstBuffer *buf = NULL;
1630   GstMapInfo map;
1631   gint stream_num = -1, n, laces = 0;
1632   guint size = 0;
1633   gint *lace_size = NULL;
1634   gint64 time = 0;
1635   gint flags = 0;
1636   gint64 referenceblock = 0;
1637
1638   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1639     if (!is_simpleblock) {
1640       if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
1641         goto data_error;
1642       }
1643     } else {
1644       id = GST_MATROSKA_ID_SIMPLEBLOCK;
1645     }
1646
1647     switch (id) {
1648         /* one block inside the group. Note, block parsing is one
1649          * of the harder things, so this code is a bit complicated.
1650          * See http://www.matroska.org/ for documentation. */
1651       case GST_MATROSKA_ID_SIMPLEBLOCK:
1652       case GST_MATROSKA_ID_BLOCK:
1653       {
1654         guint64 num;
1655         guint8 *data;
1656
1657         if (buf) {
1658           gst_buffer_unref (buf);
1659           buf = NULL;
1660         }
1661         if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
1662           break;
1663
1664         gst_buffer_map (buf, &map, GST_MAP_READ);
1665         data = map.data;
1666         size = map.size;
1667
1668         /* first byte(s): blocknum */
1669         if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1670           goto data_error;
1671         data += n;
1672         size -= n;
1673
1674         /* fetch stream from num */
1675         stream_num = gst_matroska_read_common_stream_from_num (&parse->common,
1676             num);
1677         if (G_UNLIKELY (size < 3)) {
1678           GST_WARNING_OBJECT (parse, "Invalid size %u", size);
1679           /* non-fatal, try next block(group) */
1680           ret = GST_FLOW_OK;
1681           goto done;
1682         } else if (G_UNLIKELY (stream_num < 0 ||
1683                 stream_num >= parse->common.num_streams)) {
1684           /* let's not give up on a stray invalid track number */
1685           GST_WARNING_OBJECT (parse,
1686               "Invalid stream %d for track number %" G_GUINT64_FORMAT
1687               "; ignoring block", stream_num, num);
1688           goto done;
1689         }
1690
1691         stream = g_ptr_array_index (parse->common.src, stream_num);
1692
1693         /* time (relative to cluster time) */
1694         time = ((gint16) GST_READ_UINT16_BE (data));
1695         data += 2;
1696         size -= 2;
1697         flags = GST_READ_UINT8 (data);
1698         data += 1;
1699         size -= 1;
1700
1701         GST_LOG_OBJECT (parse, "time %" G_GUINT64_FORMAT ", flags %d", time,
1702             flags);
1703
1704         switch ((flags & 0x06) >> 1) {
1705           case 0x0:            /* no lacing */
1706             laces = 1;
1707             lace_size = g_new (gint, 1);
1708             lace_size[0] = size;
1709             break;
1710
1711           case 0x1:            /* xiph lacing */
1712           case 0x2:            /* fixed-size lacing */
1713           case 0x3:            /* EBML lacing */
1714             if (size == 0)
1715               goto invalid_lacing;
1716             laces = GST_READ_UINT8 (data) + 1;
1717             data += 1;
1718             size -= 1;
1719             lace_size = g_new0 (gint, laces);
1720
1721             switch ((flags & 0x06) >> 1) {
1722               case 0x1:        /* xiph lacing */  {
1723                 guint temp, total = 0;
1724
1725                 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
1726                   while (1) {
1727                     if (size == 0)
1728                       goto invalid_lacing;
1729                     temp = GST_READ_UINT8 (data);
1730                     lace_size[n] += temp;
1731                     data += 1;
1732                     size -= 1;
1733                     if (temp != 0xff)
1734                       break;
1735                   }
1736                   total += lace_size[n];
1737                 }
1738                 lace_size[n] = size - total;
1739                 break;
1740               }
1741
1742               case 0x2:        /* fixed-size lacing */
1743                 for (n = 0; n < laces; n++)
1744                   lace_size[n] = size / laces;
1745                 break;
1746
1747               case 0x3:        /* EBML lacing */  {
1748                 guint total;
1749
1750                 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
1751                   goto data_error;
1752                 data += n;
1753                 size -= n;
1754                 total = lace_size[0] = num;
1755                 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
1756                   gint64 snum;
1757                   gint r;
1758
1759                   if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
1760                     goto data_error;
1761                   data += r;
1762                   size -= r;
1763                   lace_size[n] = lace_size[n - 1] + snum;
1764                   total += lace_size[n];
1765                 }
1766                 if (n < laces)
1767                   lace_size[n] = size - total;
1768                 break;
1769               }
1770             }
1771             break;
1772         }
1773
1774         if (ret != GST_FLOW_OK)
1775           break;
1776
1777         readblock = TRUE;
1778         break;
1779       }
1780
1781       case GST_MATROSKA_ID_BLOCKDURATION:{
1782         ret = gst_ebml_read_uint (ebml, &id, &block_duration);
1783         GST_DEBUG_OBJECT (parse, "BlockDuration: %" G_GUINT64_FORMAT,
1784             block_duration);
1785         break;
1786       }
1787
1788       case GST_MATROSKA_ID_REFERENCEBLOCK:{
1789         ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
1790         GST_DEBUG_OBJECT (parse, "ReferenceBlock: %" G_GINT64_FORMAT,
1791             referenceblock);
1792         break;
1793       }
1794
1795       case GST_MATROSKA_ID_CODECSTATE:{
1796         guint8 *data;
1797         guint64 data_len = 0;
1798
1799         if ((ret =
1800                 gst_ebml_read_binary (ebml, &id, &data,
1801                     &data_len)) != GST_FLOW_OK)
1802           break;
1803
1804         if (G_UNLIKELY (stream == NULL)) {
1805           GST_WARNING_OBJECT (parse,
1806               "Unexpected CodecState subelement - ignoring");
1807           break;
1808         }
1809
1810         g_free (stream->codec_state);
1811         stream->codec_state = data;
1812         stream->codec_state_size = data_len;
1813
1814         break;
1815       }
1816
1817       default:
1818         ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
1819             "BlockGroup", id);
1820         break;
1821
1822       case GST_MATROSKA_ID_BLOCKVIRTUAL:
1823       case GST_MATROSKA_ID_BLOCKADDITIONS:
1824       case GST_MATROSKA_ID_REFERENCEPRIORITY:
1825       case GST_MATROSKA_ID_REFERENCEVIRTUAL:
1826       case GST_MATROSKA_ID_SLICES:
1827         GST_DEBUG_OBJECT (parse,
1828             "Skipping BlockGroup subelement 0x%x - ignoring", id);
1829         ret = gst_ebml_read_skip (ebml);
1830         break;
1831     }
1832
1833     if (is_simpleblock)
1834       break;
1835   }
1836
1837   /* reading a number or so could have failed */
1838   if (ret != GST_FLOW_OK)
1839     goto data_error;
1840
1841   if (ret == GST_FLOW_OK && readblock) {
1842     guint64 duration = 0;
1843     gint64 lace_time = 0;
1844     gboolean delta_unit;
1845
1846     stream = g_ptr_array_index (parse->common.src, stream_num);
1847
1848     if (cluster_time != GST_CLOCK_TIME_NONE) {
1849       /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
1850        * Drop unless the lace contains timestamp 0? */
1851       if (time < 0 && (-time) > cluster_time) {
1852         lace_time = 0;
1853       } else {
1854         if (stream->timecodescale == 1.0)
1855           lace_time = (cluster_time + time) * parse->common.time_scale;
1856         else
1857           lace_time =
1858               gst_util_guint64_to_gdouble ((cluster_time + time) *
1859               parse->common.time_scale) * stream->timecodescale;
1860       }
1861     } else {
1862       lace_time = GST_CLOCK_TIME_NONE;
1863     }
1864
1865     if (lace_time != GST_CLOCK_TIME_NONE) {
1866       parse->last_timestamp = lace_time;
1867     }
1868     /* need to refresh segment info ASAP */
1869     if (GST_CLOCK_TIME_IS_VALID (lace_time) && parse->need_newsegment) {
1870       GstSegment segment;
1871       GST_DEBUG_OBJECT (parse,
1872           "generating segment starting at %" GST_TIME_FORMAT,
1873           GST_TIME_ARGS (lace_time));
1874       /* pretend we seeked here */
1875       gst_segment_do_seek (&parse->common.segment, parse->common.segment.rate,
1876           GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, lace_time,
1877           GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE, NULL);
1878       /* now convey our segment notion downstream */
1879       segment = parse->common.segment;
1880       segment.position = segment.start;
1881       gst_matroska_parse_send_event (parse, gst_event_new_segment (&segment));
1882       parse->need_newsegment = FALSE;
1883     }
1884
1885     if (block_duration) {
1886       if (stream->timecodescale == 1.0)
1887         duration = gst_util_uint64_scale (block_duration,
1888             parse->common.time_scale, 1);
1889       else
1890         duration =
1891             gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
1892             (gst_util_uint64_scale (block_duration, parse->common.time_scale,
1893                     1)) * stream->timecodescale);
1894     } else if (stream->default_duration) {
1895       duration = stream->default_duration * laces;
1896     }
1897     /* else duration is diff between timecode of this and next block */
1898
1899     /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
1900        a ReferenceBlock implies that this is not a keyframe. In either
1901        case, it only makes sense for video streams. */
1902     delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1903         ((is_simpleblock && !(flags & 0x80)) || referenceblock);
1904
1905     if (delta_unit && stream->set_discont) {
1906       /* When doing seeks or such, we need to restart on key frames or
1907        * decoders might choke. */
1908       GST_DEBUG_OBJECT (parse, "skipping delta unit");
1909       goto done;
1910     }
1911
1912     for (n = 0; n < laces; n++) {
1913       if (G_UNLIKELY (lace_size[n] > size)) {
1914         GST_WARNING_OBJECT (parse, "Invalid lace size");
1915         break;
1916       }
1917
1918       /* QoS for video track with an index. the assumption is that
1919          index entries point to keyframes, but if that is not true we
1920          will instad skip until the next keyframe. */
1921       if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1922           stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
1923           stream->index_table && parse->common.segment.rate > 0.0) {
1924         GstMatroskaTrackVideoContext *videocontext =
1925             (GstMatroskaTrackVideoContext *) stream;
1926         GstClockTime earliest_time;
1927         GstClockTime earliest_stream_time;
1928
1929         GST_OBJECT_LOCK (parse);
1930         earliest_time = videocontext->earliest_time;
1931         GST_OBJECT_UNLOCK (parse);
1932         earliest_stream_time = gst_segment_to_position (&parse->common.segment,
1933             GST_FORMAT_TIME, earliest_time);
1934
1935         if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
1936             GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
1937             lace_time <= earliest_stream_time) {
1938           /* find index entry (keyframe) <= earliest_stream_time */
1939           GstMatroskaIndex *entry =
1940               gst_util_array_binary_search (stream->index_table->data,
1941               stream->index_table->len, sizeof (GstMatroskaIndex),
1942               (GCompareDataFunc) gst_matroska_index_seek_find,
1943               GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
1944
1945           /* if that entry (keyframe) is after the current the current
1946              buffer, we can skip pushing (and thus decoding) all
1947              buffers until that keyframe. */
1948           if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
1949               entry->time > lace_time) {
1950             GST_LOG_OBJECT (parse, "Skipping lace before late keyframe");
1951             stream->set_discont = TRUE;
1952             goto next_lace;
1953           }
1954         }
1955       }
1956 #if 0
1957       sub = gst_buffer_create_sub (buf,
1958           GST_BUFFER_SIZE (buf) - size, lace_size[n]);
1959       GST_DEBUG_OBJECT (parse, "created subbuffer %p", sub);
1960
1961       if (delta_unit)
1962         GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1963       else
1964         GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
1965
1966       if (stream->encodings != NULL && stream->encodings->len > 0)
1967         sub = gst_matroska_decode_buffer (stream, sub);
1968
1969       if (sub == NULL) {
1970         GST_WARNING_OBJECT (parse, "Decoding buffer failed");
1971         goto next_lace;
1972       }
1973
1974       GST_BUFFER_TIMESTAMP (sub) = lace_time;
1975
1976       if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
1977         GstClockTime last_stop_end;
1978
1979         /* Check if this stream is after segment stop */
1980         if (GST_CLOCK_TIME_IS_VALID (parse->common.segment.stop) &&
1981             lace_time >= parse->common.segment.stop) {
1982           GST_DEBUG_OBJECT (parse,
1983               "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
1984               GST_TIME_ARGS (parse->common.segment.stop));
1985           gst_buffer_unref (sub);
1986           goto eos;
1987         }
1988         if (offset >= stream->to_offset) {
1989           GST_DEBUG_OBJECT (parse, "Stream %d after playback section",
1990               stream->index);
1991           gst_buffer_unref (sub);
1992           goto eos;
1993         }
1994
1995         /* handle gaps, e.g. non-zero start-time, or an cue index entry
1996          * that landed us with timestamps not quite intended */
1997         if (GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop) &&
1998             parse->segment.rate > 0.0) {
1999           GstClockTimeDiff diff;
2000
2001           /* only send newsegments with increasing start times,
2002            * otherwise if these go back and forth downstream (sinks) increase
2003            * accumulated time and running_time */
2004           diff = GST_CLOCK_DIFF (parse->segment.last_stop, lace_time);
2005           if (diff > 2 * GST_SECOND && lace_time > parse->segment.start &&
2006               (!GST_CLOCK_TIME_IS_VALID (parse->segment.stop) ||
2007                   lace_time < parse->segment.stop)) {
2008             GST_DEBUG_OBJECT (parse,
2009                 "Gap of %" G_GINT64_FORMAT " ns detected in"
2010                 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
2011                 "Sending updated NEWSEGMENT events", diff,
2012                 stream->index, GST_TIME_ARGS (stream->pos),
2013                 GST_TIME_ARGS (lace_time));
2014             /* send newsegment events such that the gap is not accounted in
2015              * accum time, hence running_time */
2016             /* close ahead of gap */
2017             gst_matroska_parse_send_event (parse,
2018                 gst_event_new_new_segment (TRUE, parse->segment.rate,
2019                     parse->segment.format, parse->segment.last_stop,
2020                     parse->segment.last_stop, parse->segment.last_stop));
2021             /* skip gap */
2022             gst_matroska_parse_send_event (parse,
2023                 gst_event_new_new_segment (FALSE, parse->segment.rate,
2024                     parse->segment.format, lace_time, parse->segment.stop,
2025                     lace_time));
2026             /* align segment view with downstream,
2027              * prevents double-counting accum when closing segment */
2028             gst_segment_set_newsegment (&parse->segment, FALSE,
2029                 parse->segment.rate, parse->segment.format, lace_time,
2030                 parse->segment.stop, lace_time);
2031             parse->segment.last_stop = lace_time;
2032           }
2033         }
2034
2035         if (!GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop)
2036             || parse->segment.last_stop < lace_time) {
2037           parse->segment.last_stop = lace_time;
2038         }
2039
2040         last_stop_end = lace_time;
2041         if (duration) {
2042           GST_BUFFER_DURATION (sub) = duration / laces;
2043           last_stop_end += GST_BUFFER_DURATION (sub);
2044         }
2045
2046         if (!GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) ||
2047             parse->last_stop_end < last_stop_end)
2048           parse->last_stop_end = last_stop_end;
2049
2050         if (parse->segment.duration == -1 ||
2051             parse->segment.duration < lace_time) {
2052           gst_segment_set_duration (&parse->segment, GST_FORMAT_TIME,
2053               last_stop_end);
2054           gst_element_post_message (GST_ELEMENT_CAST (parse),
2055               gst_message_new_duration (GST_OBJECT_CAST (parse),
2056                   GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
2057         }
2058       }
2059
2060       stream->pos = lace_time;
2061
2062       gst_matroska_parse_sync_streams (parse);
2063
2064       if (stream->set_discont) {
2065         GST_DEBUG_OBJECT (parse, "marking DISCONT");
2066         GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
2067         stream->set_discont = FALSE;
2068       }
2069
2070       /* reverse playback book-keeping */
2071       if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
2072         stream->from_time = lace_time;
2073       if (stream->from_offset == -1)
2074         stream->from_offset = offset;
2075
2076       GST_DEBUG_OBJECT (parse,
2077           "Pushing lace %d, data of size %d for stream %d, time=%"
2078           GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
2079           GST_BUFFER_SIZE (sub), stream_num,
2080           GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
2081           GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
2082
2083       if (parse->element_index) {
2084         if (stream->index_writer_id == -1)
2085           gst_index_get_writer_id (parse->element_index,
2086               GST_OBJECT (stream->pad), &stream->index_writer_id);
2087
2088         GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
2089             G_GUINT64_FORMAT " for writer id %d",
2090             GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
2091             stream->index_writer_id);
2092         gst_index_add_association (parse->element_index,
2093             stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
2094                 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
2095             GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
2096             cluster_offset, NULL);
2097       }
2098
2099       gst_buffer_set_caps (sub, GST_PAD_CAPS (parse->srcpad));
2100
2101       /* Postprocess the buffers depending on the codec used */
2102       if (stream->postprocess_frame) {
2103         GST_LOG_OBJECT (parse, "running post process");
2104         ret = stream->postprocess_frame (GST_ELEMENT (parse), stream, &sub);
2105       }
2106
2107       ret = gst_pad_push (stream->pad, sub);
2108       if (parse->segment.rate < 0) {
2109         if (lace_time > parse->segment.stop && ret == GST_FLOW_EOS) {
2110           /* In reverse playback we can get a GST_FLOW_EOS when
2111            * we are at the end of the segment, so we just need to jump
2112            * back to the previous section. */
2113           GST_DEBUG_OBJECT (parse, "downstream has reached end of segment");
2114           ret = GST_FLOW_OK;
2115         }
2116       }
2117       /* combine flows */
2118       ret = gst_matroska_parse_combine_flows (parse, stream, ret);
2119 #endif
2120
2121     next_lace:
2122       size -= lace_size[n];
2123       if (lace_time != GST_CLOCK_TIME_NONE && duration)
2124         lace_time += duration / laces;
2125       else
2126         lace_time = GST_CLOCK_TIME_NONE;
2127     }
2128   }
2129
2130 done:
2131   if (buf) {
2132     gst_buffer_unmap (buf, &map);
2133     gst_buffer_unref (buf);
2134   }
2135   g_free (lace_size);
2136
2137   return ret;
2138
2139   /* EXITS */
2140 invalid_lacing:
2141   {
2142     GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
2143     /* non-fatal, try next block(group) */
2144     ret = GST_FLOW_OK;
2145     goto done;
2146   }
2147 data_error:
2148   {
2149     GST_ELEMENT_WARNING (parse, STREAM, DEMUX, (NULL), ("Data error"));
2150     /* non-fatal, try next block(group) */
2151     ret = GST_FLOW_OK;
2152     goto done;
2153   }
2154 }
2155
2156 /* return FALSE if block(group) should be skipped (due to a seek) */
2157 static inline gboolean
2158 gst_matroska_parse_seek_block (GstMatroskaParse * parse)
2159 {
2160   if (G_UNLIKELY (parse->seek_block)) {
2161     if (!(--parse->seek_block)) {
2162       return TRUE;
2163     } else {
2164       GST_LOG_OBJECT (parse, "should skip block due to seek");
2165       return FALSE;
2166     }
2167   } else {
2168     return TRUE;
2169   }
2170 }
2171
2172 static GstFlowReturn
2173 gst_matroska_parse_parse_contents_seekentry (GstMatroskaParse * parse,
2174     GstEbmlRead * ebml)
2175 {
2176   GstFlowReturn ret;
2177   guint64 seek_pos = (guint64) - 1;
2178   guint32 seek_id = 0;
2179   guint32 id;
2180
2181   DEBUG_ELEMENT_START (parse, ebml, "Seek");
2182
2183   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2184     DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2185     return ret;
2186   }
2187
2188   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2189     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2190       break;
2191
2192     switch (id) {
2193       case GST_MATROSKA_ID_SEEKID:
2194       {
2195         guint64 t;
2196
2197         if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2198           break;
2199
2200         GST_DEBUG_OBJECT (parse, "SeekID: %" G_GUINT64_FORMAT, t);
2201         seek_id = t;
2202         break;
2203       }
2204
2205       case GST_MATROSKA_ID_SEEKPOSITION:
2206       {
2207         guint64 t;
2208
2209         if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
2210           break;
2211
2212         if (t > G_MAXINT64) {
2213           GST_WARNING_OBJECT (parse,
2214               "Too large SeekPosition %" G_GUINT64_FORMAT, t);
2215           break;
2216         }
2217
2218         GST_DEBUG_OBJECT (parse, "SeekPosition: %" G_GUINT64_FORMAT, t);
2219         seek_pos = t;
2220         break;
2221       }
2222
2223       default:
2224         ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2225             "SeekHead", id);
2226         break;
2227     }
2228   }
2229
2230   if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
2231     return ret;
2232
2233   if (!seek_id || seek_pos == (guint64) - 1) {
2234     GST_WARNING_OBJECT (parse, "Incomplete seekhead entry (0x%x/%"
2235         G_GUINT64_FORMAT ")", seek_id, seek_pos);
2236     return GST_FLOW_OK;
2237   }
2238
2239   switch (seek_id) {
2240     case GST_MATROSKA_ID_SEEKHEAD:
2241     {
2242     }
2243     case GST_MATROSKA_ID_CUES:
2244     case GST_MATROSKA_ID_TAGS:
2245     case GST_MATROSKA_ID_TRACKS:
2246     case GST_MATROSKA_ID_SEGMENTINFO:
2247     case GST_MATROSKA_ID_ATTACHMENTS:
2248     case GST_MATROSKA_ID_CHAPTERS:
2249     {
2250       guint64 length;
2251
2252       /* remember */
2253       length = gst_matroska_read_common_get_length (&parse->common);
2254
2255       if (length == (guint64) - 1) {
2256         GST_DEBUG_OBJECT (parse, "no upstream length, skipping SeakHead entry");
2257         break;
2258       }
2259
2260       /* check for validity */
2261       if (seek_pos + parse->common.ebml_segment_start + 12 >= length) {
2262         GST_WARNING_OBJECT (parse,
2263             "SeekHead reference lies outside file!" " (%"
2264             G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
2265             G_GUINT64_FORMAT ")", seek_pos, parse->common.ebml_segment_start,
2266             length);
2267         break;
2268       }
2269
2270       /* only pick up index location when streaming */
2271       if (seek_id == GST_MATROSKA_ID_CUES) {
2272         parse->index_offset = seek_pos + parse->common.ebml_segment_start;
2273         GST_DEBUG_OBJECT (parse, "Cues located at offset %" G_GUINT64_FORMAT,
2274             parse->index_offset);
2275       }
2276       break;
2277     }
2278
2279     default:
2280       GST_DEBUG_OBJECT (parse, "Ignoring Seek entry for ID=0x%x", seek_id);
2281       break;
2282   }
2283   DEBUG_ELEMENT_STOP (parse, ebml, "Seek", ret);
2284
2285   return ret;
2286 }
2287
2288 static GstFlowReturn
2289 gst_matroska_parse_parse_contents (GstMatroskaParse * parse, GstEbmlRead * ebml)
2290 {
2291   GstFlowReturn ret = GST_FLOW_OK;
2292   guint32 id;
2293
2294   DEBUG_ELEMENT_START (parse, ebml, "SeekHead");
2295
2296   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
2297     DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2298     return ret;
2299   }
2300
2301   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
2302     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
2303       break;
2304
2305     switch (id) {
2306       case GST_MATROSKA_ID_SEEKENTRY:
2307       {
2308         ret = gst_matroska_parse_parse_contents_seekentry (parse, ebml);
2309         /* Ignore EOS and errors here */
2310         if (ret != GST_FLOW_OK) {
2311           GST_DEBUG_OBJECT (parse, "Ignoring %s", gst_flow_get_name (ret));
2312           ret = GST_FLOW_OK;
2313         }
2314         break;
2315       }
2316
2317       default:
2318         ret = gst_matroska_read_common_parse_skip (&parse->common, ebml,
2319             "SeekHead", id);
2320         break;
2321     }
2322   }
2323
2324   DEBUG_ELEMENT_STOP (parse, ebml, "SeekHead", ret);
2325
2326   return ret;
2327 }
2328
2329 #define GST_FLOW_OVERFLOW   GST_FLOW_CUSTOM_ERROR
2330
2331 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
2332
2333 static inline GstFlowReturn
2334 gst_matroska_parse_check_read_size (GstMatroskaParse * parse, guint64 bytes)
2335 {
2336   if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
2337     /* only a few blocks are expected/allowed to be large,
2338      * and will be recursed into, whereas others will be read and must fit */
2339     /* fatal in streaming case, as we can't step over easily */
2340     GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2341         ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
2342             "file might be corrupt.", bytes));
2343     return GST_FLOW_ERROR;
2344   } else {
2345     return GST_FLOW_OK;
2346   }
2347 }
2348
2349 /* returns TRUE if we truely are in error state, and should give up */
2350 static inline gboolean
2351 gst_matroska_parse_check_parse_error (GstMatroskaParse * parse)
2352 {
2353   gint64 pos;
2354
2355   /* sigh, one last attempt above and beyond call of duty ...;
2356    * search for cluster mark following current pos */
2357   pos = parse->common.offset;
2358   GST_WARNING_OBJECT (parse, "parse error, looking for next cluster");
2359   if (gst_matroska_parse_search_cluster (parse, &pos) != GST_FLOW_OK) {
2360     /* did not work, give up */
2361     return TRUE;
2362   } else {
2363     GST_DEBUG_OBJECT (parse, "... found at  %" G_GUINT64_FORMAT, pos);
2364     /* try that position */
2365     parse->common.offset = pos;
2366     return FALSE;
2367   }
2368 }
2369
2370 /* initializes @ebml with @bytes from input stream at current offset.
2371  * Returns EOS if insufficient available,
2372  * ERROR if too much was attempted to read. */
2373 static inline GstFlowReturn
2374 gst_matroska_parse_take (GstMatroskaParse * parse, guint64 bytes,
2375     GstEbmlRead * ebml)
2376 {
2377   GstBuffer *buffer = NULL;
2378   GstFlowReturn ret = GST_FLOW_OK;
2379
2380   GST_LOG_OBJECT (parse, "taking %" G_GUINT64_FORMAT " bytes for parsing",
2381       bytes);
2382   ret = gst_matroska_parse_check_read_size (parse, bytes);
2383   if (G_UNLIKELY (ret != GST_FLOW_OK)) {
2384     /* otherwise fatal */
2385     ret = GST_FLOW_ERROR;
2386     goto exit;
2387   }
2388   if (gst_adapter_available (parse->common.adapter) >= bytes)
2389     buffer = gst_adapter_take_buffer (parse->common.adapter, bytes);
2390   else
2391     ret = GST_FLOW_EOS;
2392   if (G_LIKELY (buffer)) {
2393     gst_ebml_read_init (ebml, GST_ELEMENT_CAST (parse), buffer,
2394         parse->common.offset);
2395     parse->common.offset += bytes;
2396   }
2397 exit:
2398   return ret;
2399 }
2400
2401 static void
2402 gst_matroska_parse_check_seekability (GstMatroskaParse * parse)
2403 {
2404   GstQuery *query;
2405   gboolean seekable = FALSE;
2406   gint64 start = -1, stop = -1;
2407
2408   query = gst_query_new_seeking (GST_FORMAT_BYTES);
2409   if (!gst_pad_peer_query (parse->common.sinkpad, query)) {
2410     GST_DEBUG_OBJECT (parse, "seeking query failed");
2411     goto done;
2412   }
2413
2414   gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
2415
2416   /* try harder to query upstream size if we didn't get it the first time */
2417   if (seekable && stop == -1) {
2418     GST_DEBUG_OBJECT (parse, "doing duration query to fix up unset stop");
2419     gst_pad_peer_query_duration (parse->common.sinkpad, GST_FORMAT_BYTES,
2420         &stop);
2421   }
2422
2423   /* if upstream doesn't know the size, it's likely that it's not seekable in
2424    * practice even if it technically may be seekable */
2425   if (seekable && (start != 0 || stop <= start)) {
2426     GST_DEBUG_OBJECT (parse, "seekable but unknown start/stop -> disable");
2427     seekable = FALSE;
2428   }
2429
2430 done:
2431   GST_INFO_OBJECT (parse, "seekable: %d (%" G_GUINT64_FORMAT " - %"
2432       G_GUINT64_FORMAT ")", seekable, start, stop);
2433   parse->seekable = seekable;
2434
2435   gst_query_unref (query);
2436 }
2437
2438 #if 0
2439 static GstFlowReturn
2440 gst_matroska_parse_find_tracks (GstMatroskaParse * parse)
2441 {
2442   guint32 id;
2443   guint64 before_pos;
2444   guint64 length;
2445   guint needed;
2446   GstFlowReturn ret = GST_FLOW_OK;
2447
2448   GST_WARNING_OBJECT (parse,
2449       "Found Cluster element before Tracks, searching Tracks");
2450
2451   /* remember */
2452   before_pos = parse->common.offset;
2453
2454   /* Search Tracks element */
2455   while (TRUE) {
2456     ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2457         GST_ELEMENT_CAST (parse), &id, &length, &needed);
2458     if (ret != GST_FLOW_OK)
2459       break;
2460
2461     if (id != GST_MATROSKA_ID_TRACKS) {
2462       /* we may be skipping large cluster here, so forego size check etc */
2463       /* ... but we can't skip undefined size; force error */
2464       if (length == G_MAXUINT64) {
2465         ret = gst_matroska_parse_check_read_size (parse, length);
2466         break;
2467       } else {
2468         parse->common.offset += needed;
2469         parse->offset += length;
2470       }
2471       continue;
2472     }
2473
2474     /* will lead to track parsing ... */
2475     ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2476     break;
2477   }
2478
2479   /* seek back */
2480   parse->offset = before_pos;
2481
2482   return ret;
2483 }
2484 #endif
2485
2486 #define GST_READ_CHECK(stmt)  \
2487 G_STMT_START { \
2488   if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
2489     if (ret == GST_FLOW_OVERFLOW) { \
2490       ret = GST_FLOW_OK; \
2491     } \
2492     goto read_error; \
2493   } \
2494 } G_STMT_END
2495
2496 static void
2497 gst_matroska_parse_accumulate_streamheader (GstMatroskaParse * parse,
2498     GstBuffer * buffer)
2499 {
2500   if (parse->pushed_headers) {
2501     GST_WARNING_OBJECT (parse,
2502         "Accumulating headers, but headers are already pushed");
2503   }
2504
2505   if (parse->streamheader) {
2506     parse->streamheader = gst_buffer_append (parse->streamheader,
2507         gst_buffer_ref (buffer));
2508   } else {
2509     parse->streamheader = gst_buffer_ref (buffer);
2510   }
2511
2512   GST_DEBUG ("%" G_GSIZE_FORMAT, gst_buffer_get_size (parse->streamheader));
2513 }
2514
2515 static GstFlowReturn
2516 gst_matroska_parse_output (GstMatroskaParse * parse, GstBuffer * buffer,
2517     gboolean keyframe)
2518 {
2519   GstFlowReturn ret = GST_FLOW_OK;
2520
2521   if (!parse->pushed_headers) {
2522     GstCaps *caps;
2523     GstStructure *s;
2524     GValue streamheader = { 0 };
2525     GValue bufval = { 0 };
2526     GstBuffer *buf;
2527
2528     caps = gst_pad_get_current_caps (parse->common.sinkpad);
2529     /* FIXME: could run typefinding over header and pick better default */
2530     if (caps == NULL)
2531       caps = gst_caps_new_empty_simple ("video/x-matroska");
2532     else
2533       caps = gst_caps_make_writable (caps);
2534
2535     s = gst_caps_get_structure (caps, 0);
2536     g_value_init (&streamheader, GST_TYPE_ARRAY);
2537     g_value_init (&bufval, GST_TYPE_BUFFER);
2538     buf = gst_buffer_copy (parse->streamheader);
2539     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2540     gst_value_set_buffer (&bufval, buf);
2541     gst_buffer_unref (buf);
2542     gst_value_array_append_value (&streamheader, &bufval);
2543     g_value_unset (&bufval);
2544     gst_structure_set_value (s, "streamheader", &streamheader);
2545     g_value_unset (&streamheader);
2546     //gst_caps_replace (parse->caps, caps);
2547     gst_pad_set_caps (parse->srcpad, caps);
2548
2549     buf = gst_buffer_copy (parse->streamheader);
2550     gst_caps_unref (caps);
2551
2552     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2553     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2554     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
2555
2556     ret = gst_pad_push (parse->srcpad, buf);
2557
2558     parse->pushed_headers = TRUE;
2559   }
2560
2561   if (!keyframe) {
2562     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2563   } else {
2564     GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2565   }
2566   if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE) {
2567     parse->last_timestamp = GST_BUFFER_TIMESTAMP (buffer);
2568   } else {
2569     GST_BUFFER_TIMESTAMP (buffer) = parse->last_timestamp;
2570   }
2571   ret = gst_pad_push (parse->srcpad, gst_buffer_ref (buffer));
2572
2573   return ret;
2574 }
2575
2576 static GstFlowReturn
2577 gst_matroska_parse_parse_id (GstMatroskaParse * parse, guint32 id,
2578     guint64 length, guint needed)
2579 {
2580   GstEbmlRead ebml = { 0, };
2581   GstFlowReturn ret = GST_FLOW_OK;
2582   guint64 read;
2583   //GstBuffer *buffer;
2584
2585   GST_DEBUG_OBJECT (parse, "Parsing Element id 0x%x, "
2586       "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
2587
2588 #if 0
2589   if (gst_adapter_available (parse->adapter) >= length + needed) {
2590     buffer = gst_adapter_take_buffer (parse->adapter, length + needed);
2591     gst_pad_push (parse->srcpad, buffer);
2592   } else {
2593     ret = GST_FLOW_EOS;
2594   }
2595   //GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2596
2597   return ret;
2598 #endif
2599
2600
2601
2602   /* if we plan to read and parse this element, we need prefix (id + length)
2603    * and the contents */
2604   /* mind about overflow wrap-around when dealing with undefined size */
2605   read = length;
2606   if (G_LIKELY (length != G_MAXUINT64))
2607     read += needed;
2608
2609   switch (parse->common.state) {
2610     case GST_MATROSKA_READ_STATE_START:
2611       switch (id) {
2612         case GST_EBML_ID_HEADER:
2613           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2614           ret = gst_matroska_read_common_parse_header (&parse->common, &ebml);
2615           if (ret != GST_FLOW_OK)
2616             goto parse_failed;
2617           parse->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
2618           gst_matroska_parse_check_seekability (parse);
2619           gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2620           break;
2621         default:
2622           goto invalid_header;
2623           break;
2624       }
2625       break;
2626     case GST_MATROSKA_READ_STATE_SEGMENT:
2627       switch (id) {
2628         case GST_MATROSKA_ID_SEGMENT:
2629           /* eat segment prefix */
2630           GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2631           GST_DEBUG_OBJECT (parse,
2632               "Found Segment start at offset %" G_GUINT64_FORMAT,
2633               parse->common.offset);
2634           /* seeks are from the beginning of the segment,
2635            * after the segment ID/length */
2636           parse->common.ebml_segment_start = parse->common.offset;
2637           parse->common.state = GST_MATROSKA_READ_STATE_HEADER;
2638           gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2639           break;
2640         default:
2641           GST_WARNING_OBJECT (parse,
2642               "Expected a Segment ID (0x%x), but received 0x%x!",
2643               GST_MATROSKA_ID_SEGMENT, id);
2644           GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2645           gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2646           break;
2647       }
2648       break;
2649     case GST_MATROSKA_READ_STATE_SCANNING:
2650       if (id != GST_MATROSKA_ID_CLUSTER &&
2651           id != GST_MATROSKA_ID_CLUSTERTIMECODE)
2652         goto skip;
2653       /* fall-through */
2654     case GST_MATROSKA_READ_STATE_HEADER:
2655     case GST_MATROSKA_READ_STATE_DATA:
2656     case GST_MATROSKA_READ_STATE_SEEK:
2657       switch (id) {
2658         case GST_MATROSKA_ID_SEGMENTINFO:
2659           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2660           if (!parse->common.segmentinfo_parsed) {
2661             ret = gst_matroska_read_common_parse_info (&parse->common,
2662                 GST_ELEMENT_CAST (parse), &ebml);
2663           }
2664           gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2665           break;
2666         case GST_MATROSKA_ID_TRACKS:
2667           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2668           if (!parse->tracks_parsed) {
2669             ret = gst_matroska_parse_parse_tracks (parse, &ebml);
2670           }
2671           gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2672           break;
2673         case GST_MATROSKA_ID_CLUSTER:
2674           if (G_UNLIKELY (!parse->tracks_parsed)) {
2675             GST_DEBUG_OBJECT (parse, "Cluster before Track");
2676             goto not_streamable;
2677           }
2678           if (G_UNLIKELY (parse->common.state
2679                   == GST_MATROSKA_READ_STATE_HEADER)) {
2680             parse->common.state = GST_MATROSKA_READ_STATE_DATA;
2681             parse->first_cluster_offset = parse->common.offset;
2682             GST_DEBUG_OBJECT (parse, "signaling no more pads");
2683           }
2684           parse->cluster_time = GST_CLOCK_TIME_NONE;
2685           parse->cluster_offset = parse->common.offset;
2686           if (G_UNLIKELY (!parse->seek_first && parse->seek_block)) {
2687             GST_DEBUG_OBJECT (parse, "seek target block %" G_GUINT64_FORMAT
2688                 " not found in Cluster, trying next Cluster's first block instead",
2689                 parse->seek_block);
2690             parse->seek_block = 0;
2691           }
2692           parse->seek_first = FALSE;
2693           /* record next cluster for recovery */
2694           if (read != G_MAXUINT64)
2695             parse->next_cluster_offset = parse->cluster_offset + read;
2696           /* eat cluster prefix */
2697           GST_READ_CHECK (gst_matroska_parse_take (parse, needed, &ebml));
2698           ret = gst_matroska_parse_output (parse, ebml.buf, TRUE);
2699           //gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2700           break;
2701         case GST_MATROSKA_ID_CLUSTERTIMECODE:
2702         {
2703           guint64 num;
2704
2705           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2706           if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
2707             goto parse_failed;
2708           GST_DEBUG_OBJECT (parse, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
2709           parse->cluster_time = num;
2710 #if 0
2711           if (parse->common.element_index) {
2712             if (parse->common.element_index_writer_id == -1)
2713               gst_index_get_writer_id (parse->common.element_index,
2714                   GST_OBJECT (parse), &parse->common.element_index_writer_id);
2715             GST_LOG_OBJECT (parse, "adding association %" GST_TIME_FORMAT "-> %"
2716                 G_GUINT64_FORMAT " for writer id %d",
2717                 GST_TIME_ARGS (parse->cluster_time), parse->cluster_offset,
2718                 parse->common.element_index_writer_id);
2719             gst_index_add_association (parse->common.element_index,
2720                 parse->common.element_index_writer_id,
2721                 GST_ASSOCIATION_FLAG_KEY_UNIT,
2722                 GST_FORMAT_TIME, parse->cluster_time,
2723                 GST_FORMAT_BYTES, parse->cluster_offset, NULL);
2724           }
2725 #endif
2726           gst_matroska_parse_output (parse, ebml.buf, FALSE);
2727           break;
2728         }
2729         case GST_MATROSKA_ID_BLOCKGROUP:
2730           if (!gst_matroska_parse_seek_block (parse))
2731             goto skip;
2732           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2733           DEBUG_ELEMENT_START (parse, &ebml, "BlockGroup");
2734           if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
2735             ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
2736                 &ebml, parse->cluster_time, parse->cluster_offset, FALSE);
2737           }
2738           DEBUG_ELEMENT_STOP (parse, &ebml, "BlockGroup", ret);
2739           gst_matroska_parse_output (parse, ebml.buf, FALSE);
2740           break;
2741         case GST_MATROSKA_ID_SIMPLEBLOCK:
2742           if (!gst_matroska_parse_seek_block (parse))
2743             goto skip;
2744           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2745           DEBUG_ELEMENT_START (parse, &ebml, "SimpleBlock");
2746           ret = gst_matroska_parse_parse_blockgroup_or_simpleblock (parse,
2747               &ebml, parse->cluster_time, parse->cluster_offset, TRUE);
2748           DEBUG_ELEMENT_STOP (parse, &ebml, "SimpleBlock", ret);
2749           gst_matroska_parse_output (parse, ebml.buf, FALSE);
2750           break;
2751         case GST_MATROSKA_ID_ATTACHMENTS:
2752           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2753           if (!parse->common.attachments_parsed) {
2754             ret = gst_matroska_read_common_parse_attachments (&parse->common,
2755                 GST_ELEMENT_CAST (parse), &ebml);
2756           }
2757           gst_matroska_parse_output (parse, ebml.buf, FALSE);
2758           break;
2759         case GST_MATROSKA_ID_TAGS:
2760           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2761           ret = gst_matroska_read_common_parse_metadata (&parse->common,
2762               GST_ELEMENT_CAST (parse), &ebml);
2763           gst_matroska_parse_accumulate_streamheader (parse, ebml.buf);
2764           break;
2765         case GST_MATROSKA_ID_CHAPTERS:
2766           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2767           ret = gst_matroska_read_common_parse_chapters (&parse->common, &ebml);
2768           gst_matroska_parse_output (parse, ebml.buf, FALSE);
2769           break;
2770         case GST_MATROSKA_ID_SEEKHEAD:
2771           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2772           ret = gst_matroska_parse_parse_contents (parse, &ebml);
2773           gst_matroska_parse_output (parse, ebml.buf, FALSE);
2774           break;
2775         case GST_MATROSKA_ID_CUES:
2776           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2777           if (!parse->common.index_parsed) {
2778             ret = gst_matroska_read_common_parse_index (&parse->common, &ebml);
2779             /* only push based; delayed index building */
2780             if (ret == GST_FLOW_OK
2781                 && parse->common.state == GST_MATROSKA_READ_STATE_SEEK) {
2782               GstEvent *event;
2783
2784               GST_OBJECT_LOCK (parse);
2785               event = parse->seek_event;
2786               parse->seek_event = NULL;
2787               GST_OBJECT_UNLOCK (parse);
2788
2789               g_assert (event);
2790               /* unlikely to fail, since we managed to seek to this point */
2791               if (!gst_matroska_parse_handle_seek_event (parse, NULL, event))
2792                 goto seek_failed;
2793               /* resume data handling, main thread clear to seek again */
2794               GST_OBJECT_LOCK (parse);
2795               parse->common.state = GST_MATROSKA_READ_STATE_DATA;
2796               GST_OBJECT_UNLOCK (parse);
2797             }
2798           }
2799           gst_matroska_parse_output (parse, ebml.buf, FALSE);
2800           break;
2801         case GST_MATROSKA_ID_POSITION:
2802         case GST_MATROSKA_ID_PREVSIZE:
2803         case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
2804         case GST_MATROSKA_ID_SILENTTRACKS:
2805           GST_DEBUG_OBJECT (parse,
2806               "Skipping Cluster subelement 0x%x - ignoring", id);
2807           /* fall-through */
2808         default:
2809         skip:
2810           GST_DEBUG_OBJECT (parse, "skipping Element 0x%x", id);
2811           GST_READ_CHECK (gst_matroska_parse_take (parse, read, &ebml));
2812           gst_matroska_parse_output (parse, ebml.buf, FALSE);
2813           break;
2814       }
2815       break;
2816   }
2817
2818   if (ret == GST_FLOW_PARSE)
2819     goto parse_failed;
2820
2821 exit:
2822   gst_ebml_read_clear (&ebml);
2823   return ret;
2824
2825   /* ERRORS */
2826 read_error:
2827   {
2828     /* simply exit, maybe not enough data yet */
2829     /* no ebml to clear if read error */
2830     return ret;
2831   }
2832 parse_failed:
2833   {
2834     GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2835         ("Failed to parse Element 0x%x", id));
2836     ret = GST_FLOW_ERROR;
2837     goto exit;
2838   }
2839 not_streamable:
2840   {
2841     GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2842         ("File layout does not permit streaming"));
2843     ret = GST_FLOW_ERROR;
2844     goto exit;
2845   }
2846 #if 0
2847 no_tracks:
2848   {
2849     GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL),
2850         ("No Tracks element found"));
2851     ret = GST_FLOW_ERROR;
2852     goto exit;
2853   }
2854 #endif
2855 invalid_header:
2856   {
2857     GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Invalid header"));
2858     ret = GST_FLOW_ERROR;
2859     goto exit;
2860   }
2861 seek_failed:
2862   {
2863     GST_ELEMENT_ERROR (parse, STREAM, DEMUX, (NULL), ("Failed to seek"));
2864     ret = GST_FLOW_ERROR;
2865     goto exit;
2866   }
2867 }
2868
2869 #if 0
2870 static void
2871 gst_matroska_parse_loop (GstPad * pad)
2872 {
2873   GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
2874   GstFlowReturn ret;
2875   guint32 id;
2876   guint64 length;
2877   guint needed;
2878
2879   /* If we have to close a segment, send a new segment to do this now */
2880   if (G_LIKELY (parse->common.state == GST_MATROSKA_READ_STATE_DATA)) {
2881     if (G_UNLIKELY (parse->close_segment)) {
2882       gst_matroska_parse_send_event (parse, parse->close_segment);
2883       parse->close_segment = NULL;
2884     }
2885     if (G_UNLIKELY (parse->new_segment)) {
2886       gst_matroska_parse_send_event (parse, parse->new_segment);
2887       parse->new_segment = NULL;
2888     }
2889   }
2890
2891   ret = gst_matroska_read_common_peek_id_length_pull (&parse->common,
2892       GST_ELEMENT_CAST (parse), &id, &length, &needed);
2893   if (ret == GST_FLOW_EOS)
2894     goto eos;
2895   if (ret != GST_FLOW_OK) {
2896     if (gst_matroska_parse_check_parse_error (parse))
2897       goto pause;
2898     else
2899       return;
2900   }
2901
2902   GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2903       "size %" G_GUINT64_FORMAT ", needed %d", parse->offset, id,
2904       length, needed);
2905
2906   ret = gst_matroska_parse_parse_id (parse, id, length, needed);
2907   if (ret == GST_FLOW_EOS)
2908     goto eos;
2909   if (ret != GST_FLOW_OK)
2910     goto pause;
2911
2912   /* check if we're at the end of a configured segment */
2913   if (G_LIKELY (parse->src->len)) {
2914     guint i;
2915
2916     g_assert (parse->num_streams == parse->src->len);
2917     for (i = 0; i < parse->src->len; i++) {
2918       GstMatroskaTrackContext *context = g_ptr_array_index (parse->src, i);
2919       GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
2920           GST_TIME_ARGS (context->pos));
2921       if (context->eos == FALSE)
2922         goto next;
2923     }
2924
2925     GST_INFO_OBJECT (parse, "All streams are EOS");
2926     ret = GST_FLOW_EOS;
2927     goto eos;
2928   }
2929
2930 next:
2931   if (G_UNLIKELY (parse->offset ==
2932           gst_matroska_read_common_get_length (&parse->common))) {
2933     GST_LOG_OBJECT (parse, "Reached end of stream");
2934     ret = GST_FLOW_EOS;
2935     goto eos;
2936   }
2937
2938   return;
2939
2940   /* ERRORS */
2941 eos:
2942   {
2943     if (parse->segment.rate < 0.0) {
2944       ret = gst_matroska_parse_seek_to_previous_keyframe (parse);
2945       if (ret == GST_FLOW_OK)
2946         return;
2947     }
2948     /* fall-through */
2949   }
2950 pause:
2951   {
2952     const gchar *reason = gst_flow_get_name (ret);
2953     gboolean push_eos = FALSE;
2954
2955     GST_LOG_OBJECT (parse, "pausing task, reason %s", reason);
2956     parse->segment_running = FALSE;
2957     gst_pad_pause_task (parse->common.sinkpad);
2958
2959     if (ret == GST_FLOW_EOS) {
2960       /* perform EOS logic */
2961
2962       /* Close the segment, i.e. update segment stop with the duration
2963        * if no stop was set */
2964       if (GST_CLOCK_TIME_IS_VALID (parse->last_stop_end) &&
2965           !GST_CLOCK_TIME_IS_VALID (parse->segment.stop)) {
2966         GstEvent *event =
2967             gst_event_new_new_segment_full (TRUE, parse->segment.rate,
2968             parse->segment.applied_rate, parse->segment.format,
2969             parse->segment.start,
2970             MAX (parse->last_stop_end, parse->segment.start),
2971             parse->segment.time);
2972         gst_matroska_parse_send_event (parse, event);
2973       }
2974
2975       if (parse->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2976         gint64 stop;
2977
2978         /* for segment playback we need to post when (in stream time)
2979          * we stopped, this is either stop (when set) or the duration. */
2980         if ((stop = parse->segment.stop) == -1)
2981           stop = parse->last_stop_end;
2982
2983         GST_LOG_OBJECT (parse, "Sending segment done, at end of segment");
2984         gst_element_post_message (GST_ELEMENT (parse),
2985             gst_message_new_segment_done (GST_OBJECT (parse), GST_FORMAT_TIME,
2986                 stop));
2987       } else {
2988         push_eos = TRUE;
2989       }
2990     } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
2991       /* for fatal errors we post an error message */
2992       GST_ELEMENT_ERROR (parse, STREAM, FAILED, (NULL),
2993           ("stream stopped, reason %s", reason));
2994       push_eos = TRUE;
2995     }
2996     if (push_eos) {
2997       /* send EOS, and prevent hanging if no streams yet */
2998       GST_LOG_OBJECT (parse, "Sending EOS, at end of stream");
2999       if (!gst_matroska_parse_send_event (parse, gst_event_new_eos ()) &&
3000           (ret == GST_FLOW_EOS)) {
3001         GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3002             (NULL), ("got eos but no streams (yet)"));
3003       }
3004     }
3005     return;
3006   }
3007 }
3008 #endif
3009
3010 /*
3011  * Create and push a flushing seek event upstream
3012  */
3013 static gboolean
3014 perform_seek_to_offset (GstMatroskaParse * parse, guint64 offset)
3015 {
3016   GstEvent *event;
3017   gboolean res = 0;
3018
3019   GST_DEBUG_OBJECT (parse, "Seeking to %" G_GUINT64_FORMAT, offset);
3020
3021   event =
3022       gst_event_new_seek (1.0, GST_FORMAT_BYTES,
3023       GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
3024       GST_SEEK_TYPE_NONE, -1);
3025
3026   res = gst_pad_push_event (parse->common.sinkpad, event);
3027
3028   /* newsegment event will update offset */
3029   return res;
3030 }
3031
3032 static GstFlowReturn
3033 gst_matroska_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
3034 {
3035   GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
3036   guint available;
3037   GstFlowReturn ret = GST_FLOW_OK;
3038   guint needed = 0;
3039   guint32 id;
3040   guint64 length;
3041
3042   if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
3043     GST_DEBUG_OBJECT (parse, "got DISCONT");
3044     gst_adapter_clear (parse->common.adapter);
3045     GST_OBJECT_LOCK (parse);
3046     gst_matroska_read_common_reset_streams (&parse->common,
3047         GST_CLOCK_TIME_NONE, FALSE);
3048     GST_OBJECT_UNLOCK (parse);
3049   }
3050
3051   gst_adapter_push (parse->common.adapter, buffer);
3052   buffer = NULL;
3053
3054 next:
3055   available = gst_adapter_available (parse->common.adapter);
3056
3057   ret = gst_matroska_read_common_peek_id_length_push (&parse->common,
3058       GST_ELEMENT_CAST (parse), &id, &length, &needed);
3059   if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS))
3060     return ret;
3061
3062   GST_LOG_OBJECT (parse, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
3063       "size %" G_GUINT64_FORMAT ", needed %d, available %d",
3064       parse->common.offset, id, length, needed, available);
3065
3066   if (needed > available)
3067     return GST_FLOW_OK;
3068
3069   ret = gst_matroska_parse_parse_id (parse, id, length, needed);
3070   if (ret == GST_FLOW_EOS) {
3071     /* need more data */
3072     return GST_FLOW_OK;
3073   } else if (ret != GST_FLOW_OK) {
3074     return ret;
3075   } else
3076     goto next;
3077 }
3078
3079 static gboolean
3080 gst_matroska_parse_handle_sink_event (GstPad * pad, GstObject * parent,
3081     GstEvent * event)
3082 {
3083   gboolean res = TRUE;
3084   GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
3085
3086   GST_DEBUG_OBJECT (parse,
3087       "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
3088
3089   switch (GST_EVENT_TYPE (event)) {
3090     case GST_EVENT_SEGMENT:
3091     {
3092       const GstSegment *segment;
3093
3094       /* some debug output */
3095       gst_event_parse_segment (event, &segment);
3096       GST_DEBUG_OBJECT (parse,
3097           "received format %d newsegment %" GST_SEGMENT_FORMAT,
3098           segment->format, segment);
3099
3100       if (parse->common.state < GST_MATROSKA_READ_STATE_DATA) {
3101         GST_DEBUG_OBJECT (parse, "still starting");
3102         goto exit;
3103       }
3104
3105       /* we only expect a BYTE segment, e.g. following a seek */
3106       if (segment->format != GST_FORMAT_BYTES) {
3107         GST_DEBUG_OBJECT (parse, "unsupported segment format, ignoring");
3108         goto exit;
3109       }
3110
3111       GST_DEBUG_OBJECT (parse, "clearing segment state");
3112       /* clear current segment leftover */
3113       gst_adapter_clear (parse->common.adapter);
3114       /* and some streaming setup */
3115       parse->common.offset = segment->start;
3116       /* do not know where we are;
3117        * need to come across a cluster and generate newsegment */
3118       parse->common.segment.position = GST_CLOCK_TIME_NONE;
3119       parse->cluster_time = GST_CLOCK_TIME_NONE;
3120       parse->cluster_offset = 0;
3121       parse->need_newsegment = TRUE;
3122       /* but keep some of the upstream segment */
3123       parse->common.segment.rate = segment->rate;
3124     exit:
3125       /* chain will send initial newsegment after pads have been added,
3126        * or otherwise come up with one */
3127       GST_DEBUG_OBJECT (parse, "eating event");
3128       gst_event_unref (event);
3129       res = TRUE;
3130       break;
3131     }
3132     case GST_EVENT_EOS:
3133     {
3134       if (parse->common.state != GST_MATROSKA_READ_STATE_DATA) {
3135         gst_event_unref (event);
3136         GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3137             (NULL), ("got eos and didn't receive a complete header object"));
3138       } else if (parse->common.num_streams == 0) {
3139         GST_ELEMENT_ERROR (parse, STREAM, DEMUX,
3140             (NULL), ("got eos but no streams (yet)"));
3141       } else {
3142         gst_matroska_parse_send_event (parse, event);
3143       }
3144       break;
3145     }
3146     case GST_EVENT_FLUSH_STOP:
3147     {
3148       gst_adapter_clear (parse->common.adapter);
3149       GST_OBJECT_LOCK (parse);
3150       gst_matroska_read_common_reset_streams (&parse->common,
3151           GST_CLOCK_TIME_NONE, TRUE);
3152       GST_OBJECT_UNLOCK (parse);
3153       parse->common.segment.position = GST_CLOCK_TIME_NONE;
3154       parse->cluster_time = GST_CLOCK_TIME_NONE;
3155       parse->cluster_offset = 0;
3156       /* fall-through */
3157     }
3158     default:
3159       res = gst_pad_event_default (pad, parent, event);
3160       break;
3161   }
3162
3163   return res;
3164 }
3165
3166 #if 0
3167 static void
3168 gst_matroska_parse_set_index (GstElement * element, GstIndex * index)
3169 {
3170   GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3171
3172   GST_OBJECT_LOCK (parse);
3173   if (parse->common.element_index)
3174     gst_object_unref (parse->common.element_index);
3175   parse->common.element_index = index ? gst_object_ref (index) : NULL;
3176   GST_OBJECT_UNLOCK (parse);
3177   GST_DEBUG_OBJECT (parse, "Set index %" GST_PTR_FORMAT,
3178       parse->common.element_index);
3179 }
3180
3181 static GstIndex *
3182 gst_matroska_parse_get_index (GstElement * element)
3183 {
3184   GstIndex *result = NULL;
3185   GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3186
3187   GST_OBJECT_LOCK (parse);
3188   if (parse->common.element_index)
3189     result = gst_object_ref (parse->common.element_index);
3190   GST_OBJECT_UNLOCK (parse);
3191
3192   GST_DEBUG_OBJECT (parse, "Returning index %" GST_PTR_FORMAT, result);
3193
3194   return result;
3195 }
3196 #endif
3197
3198 static GstStateChangeReturn
3199 gst_matroska_parse_change_state (GstElement * element,
3200     GstStateChange transition)
3201 {
3202   GstMatroskaParse *parse = GST_MATROSKA_PARSE (element);
3203   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
3204
3205   /* handle upwards state changes here */
3206   switch (transition) {
3207     default:
3208       break;
3209   }
3210
3211   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
3212
3213   /* handle downwards state changes */
3214   switch (transition) {
3215     case GST_STATE_CHANGE_PAUSED_TO_READY:
3216       gst_matroska_parse_reset (GST_ELEMENT (parse));
3217       break;
3218     default:
3219       break;
3220   }
3221
3222   return ret;
3223 }
3224
3225 gboolean
3226 gst_matroska_parse_plugin_init (GstPlugin * plugin)
3227 {
3228   gst_riff_init ();
3229
3230   /* create an elementfactory for the matroska_parse element */
3231   if (!gst_element_register (plugin, "matroskaparse",
3232           GST_RANK_NONE, GST_TYPE_MATROSKA_PARSE))
3233     return FALSE;
3234
3235   return TRUE;
3236 }