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