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