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