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