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