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