upload tizen1.0 source
[framework/multimedia/gst-plugins-good0.10.git] / gst / matroska / matroska-demux.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  *
6  * matroska-demux.c: matroska file/stream demuxer
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 /* TODO: check CRC32 if present
25  * TODO: there can be a segment after the first segment. Handle like
26  *       chained oggs. Fixes #334082
27  * TODO: Test samples: http://www.matroska.org/samples/matrix/index.html
28  *                     http://samples.mplayerhq.hu/Matroska/
29  * TODO: check if demuxing is done correct for all codecs according to spec
30  * TODO: seeking with incomplete or without CUE
31  */
32
33 /**
34  * SECTION:element-matroskademux
35  *
36  * matroskademux demuxes a Matroska file into the different contained streams.
37  *
38  * <refsect2>
39  * <title>Example launch line</title>
40  * |[
41  * gst-launch -v filesrc location=/path/to/mkv ! matroskademux ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
42  * ]| This pipeline demuxes a Matroska file and outputs the contained Vorbis audio.
43  * </refsect2>
44  */
45
46
47 #ifdef HAVE_CONFIG_H
48 #include "config.h"
49 #endif
50
51 #include <math.h>
52 #include <string.h>
53 #include <glib/gprintf.h>
54
55 /* For AVI compatibility mode
56    and for fourcc stuff */
57 #include <gst/riff/riff-read.h>
58 #include <gst/riff/riff-ids.h>
59 #include <gst/riff/riff-media.h>
60
61 #include <gst/tag/tag.h>
62
63 #include <gst/base/gsttypefindhelper.h>
64
65 #ifdef HAVE_ZLIB
66 #include <zlib.h>
67 #endif
68
69 #ifdef HAVE_BZ2
70 #include <bzlib.h>
71 #endif
72
73 #include <gst/pbutils/pbutils.h>
74
75 #include "lzo.h"
76
77 #include "matroska-demux.h"
78 #include "matroska-ids.h"
79
80 GST_DEBUG_CATEGORY_STATIC (matroskademux_debug);
81 #define GST_CAT_DEFAULT matroskademux_debug
82
83 #define DEBUG_ELEMENT_START(demux, ebml, element) \
84     GST_DEBUG_OBJECT (demux, "Parsing " element " element at offset %" \
85         G_GUINT64_FORMAT, gst_ebml_read_get_pos (ebml))
86
87 #define DEBUG_ELEMENT_STOP(demux, ebml, element, ret) \
88     GST_DEBUG_OBJECT (demux, "Parsing " element " element " \
89         " finished with '%s'", gst_flow_get_name (ret))
90
91 enum
92 {
93   ARG_0,
94   ARG_METADATA,
95   ARG_STREAMINFO
96 };
97
98 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
99     GST_PAD_SINK,
100     GST_PAD_ALWAYS,
101     GST_STATIC_CAPS ("video/x-matroska; video/webm")
102     );
103
104 /* TODO: fill in caps! */
105
106 static GstStaticPadTemplate audio_src_templ =
107 GST_STATIC_PAD_TEMPLATE ("audio_%02d",
108     GST_PAD_SRC,
109     GST_PAD_SOMETIMES,
110     GST_STATIC_CAPS ("ANY")
111     );
112
113 static GstStaticPadTemplate video_src_templ =
114 GST_STATIC_PAD_TEMPLATE ("video_%02d",
115     GST_PAD_SRC,
116     GST_PAD_SOMETIMES,
117     GST_STATIC_CAPS ("ANY")
118     );
119
120 static GstStaticPadTemplate subtitle_src_templ =
121     GST_STATIC_PAD_TEMPLATE ("subtitle_%02d",
122     GST_PAD_SRC,
123     GST_PAD_SOMETIMES,
124     GST_STATIC_CAPS ("text/plain; application/x-ssa; application/x-ass; "
125         "application/x-usf; video/x-dvd-subpicture; "
126         "subpicture/x-pgs; subtitle/x-kate; " "application/x-subtitle-unknown")
127     );
128
129 static GstFlowReturn gst_matroska_demux_parse_id (GstMatroskaDemux * demux,
130     guint32 id, guint64 length, guint needed);
131
132 /* element functions */
133 static void gst_matroska_demux_loop (GstPad * pad);
134
135 static gboolean gst_matroska_demux_element_send_event (GstElement * element,
136     GstEvent * event);
137 static gboolean gst_matroska_demux_element_query (GstElement * element,
138     GstQuery * query);
139
140 /* pad functions */
141 static gboolean gst_matroska_demux_sink_activate_pull (GstPad * sinkpad,
142     gboolean active);
143 static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad);
144
145 static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
146     GstPad * pad, GstEvent * event);
147 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
148     GstEvent * event);
149 static const GstQueryType *gst_matroska_demux_get_src_query_types (GstPad *
150     pad);
151 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
152     GstQuery * query);
153
154 static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
155     GstEvent * event);
156 static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
157     GstBuffer * buffer);
158
159 static GstStateChangeReturn
160 gst_matroska_demux_change_state (GstElement * element,
161     GstStateChange transition);
162 static void
163 gst_matroska_demux_set_index (GstElement * element, GstIndex * index);
164 static GstIndex *gst_matroska_demux_get_index (GstElement * element);
165
166 /* caps functions */
167 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
168     * videocontext, const gchar * codec_id, guint8 * data, guint size,
169     gchar ** codec_name, guint32 * riff_fourcc);
170 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
171     * audiocontext, const gchar * codec_id, guint8 * data, guint size,
172     gchar ** codec_name, guint16 * riff_audio_fmt);
173 static GstCaps
174     * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
175     subtitlecontext, const gchar * codec_id, gpointer data, guint size);
176
177 /* stream methods */
178 static void gst_matroska_demux_reset (GstElement * element);
179 static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
180     guint64 offset);
181
182 #ifdef MKVDEMUX_MODIFICATION
183 static GstFlowReturn gst_sec_matroska_demux_find_tracks (GstMatroskaDemux * demux);
184 static GstFlowReturn gst_sec_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id, guint64 length, guint needed);
185 static GstFlowReturn gst_sec_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux, GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset, gboolean is_simpleblock);
186 static gint32 gst_sec_matroska_nframes2show_bw_keyframes (GstMatroskaDemux* demux, GstMatroskaTrackContext * stream);
187 static GstFlowReturn gst_sec_matroska_forward_trickplay (GstMatroskaDemux* demux, GstMatroskaTrackContext * stream, GstBuffer *buffer, gboolean *skip);
188 #endif
189
190 GType gst_matroska_demux_get_type (void);
191 GST_BOILERPLATE (GstMatroskaDemux, gst_matroska_demux, GstElement,
192     GST_TYPE_ELEMENT);
193
194 static void
195 gst_matroska_demux_base_init (gpointer klass)
196 {
197   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
198
199   gst_element_class_add_pad_template (element_class,
200       gst_static_pad_template_get (&video_src_templ));
201   gst_element_class_add_pad_template (element_class,
202       gst_static_pad_template_get (&audio_src_templ));
203   gst_element_class_add_pad_template (element_class,
204       gst_static_pad_template_get (&subtitle_src_templ));
205   gst_element_class_add_pad_template (element_class,
206       gst_static_pad_template_get (&sink_templ));
207
208   gst_element_class_set_details_simple (element_class, "Matroska demuxer",
209       "Codec/Demuxer",
210       "Demuxes Matroska/WebM streams into video/audio/subtitles",
211       "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
212 }
213
214 static void
215 gst_matroska_demux_finalize (GObject * object)
216 {
217   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (object);
218
219   if (demux->src) {
220     g_ptr_array_free (demux->src, TRUE);
221     demux->src = NULL;
222   }
223
224   if (demux->global_tags) {
225     gst_tag_list_free (demux->global_tags);
226     demux->global_tags = NULL;
227   }
228
229   g_object_unref (demux->adapter);
230
231   G_OBJECT_CLASS (parent_class)->finalize (object);
232 }
233
234 static void
235 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
236 {
237   GObjectClass *gobject_class = (GObjectClass *) klass;
238   GstElementClass *gstelement_class = (GstElementClass *) klass;
239
240   /* parser helper separate debug */
241   GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
242       0, "EBML stream helper class");
243
244   GST_DEBUG_CATEGORY_INIT (matroskademux_debug, "matroskademux", 0,
245       "Matroska demuxer");
246
247   gobject_class->finalize = gst_matroska_demux_finalize;
248
249   gstelement_class->change_state =
250       GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
251   gstelement_class->send_event =
252       GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event);
253   gstelement_class->query =
254       GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query);
255
256   gstelement_class->set_index =
257       GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
258   gstelement_class->get_index =
259       GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
260 }
261
262 static void
263 gst_matroska_demux_init (GstMatroskaDemux * demux,
264     GstMatroskaDemuxClass * klass)
265 {
266   demux->sinkpad = gst_pad_new_from_static_template (&sink_templ, "sink");
267   gst_pad_set_activate_function (demux->sinkpad,
268       GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
269   gst_pad_set_activatepull_function (demux->sinkpad,
270       GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_pull));
271   gst_pad_set_chain_function (demux->sinkpad,
272       GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
273   gst_pad_set_event_function (demux->sinkpad,
274       GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_sink_event));
275   gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);
276
277   /* initial stream no. */
278   demux->src = NULL;
279
280   demux->writing_app = NULL;
281   demux->muxing_app = NULL;
282   demux->index = NULL;
283   demux->global_tags = NULL;
284
285   demux->adapter = gst_adapter_new ();
286
287 #ifdef MKVDEMUX_MODIFICATION
288   demux->found_videokeyframe = FALSE;
289   demux->found_audioframe = FALSE;
290 #endif
291
292   /* finish off */
293   gst_matroska_demux_reset (GST_ELEMENT (demux));
294 }
295
296 static void
297 gst_matroska_track_free (GstMatroskaTrackContext * track)
298 {
299   g_free (track->codec_id);
300   g_free (track->codec_name);
301   g_free (track->name);
302   g_free (track->language);
303   g_free (track->codec_priv);
304   g_free (track->codec_state);
305
306 #ifdef MKVDEMUX_MODIFICATION
307   while (!g_queue_is_empty (track->queue)) {
308         GstBuffer* buf = g_queue_pop_head (track->queue);
309         gst_buffer_unref (buf);
310   } 
311   g_queue_free (track->queue);
312 #endif
313
314   if (track->encodings != NULL) {
315     int i;
316
317     for (i = 0; i < track->encodings->len; ++i) {
318       GstMatroskaTrackEncoding *enc = &g_array_index (track->encodings,
319           GstMatroskaTrackEncoding,
320           i);
321
322       g_free (enc->comp_settings);
323     }
324     g_array_free (track->encodings, TRUE);
325   }
326
327   if (track->pending_tags)
328     gst_tag_list_free (track->pending_tags);
329
330   if (track->index_table)
331     g_array_free (track->index_table, TRUE);
332
333   g_free (track);
334 }
335
336 /*
337  * Returns the aggregated GstFlowReturn.
338  */
339 static GstFlowReturn
340 gst_matroska_demux_combine_flows (GstMatroskaDemux * demux,
341     GstMatroskaTrackContext * track, GstFlowReturn ret)
342 {
343   guint i;
344
345   /* store the value */
346   track->last_flow = ret;
347
348   /* any other error that is not-linked can be returned right away */
349   if (ret != GST_FLOW_NOT_LINKED)
350     goto done;
351
352   /* only return NOT_LINKED if all other pads returned NOT_LINKED */
353   g_assert (demux->src->len == demux->num_streams);
354   for (i = 0; i < demux->src->len; i++) {
355     GstMatroskaTrackContext *ostream = g_ptr_array_index (demux->src, i);
356
357     if (ostream == NULL)
358       continue;
359
360     ret = ostream->last_flow;
361     /* some other return value (must be SUCCESS but we can return
362      * other values as well) */
363     if (ret != GST_FLOW_NOT_LINKED)
364       goto done;
365   }
366   /* if we get here, all other pads were unlinked and we return
367    * NOT_LINKED then */
368 done:
369   GST_LOG_OBJECT (demux, "combined return %s", gst_flow_get_name (ret));
370   return ret;
371 }
372
373 static void
374 gst_matroska_demux_free_parsed_el (gpointer mem, gpointer user_data)
375 {
376   g_slice_free (guint64, mem);
377 }
378
379 static void
380 gst_matroska_demux_reset (GstElement * element)
381 {
382   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
383   guint i;
384
385   GST_DEBUG_OBJECT (demux, "Resetting state");
386
387   /* reset input */
388   demux->state = GST_MATROSKA_DEMUX_STATE_START;
389
390   /* clean up existing streams */
391   if (demux->src) {
392     g_assert (demux->src->len == demux->num_streams);
393     for (i = 0; i < demux->src->len; i++) {
394       GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
395
396       if (context->pad != NULL)
397         gst_element_remove_pad (GST_ELEMENT (demux), context->pad);
398
399       gst_caps_replace (&context->caps, NULL);
400       gst_matroska_track_free (context);
401     }
402     g_ptr_array_free (demux->src, TRUE);
403   }
404   demux->src = g_ptr_array_new ();
405
406   demux->num_streams = 0;
407   demux->num_a_streams = 0;
408   demux->num_t_streams = 0;
409   demux->num_v_streams = 0;
410
411   /* reset media info */
412   g_free (demux->writing_app);
413   demux->writing_app = NULL;
414   g_free (demux->muxing_app);
415   demux->muxing_app = NULL;
416
417   /* reset indexes */
418   if (demux->index) {
419     g_array_free (demux->index, TRUE);
420     demux->index = NULL;
421   }
422
423   if (demux->clusters) {
424     g_array_free (demux->clusters, TRUE);
425     demux->clusters = NULL;
426   }
427
428   /* reset timers */
429   demux->clock = NULL;
430   demux->time_scale = 1000000;
431   demux->created = G_MININT64;
432
433   demux->index_parsed = FALSE;
434   demux->tracks_parsed = FALSE;
435   demux->segmentinfo_parsed = FALSE;
436   demux->attachments_parsed = FALSE;
437
438   g_list_foreach (demux->tags_parsed,
439       (GFunc) gst_matroska_demux_free_parsed_el, NULL);
440   g_list_free (demux->tags_parsed);
441   demux->tags_parsed = NULL;
442
443   g_list_foreach (demux->seek_parsed,
444       (GFunc) gst_matroska_demux_free_parsed_el, NULL);
445   g_list_free (demux->seek_parsed);
446   demux->seek_parsed = NULL;
447
448   gst_segment_init (&demux->segment, GST_FORMAT_TIME);
449   demux->last_stop_end = GST_CLOCK_TIME_NONE;
450   demux->seek_block = 0;
451
452   demux->offset = 0;
453   demux->cluster_time = GST_CLOCK_TIME_NONE;
454   demux->cluster_offset = 0;
455   demux->next_cluster_offset = 0;
456   demux->index_offset = 0;
457   demux->seekable = FALSE;
458   demux->need_newsegment = FALSE;
459   demux->building_index = FALSE;
460   if (demux->seek_event) {
461     gst_event_unref (demux->seek_event);
462     demux->seek_event = NULL;
463   }
464
465   demux->seek_index = NULL;
466   demux->seek_entry = 0;
467
468   if (demux->close_segment) {
469     gst_event_unref (demux->close_segment);
470     demux->close_segment = NULL;
471   }
472
473   if (demux->new_segment) {
474     gst_event_unref (demux->new_segment);
475     demux->new_segment = NULL;
476   }
477
478   if (demux->element_index) {
479     gst_object_unref (demux->element_index);
480     demux->element_index = NULL;
481   }
482   demux->element_index_writer_id = -1;
483
484   if (demux->global_tags) {
485     gst_tag_list_free (demux->global_tags);
486   }
487   demux->global_tags = gst_tag_list_new ();
488
489   if (demux->cached_buffer) {
490     gst_buffer_unref (demux->cached_buffer);
491     demux->cached_buffer = NULL;
492   }
493 }
494
495 /*
496  * Calls pull_range for (offset,size) without advancing our offset
497  */
498 static GstFlowReturn
499 gst_matroska_demux_peek_bytes (GstMatroskaDemux * demux, guint64 offset,
500     guint size, GstBuffer ** p_buf, guint8 ** bytes)
501 {
502   GstFlowReturn ret;
503
504   /* Caching here actually makes much less difference than one would expect.
505    * We do it mainly to avoid pulling buffers of 1 byte all the time */
506   if (demux->cached_buffer) {
507     guint64 cache_offset = GST_BUFFER_OFFSET (demux->cached_buffer);
508     guint cache_size = GST_BUFFER_SIZE (demux->cached_buffer);
509
510     if (cache_offset <= demux->offset &&
511         (demux->offset + size) <= (cache_offset + cache_size)) {
512       if (p_buf)
513         *p_buf = gst_buffer_create_sub (demux->cached_buffer,
514             demux->offset - cache_offset, size);
515       if (bytes)
516         *bytes = GST_BUFFER_DATA (demux->cached_buffer) + demux->offset -
517             cache_offset;
518       return GST_FLOW_OK;
519     }
520     /* not enough data in the cache, free cache and get a new one */
521     gst_buffer_unref (demux->cached_buffer);
522     demux->cached_buffer = NULL;
523   }
524
525   /* refill the cache */
526   ret = gst_pad_pull_range (demux->sinkpad, demux->offset,
527       MAX (size, 64 * 1024), &demux->cached_buffer);
528   if (ret != GST_FLOW_OK) {
529     demux->cached_buffer = NULL;
530     return ret;
531   }
532
533   if (GST_BUFFER_SIZE (demux->cached_buffer) >= size) {
534     if (p_buf)
535       *p_buf = gst_buffer_create_sub (demux->cached_buffer, 0, size);
536     if (bytes)
537       *bytes = GST_BUFFER_DATA (demux->cached_buffer);
538     return GST_FLOW_OK;
539   }
540
541   /* Not possible to get enough data, try a last time with
542    * requesting exactly the size we need */
543   gst_buffer_unref (demux->cached_buffer);
544   demux->cached_buffer = NULL;
545
546   ret =
547       gst_pad_pull_range (demux->sinkpad, demux->offset, size,
548       &demux->cached_buffer);
549   if (ret != GST_FLOW_OK) {
550     GST_DEBUG_OBJECT (demux, "pull_range returned %d", ret);
551     if (p_buf)
552       *p_buf = NULL;
553     if (bytes)
554       *bytes = NULL;
555     return ret;
556   }
557
558   if (GST_BUFFER_SIZE (demux->cached_buffer) < size) {
559     GST_WARNING_OBJECT (demux, "Dropping short buffer at offset %"
560         G_GUINT64_FORMAT ": wanted %u bytes, got %u bytes", demux->offset,
561         size, GST_BUFFER_SIZE (demux->cached_buffer));
562
563     gst_buffer_unref (demux->cached_buffer);
564     demux->cached_buffer = NULL;
565     if (p_buf)
566       *p_buf = NULL;
567     if (bytes)
568       *bytes = NULL;
569     return GST_FLOW_UNEXPECTED;
570   }
571
572   if (p_buf)
573     *p_buf = gst_buffer_create_sub (demux->cached_buffer, 0, size);
574   if (bytes)
575     *bytes = GST_BUFFER_DATA (demux->cached_buffer);
576
577   return GST_FLOW_OK;
578 }
579
580 static const guint8 *
581 gst_matroska_demux_peek_pull (GstMatroskaDemux * demux, guint peek)
582 {
583   guint8 *data = NULL;
584
585   gst_matroska_demux_peek_bytes (demux, demux->offset, peek, NULL, &data);
586   return data;
587 }
588
589 static GstFlowReturn
590 gst_matroska_demux_peek_id_length_pull (GstMatroskaDemux * demux, guint32 * _id,
591     guint64 * _length, guint * _needed)
592 {
593   return gst_ebml_peek_id_length (_id, _length, _needed,
594       (GstPeekData) gst_matroska_demux_peek_pull, (gpointer) demux,
595       GST_ELEMENT_CAST (demux), demux->offset);
596 }
597
598 static gint64
599 gst_matroska_demux_get_length (GstMatroskaDemux * demux)
600 {
601   GstFormat fmt = GST_FORMAT_BYTES;
602   gint64 end = -1;
603
604   if (!gst_pad_query_peer_duration (demux->sinkpad, &fmt, &end) ||
605       fmt != GST_FORMAT_BYTES || end < 0)
606     GST_DEBUG_OBJECT (demux, "no upstream length");
607
608   return end;
609 }
610
611 static gint
612 gst_matroska_demux_stream_from_num (GstMatroskaDemux * demux, guint track_num)
613 {
614   guint n;
615
616   g_assert (demux->src->len == demux->num_streams);
617   for (n = 0; n < demux->src->len; n++) {
618     GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, n);
619
620     if (context->num == track_num) {
621       return n;
622     }
623   }
624
625   if (n == demux->num_streams)
626     GST_WARNING_OBJECT (demux,
627         "Failed to find corresponding pad for tracknum %d", track_num);
628
629   return -1;
630 }
631
632 static gint
633 gst_matroska_demux_encoding_cmp (GstMatroskaTrackEncoding * a,
634     GstMatroskaTrackEncoding * b)
635 {
636   if (b->order > a->order)
637     return 1;
638   else if (b->order < a->order)
639     return -1;
640   else
641     return 0;
642 }
643
644 static gboolean
645 gst_matroska_demux_encoding_order_unique (GArray * encodings, guint64 order)
646 {
647   gint i;
648
649   if (encodings == NULL || encodings->len == 0)
650     return TRUE;
651
652   for (i = 0; i < encodings->len; i++)
653     if (g_array_index (encodings, GstMatroskaTrackEncoding, i).order == order)
654       return FALSE;
655
656   return TRUE;
657 }
658
659 static GstFlowReturn
660 gst_matroska_demux_read_track_encoding (GstMatroskaDemux * demux,
661     GstEbmlRead * ebml, GstMatroskaTrackContext * context)
662 {
663   GstMatroskaTrackEncoding enc = { 0, };
664   GstFlowReturn ret;
665   guint32 id;
666
667   DEBUG_ELEMENT_START (demux, ebml, "ContentEncoding");
668   /* Set default values */
669   enc.scope = 1;
670   /* All other default values are 0 */
671
672   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
673     DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncoding", ret);
674     return ret;
675   }
676
677   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
678     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
679       break;
680
681     switch (id) {
682       case GST_MATROSKA_ID_CONTENTENCODINGORDER:{
683         guint64 num;
684
685         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
686           break;
687
688         if (!gst_matroska_demux_encoding_order_unique (context->encodings, num)) {
689           GST_ERROR_OBJECT (demux, "ContentEncodingOrder %" G_GUINT64_FORMAT
690               "is not unique for track %d", num, context->num);
691           ret = GST_FLOW_ERROR;
692           break;
693         }
694
695         GST_DEBUG_OBJECT (demux, "ContentEncodingOrder: %" G_GUINT64_FORMAT,
696             num);
697         enc.order = num;
698         break;
699       }
700       case GST_MATROSKA_ID_CONTENTENCODINGSCOPE:{
701         guint64 num;
702
703         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
704           break;
705
706         if (num > 7 && num == 0) {
707           GST_ERROR_OBJECT (demux, "Invalid ContentEncodingScope %"
708               G_GUINT64_FORMAT, num);
709           ret = GST_FLOW_ERROR;
710           break;
711         }
712
713         GST_DEBUG_OBJECT (demux, "ContentEncodingScope: %" G_GUINT64_FORMAT,
714             num);
715         enc.scope = num;
716
717         break;
718       }
719       case GST_MATROSKA_ID_CONTENTENCODINGTYPE:{
720         guint64 num;
721
722         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
723           break;
724
725         if (num > 1) {
726           GST_ERROR_OBJECT (demux, "Invalid ContentEncodingType %"
727               G_GUINT64_FORMAT, num);
728           ret = GST_FLOW_ERROR;
729           break;
730         } else if (num != 0) {
731           GST_ERROR_OBJECT (demux, "Encrypted tracks are not supported yet");
732           ret = GST_FLOW_ERROR;
733           break;
734         }
735         GST_DEBUG_OBJECT (demux, "ContentEncodingType: %" G_GUINT64_FORMAT,
736             num);
737         enc.type = num;
738         break;
739       }
740       case GST_MATROSKA_ID_CONTENTCOMPRESSION:{
741
742         DEBUG_ELEMENT_START (demux, ebml, "ContentCompression");
743
744         if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
745           break;
746
747         while (ret == GST_FLOW_OK &&
748             gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
749           if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
750             break;
751
752           switch (id) {
753             case GST_MATROSKA_ID_CONTENTCOMPALGO:{
754               guint64 num;
755
756               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK) {
757                 break;
758               }
759               if (num > 3) {
760                 GST_ERROR_OBJECT (demux, "Invalid ContentCompAlgo %"
761                     G_GUINT64_FORMAT, num);
762                 ret = GST_FLOW_ERROR;
763                 break;
764               }
765               GST_DEBUG_OBJECT (demux, "ContentCompAlgo: %" G_GUINT64_FORMAT,
766                   num);
767               enc.comp_algo = num;
768
769               break;
770             }
771             case GST_MATROSKA_ID_CONTENTCOMPSETTINGS:{
772               guint8 *data;
773               guint64 size;
774
775               if ((ret =
776                       gst_ebml_read_binary (ebml, &id, &data,
777                           &size)) != GST_FLOW_OK) {
778                 break;
779               }
780               enc.comp_settings = data;
781               enc.comp_settings_length = size;
782               GST_DEBUG_OBJECT (demux,
783                   "ContentCompSettings of size %" G_GUINT64_FORMAT, size);
784               break;
785             }
786             default:
787               GST_WARNING_OBJECT (demux,
788                   "Unknown ContentCompression subelement 0x%x - ignoring", id);
789               ret = gst_ebml_read_skip (ebml);
790               break;
791           }
792         }
793         DEBUG_ELEMENT_STOP (demux, ebml, "ContentCompression", ret);
794         break;
795       }
796
797       case GST_MATROSKA_ID_CONTENTENCRYPTION:
798         GST_ERROR_OBJECT (demux, "Encrypted tracks not yet supported");
799         gst_ebml_read_skip (ebml);
800         ret = GST_FLOW_ERROR;
801         break;
802       default:
803         GST_WARNING_OBJECT (demux,
804             "Unknown ContentEncoding subelement 0x%x - ignoring", id);
805         ret = gst_ebml_read_skip (ebml);
806         break;
807     }
808   }
809
810   DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncoding", ret);
811   if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
812     return ret;
813
814   /* TODO: Check if the combination of values is valid */
815
816   g_array_append_val (context->encodings, enc);
817
818   return ret;
819 }
820
821 static gboolean
822 gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
823     guint8 ** data_out, guint * size_out,
824     GstMatroskaTrackCompressionAlgorithm algo)
825 {
826   guint8 *new_data = NULL;
827   guint new_size = 0;
828   guint8 *data = *data_out;
829   guint size = *size_out;
830   gboolean ret = TRUE;
831
832   if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_ZLIB) {
833 #ifdef HAVE_ZLIB
834     /* zlib encoded data */
835     z_stream zstream;
836     guint orig_size;
837     int result;
838
839     orig_size = size;
840     zstream.zalloc = (alloc_func) 0;
841     zstream.zfree = (free_func) 0;
842     zstream.opaque = (voidpf) 0;
843     if (inflateInit (&zstream) != Z_OK) {
844       GST_WARNING ("zlib initialization failed.");
845       ret = FALSE;
846       goto out;
847     }
848     zstream.next_in = (Bytef *) data;
849     zstream.avail_in = orig_size;
850     new_size = orig_size;
851     new_data = g_malloc (new_size);
852     zstream.avail_out = new_size;
853     zstream.next_out = (Bytef *) new_data;
854
855     do {
856       result = inflate (&zstream, Z_NO_FLUSH);
857       if (result != Z_OK && result != Z_STREAM_END) {
858         GST_WARNING ("zlib decompression failed.");
859         g_free (new_data);
860         inflateEnd (&zstream);
861         break;
862       }
863       new_size += 4000;
864       new_data = g_realloc (new_data, new_size);
865       zstream.next_out = (Bytef *) (new_data + zstream.total_out);
866       zstream.avail_out += 4000;
867     } while (zstream.avail_in != 0 && result != Z_STREAM_END);
868
869     if (result != Z_STREAM_END) {
870       ret = FALSE;
871       goto out;
872     } else {
873       new_size = zstream.total_out;
874       inflateEnd (&zstream);
875     }
876 #else
877     GST_WARNING ("zlib encoded tracks not supported.");
878     ret = FALSE;
879     goto out;
880 #endif
881   } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_BZLIB) {
882 #ifdef HAVE_BZ2
883     /* bzip2 encoded data */
884     bz_stream bzstream;
885     guint orig_size;
886     int result;
887
888     bzstream.bzalloc = NULL;
889     bzstream.bzfree = NULL;
890     bzstream.opaque = NULL;
891     orig_size = size;
892
893     if (BZ2_bzDecompressInit (&bzstream, 0, 0) != BZ_OK) {
894       GST_WARNING ("bzip2 initialization failed.");
895       ret = FALSE;
896       goto out;
897     }
898
899     bzstream.next_in = (char *) data;
900     bzstream.avail_in = orig_size;
901     new_size = orig_size;
902     new_data = g_malloc (new_size);
903     bzstream.avail_out = new_size;
904     bzstream.next_out = (char *) new_data;
905
906     do {
907       result = BZ2_bzDecompress (&bzstream);
908       if (result != BZ_OK && result != BZ_STREAM_END) {
909         GST_WARNING ("bzip2 decompression failed.");
910         g_free (new_data);
911         BZ2_bzDecompressEnd (&bzstream);
912         break;
913       }
914       new_size += 4000;
915       new_data = g_realloc (new_data, new_size);
916       bzstream.next_out = (char *) (new_data + bzstream.total_out_lo32);
917       bzstream.avail_out += 4000;
918     } while (bzstream.avail_in != 0 && result != BZ_STREAM_END);
919
920     if (result != BZ_STREAM_END) {
921       ret = FALSE;
922       goto out;
923     } else {
924       new_size = bzstream.total_out_lo32;
925       BZ2_bzDecompressEnd (&bzstream);
926     }
927 #else
928     GST_WARNING ("bzip2 encoded tracks not supported.");
929     ret = FALSE;
930     goto out;
931 #endif
932   } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_LZO1X) {
933     /* lzo encoded data */
934     int result;
935     int orig_size, out_size;
936
937     orig_size = size;
938     out_size = size;
939     new_size = size;
940     new_data = g_malloc (new_size);
941
942     do {
943       orig_size = size;
944       out_size = new_size;
945
946       result = lzo1x_decode (new_data, &out_size, data, &orig_size);
947
948       if (orig_size > 0) {
949         new_size += 4000;
950         new_data = g_realloc (new_data, new_size);
951       }
952     } while (orig_size > 0 && result == LZO_OUTPUT_FULL);
953
954     new_size -= out_size;
955
956     if (result != LZO_OUTPUT_FULL) {
957       GST_WARNING ("lzo decompression failed");
958       g_free (new_data);
959
960       ret = FALSE;
961       goto out;
962     }
963
964   } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_HEADERSTRIP) {
965     /* header stripped encoded data */
966     if (enc->comp_settings_length > 0) {
967       new_data = g_malloc (size + enc->comp_settings_length);
968       new_size = size + enc->comp_settings_length;
969
970       memcpy (new_data, enc->comp_settings, enc->comp_settings_length);
971       memcpy (new_data + enc->comp_settings_length, data, size);
972     }
973   } else {
974     GST_ERROR ("invalid compression algorithm %d", algo);
975     ret = FALSE;
976   }
977
978 out:
979
980   if (!ret) {
981     *data_out = NULL;
982     *size_out = 0;
983   } else {
984     *data_out = new_data;
985     *size_out = new_size;
986   }
987
988   return ret;
989 }
990
991 static gboolean
992 gst_matroska_decode_data (GArray * encodings, guint8 ** data_out,
993     guint * size_out, GstMatroskaTrackEncodingScope scope, gboolean free)
994 {
995   guint8 *data;
996   guint size;
997   gboolean ret = TRUE;
998   gint i;
999
1000   g_return_val_if_fail (encodings != NULL, FALSE);
1001   g_return_val_if_fail (data_out != NULL && *data_out != NULL, FALSE);
1002   g_return_val_if_fail (size_out != NULL, FALSE);
1003
1004   data = *data_out;
1005   size = *size_out;
1006
1007   for (i = 0; i < encodings->len; i++) {
1008     GstMatroskaTrackEncoding *enc =
1009         &g_array_index (encodings, GstMatroskaTrackEncoding, i);
1010     guint8 *new_data = NULL;
1011     guint new_size = 0;
1012
1013     if ((enc->scope & scope) == 0)
1014       continue;
1015
1016     /* Encryption not supported yet */
1017     if (enc->type != 0) {
1018       ret = FALSE;
1019       break;
1020     }
1021
1022     new_data = data;
1023     new_size = size;
1024
1025     ret =
1026         gst_matroska_decompress_data (enc, &new_data, &new_size,
1027         enc->comp_algo);
1028
1029     if (!ret)
1030       break;
1031
1032     if ((data == *data_out && free) || (data != *data_out))
1033       g_free (data);
1034
1035     data = new_data;
1036     size = new_size;
1037   }
1038
1039   if (!ret) {
1040     if ((data == *data_out && free) || (data != *data_out))
1041       g_free (data);
1042
1043     *data_out = NULL;
1044     *size_out = 0;
1045   } else {
1046     *data_out = data;
1047     *size_out = size;
1048   }
1049
1050   return ret;
1051 }
1052
1053 static GstBuffer *
1054 gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
1055 {
1056   guint8 *data;
1057   guint size;
1058   GstBuffer *new_buf;
1059
1060   g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
1061
1062   GST_DEBUG ("decoding buffer %p", buf);
1063
1064   data = GST_BUFFER_DATA (buf);
1065   size = GST_BUFFER_SIZE (buf);
1066
1067   g_return_val_if_fail (data != NULL && size > 0, buf);
1068
1069   if (gst_matroska_decode_data (context->encodings, &data, &size,
1070           GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
1071     new_buf = gst_buffer_new ();
1072     GST_BUFFER_MALLOCDATA (new_buf) = (guint8 *) data;
1073     GST_BUFFER_DATA (new_buf) = (guint8 *) data;
1074     GST_BUFFER_SIZE (new_buf) = size;
1075
1076     gst_buffer_unref (buf);
1077     buf = new_buf;
1078
1079     return buf;
1080   } else {
1081     GST_DEBUG ("decode data failed");
1082     gst_buffer_unref (buf);
1083     return NULL;
1084   }
1085 }
1086
1087 static GstFlowReturn
1088 gst_matroska_decode_content_encodings (GArray * encodings)
1089 {
1090   gint i;
1091
1092   if (encodings == NULL)
1093     return GST_FLOW_OK;
1094
1095   for (i = 0; i < encodings->len; i++) {
1096     GstMatroskaTrackEncoding *enc =
1097         &g_array_index (encodings, GstMatroskaTrackEncoding, i);
1098     GstMatroskaTrackEncoding *enc2;
1099     guint8 *data = NULL;
1100     guint size;
1101
1102     if ((enc->scope & GST_MATROSKA_TRACK_ENCODING_SCOPE_NEXT_CONTENT_ENCODING)
1103         == 0)
1104       continue;
1105
1106     /* Encryption not supported yet */
1107     if (enc->type != 0)
1108       return GST_FLOW_ERROR;
1109
1110     if (i + 1 >= encodings->len)
1111       return GST_FLOW_ERROR;
1112
1113     enc2 = &g_array_index (encodings, GstMatroskaTrackEncoding, i + 1);
1114
1115     if (enc->comp_settings_length == 0)
1116       continue;
1117
1118     data = enc->comp_settings;
1119     size = enc->comp_settings_length;
1120
1121     if (!gst_matroska_decompress_data (enc, &data, &size, enc->comp_algo))
1122       return GST_FLOW_ERROR;
1123
1124     g_free (enc->comp_settings);
1125
1126     enc->comp_settings = data;
1127     enc->comp_settings_length = size;
1128   }
1129
1130   return GST_FLOW_OK;
1131 }
1132
1133 static GstFlowReturn
1134 gst_matroska_demux_read_track_encodings (GstMatroskaDemux * demux,
1135     GstEbmlRead * ebml, GstMatroskaTrackContext * context)
1136 {
1137   GstFlowReturn ret;
1138   guint32 id;
1139
1140   DEBUG_ELEMENT_START (demux, ebml, "ContentEncodings");
1141
1142   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1143     DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncodings", ret);
1144     return ret;
1145   }
1146
1147   context->encodings =
1148       g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaTrackEncoding), 1);
1149
1150   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1151     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1152       break;
1153
1154     switch (id) {
1155       case GST_MATROSKA_ID_CONTENTENCODING:
1156         ret = gst_matroska_demux_read_track_encoding (demux, ebml, context);
1157         break;
1158       default:
1159         GST_WARNING_OBJECT (demux,
1160             "Unknown ContentEncodings subelement 0x%x - ignoring", id);
1161         ret = gst_ebml_read_skip (ebml);
1162         break;
1163     }
1164   }
1165
1166   DEBUG_ELEMENT_STOP (demux, ebml, "ContentEncodings", ret);
1167   if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
1168     return ret;
1169
1170   /* Sort encodings according to their order */
1171   g_array_sort (context->encodings,
1172       (GCompareFunc) gst_matroska_demux_encoding_cmp);
1173
1174   return gst_matroska_decode_content_encodings (context->encodings);
1175 }
1176
1177 static gboolean
1178 gst_matroska_demux_tracknumber_unique (GstMatroskaDemux * demux, guint64 num)
1179 {
1180   gint i;
1181
1182   g_assert (demux->src->len == demux->num_streams);
1183   for (i = 0; i < demux->src->len; i++) {
1184     GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
1185
1186     if (context->num == num)
1187       return FALSE;
1188   }
1189
1190   return TRUE;
1191 }
1192
1193 static GstFlowReturn
1194 gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
1195 {
1196   GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
1197   GstMatroskaTrackContext *context;
1198   GstPadTemplate *templ = NULL;
1199   GstCaps *caps = NULL;
1200   gchar *padname = NULL;
1201   GstFlowReturn ret;
1202   guint32 id, riff_fourcc = 0;
1203   guint16 riff_audio_fmt = 0;
1204   GstTagList *list = NULL;
1205   gchar *codec = NULL;
1206
1207   DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
1208
1209   /* start with the master */
1210   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1211     DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1212     return ret;
1213   }
1214
1215   /* allocate generic... if we know the type, we'll g_renew()
1216    * with the precise type */
1217   context = g_new0 (GstMatroskaTrackContext, 1);
1218   g_ptr_array_add (demux->src, context);
1219   context->index = demux->num_streams;
1220   context->index_writer_id = -1;
1221   context->type = 0;            /* no type yet */
1222   context->default_duration = 0;
1223   context->pos = 0;
1224 #ifdef MKVDEMUX_MODIFICATION
1225   context->found_next_kframe = FALSE;
1226 #endif
1227   context->set_discont = TRUE;
1228   context->timecodescale = 1.0;
1229   context->flags =
1230       GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT |
1231       GST_MATROSKA_TRACK_LACING;
1232   context->last_flow = GST_FLOW_OK;
1233   context->to_offset = G_MAXINT64;
1234   demux->num_streams++;
1235   g_assert (demux->src->len == demux->num_streams);
1236   
1237 #ifdef MKVDEMUX_MODIFICATION
1238   context->queue = g_queue_new ();
1239   context->found_key_frame = FALSE;
1240   context->last_ts = GST_CLOCK_TIME_NONE;
1241   context->avg_duration = GST_CLOCK_TIME_NONE;
1242   context->intra_gap = 0;
1243 #endif
1244
1245   GST_DEBUG_OBJECT (demux, "Stream number %d", context->index);
1246
1247   /* try reading the trackentry headers */
1248   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1249     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1250       break;
1251
1252     switch (id) {
1253         /* track number (unique stream ID) */
1254       case GST_MATROSKA_ID_TRACKNUMBER:{
1255         guint64 num;
1256
1257         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1258           break;
1259
1260         if (num == 0) {
1261           GST_ERROR_OBJECT (demux, "Invalid TrackNumber 0");
1262           ret = GST_FLOW_ERROR;
1263           break;
1264         } else if (!gst_matroska_demux_tracknumber_unique (demux, num)) {
1265           GST_ERROR_OBJECT (demux, "TrackNumber %" G_GUINT64_FORMAT
1266               " is not unique", num);
1267           ret = GST_FLOW_ERROR;
1268           break;
1269         }
1270
1271         GST_DEBUG_OBJECT (demux, "TrackNumber: %" G_GUINT64_FORMAT, num);
1272         context->num = num;
1273         break;
1274       }
1275         /* track UID (unique identifier) */
1276       case GST_MATROSKA_ID_TRACKUID:{
1277         guint64 num;
1278
1279         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1280           break;
1281
1282         if (num == 0) {
1283           GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
1284           ret = GST_FLOW_ERROR;
1285           break;
1286         }
1287
1288         GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
1289         context->uid = num;
1290         break;
1291       }
1292
1293         /* track type (video, audio, combined, subtitle, etc.) */
1294       case GST_MATROSKA_ID_TRACKTYPE:{
1295         guint64 track_type;
1296
1297         if ((ret = gst_ebml_read_uint (ebml, &id, &track_type)) != GST_FLOW_OK) {
1298           break;
1299         }
1300
1301         if (context->type != 0 && context->type != track_type) {
1302           GST_WARNING_OBJECT (demux,
1303               "More than one tracktype defined in a TrackEntry - skipping");
1304           break;
1305         } else if (track_type < 1 || track_type > 254) {
1306           GST_WARNING_OBJECT (demux, "Invalid TrackType %" G_GUINT64_FORMAT,
1307               track_type);
1308           break;
1309         }
1310
1311         GST_DEBUG_OBJECT (demux, "TrackType: %" G_GUINT64_FORMAT, track_type);
1312
1313         /* ok, so we're actually going to reallocate this thing */
1314         switch (track_type) {
1315           case GST_MATROSKA_TRACK_TYPE_VIDEO:
1316             gst_matroska_track_init_video_context (&context);
1317             break;
1318           case GST_MATROSKA_TRACK_TYPE_AUDIO:
1319             gst_matroska_track_init_audio_context (&context);
1320             break;
1321           case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1322             gst_matroska_track_init_subtitle_context (&context);
1323             break;
1324           case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1325           case GST_MATROSKA_TRACK_TYPE_LOGO:
1326           case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1327           case GST_MATROSKA_TRACK_TYPE_CONTROL:
1328           default:
1329             GST_WARNING_OBJECT (demux,
1330                 "Unknown or unsupported TrackType %" G_GUINT64_FORMAT,
1331                 track_type);
1332             context->type = 0;
1333             break;
1334         }
1335         g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
1336         break;
1337       }
1338
1339         /* tracktype specific stuff for video */
1340       case GST_MATROSKA_ID_TRACKVIDEO:{
1341         GstMatroskaTrackVideoContext *videocontext;
1342
1343         DEBUG_ELEMENT_START (demux, ebml, "TrackVideo");
1344
1345         if (!gst_matroska_track_init_video_context (&context)) {
1346           GST_WARNING_OBJECT (demux,
1347               "TrackVideo element in non-video track - ignoring track");
1348           ret = GST_FLOW_ERROR;
1349           break;
1350         } else if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
1351           break;
1352         }
1353         videocontext = (GstMatroskaTrackVideoContext *) context;
1354         g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
1355
1356         while (ret == GST_FLOW_OK &&
1357             gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1358           if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1359             break;
1360
1361           switch (id) {
1362               /* Should be one level up but some broken muxers write it here. */
1363             case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1364               guint64 num;
1365
1366               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1367                 break;
1368
1369               if (num == 0) {
1370                 GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1371                 break;
1372               }
1373
1374               GST_DEBUG_OBJECT (demux,
1375                   "TrackDefaultDuration: %" G_GUINT64_FORMAT, num);
1376               context->default_duration = num;
1377               break;
1378             }
1379
1380               /* video framerate */
1381               /* NOTE: This one is here only for backward compatibility.
1382                * Use _TRACKDEFAULDURATION one level up. */
1383             case GST_MATROSKA_ID_VIDEOFRAMERATE:{
1384               gdouble num;
1385
1386               if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1387                 break;
1388
1389               if (num <= 0.0) {
1390                 GST_WARNING_OBJECT (demux, "Invalid TrackVideoFPS %lf", num);
1391                 break;
1392               }
1393
1394               GST_DEBUG_OBJECT (demux, "TrackVideoFrameRate: %lf", num);
1395               if (context->default_duration == 0)
1396                 context->default_duration =
1397                     gst_gdouble_to_guint64 ((gdouble) GST_SECOND * (1.0 / num));
1398               videocontext->default_fps = num;
1399               break;
1400             }
1401
1402               /* width of the size to display the video at */
1403             case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
1404               guint64 num;
1405
1406               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1407                 break;
1408
1409               if (num == 0) {
1410                 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayWidth 0");
1411                 break;
1412               }
1413
1414               GST_DEBUG_OBJECT (demux,
1415                   "TrackVideoDisplayWidth: %" G_GUINT64_FORMAT, num);
1416               videocontext->display_width = num;
1417               break;
1418             }
1419
1420               /* height of the size to display the video at */
1421             case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
1422               guint64 num;
1423
1424               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1425                 break;
1426
1427               if (num == 0) {
1428                 GST_WARNING_OBJECT (demux, "Invalid TrackVideoDisplayHeight 0");
1429                 break;
1430               }
1431
1432               GST_DEBUG_OBJECT (demux,
1433                   "TrackVideoDisplayHeight: %" G_GUINT64_FORMAT, num);
1434               videocontext->display_height = num;
1435               break;
1436             }
1437
1438               /* width of the video in the file */
1439             case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
1440               guint64 num;
1441
1442               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1443                 break;
1444
1445               if (num == 0) {
1446                 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelWidth 0");
1447                 break;
1448               }
1449
1450               GST_DEBUG_OBJECT (demux,
1451                   "TrackVideoPixelWidth: %" G_GUINT64_FORMAT, num);
1452               videocontext->pixel_width = num;
1453               break;
1454             }
1455
1456               /* height of the video in the file */
1457             case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
1458               guint64 num;
1459
1460               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1461                 break;
1462
1463               if (num == 0) {
1464                 GST_WARNING_OBJECT (demux, "Invalid TrackVideoPixelHeight 0");
1465                 break;
1466               }
1467
1468               GST_DEBUG_OBJECT (demux,
1469                   "TrackVideoPixelHeight: %" G_GUINT64_FORMAT, num);
1470               videocontext->pixel_height = num;
1471               break;
1472             }
1473
1474               /* whether the video is interlaced */
1475             case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
1476               guint64 num;
1477
1478               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1479                 break;
1480
1481               if (num)
1482                 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
1483               else
1484                 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
1485               GST_DEBUG_OBJECT (demux, "TrackVideoInterlaced: %d",
1486                   (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED) ? 1 :
1487                   0);
1488               break;
1489             }
1490
1491               /* aspect ratio behaviour */
1492             case GST_MATROSKA_ID_VIDEOASPECTRATIOTYPE:{
1493               guint64 num;
1494
1495               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1496                 break;
1497
1498               if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
1499                   num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
1500                   num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
1501                 GST_WARNING_OBJECT (demux,
1502                     "Unknown TrackVideoAspectRatioType 0x%x", (guint) num);
1503                 break;
1504               }
1505               GST_DEBUG_OBJECT (demux,
1506                   "TrackVideoAspectRatioType: %" G_GUINT64_FORMAT, num);
1507               videocontext->asr_mode = num;
1508               break;
1509             }
1510
1511               /* colourspace (only matters for raw video) fourcc */
1512             case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
1513               guint8 *data;
1514               guint64 datalen;
1515
1516               if ((ret =
1517                       gst_ebml_read_binary (ebml, &id, &data,
1518                           &datalen)) != GST_FLOW_OK)
1519                 break;
1520
1521               if (datalen != 4) {
1522                 g_free (data);
1523                 GST_WARNING_OBJECT (demux,
1524                     "Invalid TrackVideoColourSpace length %" G_GUINT64_FORMAT,
1525                     datalen);
1526                 break;
1527               }
1528
1529               memcpy (&videocontext->fourcc, data, 4);
1530               GST_DEBUG_OBJECT (demux,
1531                   "TrackVideoColourSpace: %" GST_FOURCC_FORMAT,
1532                   GST_FOURCC_ARGS (videocontext->fourcc));
1533               g_free (data);
1534               break;
1535             }
1536
1537             default:
1538               GST_WARNING_OBJECT (demux,
1539                   "Unknown TrackVideo subelement 0x%x - ignoring", id);
1540               /* fall through */
1541             case GST_MATROSKA_ID_VIDEOSTEREOMODE:
1542             case GST_MATROSKA_ID_VIDEODISPLAYUNIT:
1543             case GST_MATROSKA_ID_VIDEOPIXELCROPBOTTOM:
1544             case GST_MATROSKA_ID_VIDEOPIXELCROPTOP:
1545             case GST_MATROSKA_ID_VIDEOPIXELCROPLEFT:
1546             case GST_MATROSKA_ID_VIDEOPIXELCROPRIGHT:
1547             case GST_MATROSKA_ID_VIDEOGAMMAVALUE:
1548               ret = gst_ebml_read_skip (ebml);
1549               break;
1550           }
1551         }
1552
1553         DEBUG_ELEMENT_STOP (demux, ebml, "TrackVideo", ret);
1554         break;
1555       }
1556
1557         /* tracktype specific stuff for audio */
1558       case GST_MATROSKA_ID_TRACKAUDIO:{
1559         GstMatroskaTrackAudioContext *audiocontext;
1560
1561         DEBUG_ELEMENT_START (demux, ebml, "TrackAudio");
1562
1563         if (!gst_matroska_track_init_audio_context (&context)) {
1564           GST_WARNING_OBJECT (demux,
1565               "TrackAudio element in non-audio track - ignoring track");
1566           ret = GST_FLOW_ERROR;
1567           break;
1568         }
1569
1570         if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK)
1571           break;
1572
1573         audiocontext = (GstMatroskaTrackAudioContext *) context;
1574         g_ptr_array_index (demux->src, demux->num_streams - 1) = context;
1575
1576         while (ret == GST_FLOW_OK &&
1577             gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
1578           if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
1579             break;
1580
1581           switch (id) {
1582               /* samplerate */
1583             case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
1584               gdouble num;
1585
1586               if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1587                 break;
1588
1589
1590               if (num <= 0.0) {
1591                 GST_WARNING_OBJECT (demux,
1592                     "Invalid TrackAudioSamplingFrequency %lf", num);
1593                 break;
1594               }
1595
1596               GST_DEBUG_OBJECT (demux, "TrackAudioSamplingFrequency: %lf", num);
1597               audiocontext->samplerate = num;
1598               break;
1599             }
1600
1601               /* bitdepth */
1602             case GST_MATROSKA_ID_AUDIOBITDEPTH:{
1603               guint64 num;
1604
1605               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1606                 break;
1607
1608               if (num == 0) {
1609                 GST_WARNING_OBJECT (demux, "Invalid TrackAudioBitDepth 0");
1610                 break;
1611               }
1612
1613               GST_DEBUG_OBJECT (demux, "TrackAudioBitDepth: %" G_GUINT64_FORMAT,
1614                   num);
1615               audiocontext->bitdepth = num;
1616               break;
1617             }
1618
1619               /* channels */
1620             case GST_MATROSKA_ID_AUDIOCHANNELS:{
1621               guint64 num;
1622
1623               if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1624                 break;
1625
1626               if (num == 0) {
1627                 GST_WARNING_OBJECT (demux, "Invalid TrackAudioChannels 0");
1628                 break;
1629               }
1630
1631               GST_DEBUG_OBJECT (demux, "TrackAudioChannels: %" G_GUINT64_FORMAT,
1632                   num);
1633               audiocontext->channels = num;
1634               break;
1635             }
1636
1637             default:
1638               GST_WARNING_OBJECT (demux,
1639                   "Unknown TrackAudio subelement 0x%x - ignoring", id);
1640               /* fall through */
1641             case GST_MATROSKA_ID_AUDIOCHANNELPOSITIONS:
1642             case GST_MATROSKA_ID_AUDIOOUTPUTSAMPLINGFREQ:
1643               ret = gst_ebml_read_skip (ebml);
1644               break;
1645           }
1646         }
1647
1648         DEBUG_ELEMENT_STOP (demux, ebml, "TrackAudio", ret);
1649
1650         break;
1651       }
1652
1653         /* codec identifier */
1654       case GST_MATROSKA_ID_CODECID:{
1655         gchar *text;
1656
1657         if ((ret = gst_ebml_read_ascii (ebml, &id, &text)) != GST_FLOW_OK)
1658           break;
1659
1660         GST_DEBUG_OBJECT (demux, "CodecID: %s", GST_STR_NULL (text));
1661         context->codec_id = text;
1662         break;
1663       }
1664
1665         /* codec private data */
1666       case GST_MATROSKA_ID_CODECPRIVATE:{
1667         guint8 *data;
1668         guint64 size;
1669
1670         if ((ret =
1671                 gst_ebml_read_binary (ebml, &id, &data, &size)) != GST_FLOW_OK)
1672           break;
1673
1674         context->codec_priv = data;
1675         context->codec_priv_size = size;
1676
1677         GST_DEBUG_OBJECT (demux, "CodecPrivate of size %" G_GUINT64_FORMAT,
1678             size);
1679         break;
1680       }
1681
1682         /* name of the codec */
1683       case GST_MATROSKA_ID_CODECNAME:{
1684         gchar *text;
1685
1686         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1687           break;
1688
1689         GST_DEBUG_OBJECT (demux, "CodecName: %s", GST_STR_NULL (text));
1690         context->codec_name = text;
1691         break;
1692       }
1693
1694         /* name of this track */
1695       case GST_MATROSKA_ID_TRACKNAME:{
1696         gchar *text;
1697
1698         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1699           break;
1700
1701         context->name = text;
1702         GST_DEBUG_OBJECT (demux, "TrackName: %s", GST_STR_NULL (text));
1703         break;
1704       }
1705
1706         /* language (matters for audio/subtitles, mostly) */
1707       case GST_MATROSKA_ID_TRACKLANGUAGE:{
1708         gchar *text;
1709
1710         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
1711           break;
1712
1713
1714         context->language = text;
1715
1716         /* fre-ca => fre */
1717         if (strlen (context->language) >= 4 && context->language[3] == '-')
1718           context->language[3] = '\0';
1719
1720         GST_DEBUG_OBJECT (demux, "TrackLanguage: %s",
1721             GST_STR_NULL (context->language));
1722         break;
1723       }
1724
1725         /* whether this is actually used */
1726       case GST_MATROSKA_ID_TRACKFLAGENABLED:{
1727         guint64 num;
1728
1729         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1730           break;
1731
1732         if (num)
1733           context->flags |= GST_MATROSKA_TRACK_ENABLED;
1734         else
1735           context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
1736
1737         GST_DEBUG_OBJECT (demux, "TrackEnabled: %d",
1738             (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1739         break;
1740       }
1741
1742         /* whether it's the default for this track type */
1743       case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
1744         guint64 num;
1745
1746         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1747           break;
1748
1749         if (num)
1750           context->flags |= GST_MATROSKA_TRACK_DEFAULT;
1751         else
1752           context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
1753
1754         GST_DEBUG_OBJECT (demux, "TrackDefault: %d",
1755             (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1756         break;
1757       }
1758
1759         /* whether the track must be used during playback */
1760       case GST_MATROSKA_ID_TRACKFLAGFORCED:{
1761         guint64 num;
1762
1763         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1764           break;
1765
1766         if (num)
1767           context->flags |= GST_MATROSKA_TRACK_FORCED;
1768         else
1769           context->flags &= ~GST_MATROSKA_TRACK_FORCED;
1770
1771         GST_DEBUG_OBJECT (demux, "TrackForced: %d",
1772             (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1773         break;
1774       }
1775
1776         /* lacing (like MPEG, where blocks don't end/start on frame
1777          * boundaries) */
1778       case GST_MATROSKA_ID_TRACKFLAGLACING:{
1779         guint64 num;
1780
1781         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1782           break;
1783
1784         if (num)
1785           context->flags |= GST_MATROSKA_TRACK_LACING;
1786         else
1787           context->flags &= ~GST_MATROSKA_TRACK_LACING;
1788
1789         GST_DEBUG_OBJECT (demux, "TrackLacing: %d",
1790             (context->flags & GST_MATROSKA_TRACK_ENABLED) ? 1 : 0);
1791         break;
1792       }
1793
1794         /* default length (in time) of one data block in this track */
1795       case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
1796         guint64 num;
1797
1798         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
1799           break;
1800
1801
1802         if (num == 0) {
1803           GST_WARNING_OBJECT (demux, "Invalid TrackDefaultDuration 0");
1804           break;
1805         }
1806
1807         GST_DEBUG_OBJECT (demux, "TrackDefaultDuration: %" G_GUINT64_FORMAT,
1808             num);
1809         context->default_duration = num;
1810         break;
1811       }
1812
1813       case GST_MATROSKA_ID_CONTENTENCODINGS:{
1814         ret = gst_matroska_demux_read_track_encodings (demux, ebml, context);
1815         break;
1816       }
1817
1818       case GST_MATROSKA_ID_TRACKTIMECODESCALE:{
1819         gdouble num;
1820
1821         if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
1822           break;
1823
1824         if (num <= 0.0) {
1825           GST_WARNING_OBJECT (demux, "Invalid TrackTimeCodeScale %lf", num);
1826           break;
1827         }
1828
1829         GST_DEBUG_OBJECT (demux, "TrackTimeCodeScale: %lf", num);
1830         context->timecodescale = num;
1831         break;
1832       }
1833
1834       default:
1835         GST_WARNING ("Unknown TrackEntry subelement 0x%x - ignoring", id);
1836         /* pass-through */
1837
1838         /* we ignore these because they're nothing useful (i.e. crap)
1839          * or simply not implemented yet. */
1840       case GST_MATROSKA_ID_TRACKMINCACHE:
1841       case GST_MATROSKA_ID_TRACKMAXCACHE:
1842       case GST_MATROSKA_ID_MAXBLOCKADDITIONID:
1843       case GST_MATROSKA_ID_TRACKATTACHMENTLINK:
1844       case GST_MATROSKA_ID_TRACKOVERLAY:
1845       case GST_MATROSKA_ID_TRACKTRANSLATE:
1846       case GST_MATROSKA_ID_TRACKOFFSET:
1847       case GST_MATROSKA_ID_CODECSETTINGS:
1848       case GST_MATROSKA_ID_CODECINFOURL:
1849       case GST_MATROSKA_ID_CODECDOWNLOADURL:
1850       case GST_MATROSKA_ID_CODECDECODEALL:
1851         ret = gst_ebml_read_skip (ebml);
1852         break;
1853     }
1854   }
1855
1856   DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
1857
1858   /* Decode codec private data if necessary */
1859   if (context->encodings && context->encodings->len > 0 && context->codec_priv
1860       && context->codec_priv_size > 0) {
1861     if (!gst_matroska_decode_data (context->encodings,
1862             &context->codec_priv, &context->codec_priv_size,
1863             GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
1864       GST_WARNING_OBJECT (demux, "Decoding codec private data failed");
1865       ret = GST_FLOW_ERROR;
1866     }
1867   }
1868
1869   if (context->type == 0 || context->codec_id == NULL || (ret != GST_FLOW_OK
1870           && ret != GST_FLOW_UNEXPECTED)) {
1871     if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
1872       GST_WARNING_OBJECT (ebml, "Unknown stream/codec in track entry header");
1873
1874     demux->num_streams--;
1875     g_ptr_array_remove_index (demux->src, demux->num_streams);
1876     g_assert (demux->src->len == demux->num_streams);
1877     if (context) {
1878       gst_matroska_track_free (context);
1879     }
1880
1881     return ret;
1882   }
1883
1884   /* now create the GStreamer connectivity */
1885   switch (context->type) {
1886     case GST_MATROSKA_TRACK_TYPE_VIDEO:{
1887       GstMatroskaTrackVideoContext *videocontext =
1888           (GstMatroskaTrackVideoContext *) context;
1889
1890       padname = g_strdup_printf ("video_%02d", demux->num_v_streams++);
1891       templ = gst_element_class_get_pad_template (klass, "video_%02d");
1892       caps = gst_matroska_demux_video_caps (videocontext,
1893           context->codec_id, (guint8 *) context->codec_priv,
1894           context->codec_priv_size, &codec, &riff_fourcc);
1895
1896       if (codec) {
1897         list = gst_tag_list_new ();
1898         gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1899             GST_TAG_VIDEO_CODEC, codec, NULL);
1900         g_free (codec);
1901       }
1902       break;
1903     }
1904
1905     case GST_MATROSKA_TRACK_TYPE_AUDIO:{
1906       GstMatroskaTrackAudioContext *audiocontext =
1907           (GstMatroskaTrackAudioContext *) context;
1908
1909       padname = g_strdup_printf ("audio_%02d", demux->num_a_streams++);
1910       templ = gst_element_class_get_pad_template (klass, "audio_%02d");
1911       caps = gst_matroska_demux_audio_caps (audiocontext,
1912           context->codec_id, context->codec_priv, context->codec_priv_size,
1913           &codec, &riff_audio_fmt);
1914
1915       if (codec) {
1916         list = gst_tag_list_new ();
1917         gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1918             GST_TAG_AUDIO_CODEC, codec, NULL);
1919         g_free (codec);
1920       }
1921       break;
1922     }
1923
1924     case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
1925       GstMatroskaTrackSubtitleContext *subtitlecontext =
1926           (GstMatroskaTrackSubtitleContext *) context;
1927
1928       padname = g_strdup_printf ("subtitle_%02d", demux->num_t_streams++);
1929       templ = gst_element_class_get_pad_template (klass, "subtitle_%02d");
1930       caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
1931           context->codec_id, context->codec_priv, context->codec_priv_size);
1932       break;
1933     }
1934
1935     case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1936     case GST_MATROSKA_TRACK_TYPE_LOGO:
1937     case GST_MATROSKA_TRACK_TYPE_BUTTONS:
1938     case GST_MATROSKA_TRACK_TYPE_CONTROL:
1939     default:
1940       /* we should already have quit by now */
1941       g_assert_not_reached ();
1942   }
1943
1944   if ((context->language == NULL || *context->language == '\0') &&
1945       (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO ||
1946           context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
1947     GST_LOG ("stream %d: language=eng (assuming default)", context->index);
1948     context->language = g_strdup ("eng");
1949   }
1950
1951   if (context->language) {
1952     const gchar *lang;
1953
1954     if (!list)
1955       list = gst_tag_list_new ();
1956
1957     /* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
1958     lang = gst_tag_get_language_code (context->language);
1959     gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1960         GST_TAG_LANGUAGE_CODE, (lang) ? lang : context->language, NULL);
1961   }
1962
1963   if (caps == NULL) {
1964     GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
1965         "codec_id='%s'", context->codec_id);
1966     switch (context->type) {
1967       case GST_MATROSKA_TRACK_TYPE_VIDEO:
1968         caps = gst_caps_new_simple ("video/x-unknown", NULL);
1969         break;
1970       case GST_MATROSKA_TRACK_TYPE_AUDIO:
1971         caps = gst_caps_new_simple ("audio/x-unknown", NULL);
1972         break;
1973       case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
1974         caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
1975         break;
1976       case GST_MATROSKA_TRACK_TYPE_COMPLEX:
1977       default:
1978         caps = gst_caps_new_simple ("application/x-matroska-unknown", NULL);
1979         break;
1980     }
1981     gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
1982         NULL);
1983
1984     /* add any unrecognised riff fourcc / audio format, but after codec-id */
1985     if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
1986       gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
1987     else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0)
1988       gst_caps_set_simple (caps, "fourcc", GST_TYPE_FOURCC, riff_fourcc, NULL);
1989   }
1990
1991   /* the pad in here */
1992   context->pad = gst_pad_new_from_template (templ, padname);
1993   context->caps = caps;
1994
1995   gst_pad_set_event_function (context->pad,
1996       GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
1997   gst_pad_set_query_type_function (context->pad,
1998       GST_DEBUG_FUNCPTR (gst_matroska_demux_get_src_query_types));
1999   gst_pad_set_query_function (context->pad,
2000       GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
2001
2002   GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
2003       padname, caps);
2004
2005   context->pending_tags = list;
2006
2007   gst_pad_set_element_private (context->pad, context);
2008
2009   gst_pad_use_fixed_caps (context->pad);
2010   gst_pad_set_caps (context->pad, context->caps);
2011   gst_pad_set_active (context->pad, TRUE);
2012   gst_element_add_pad (GST_ELEMENT (demux), context->pad);
2013
2014   g_free (padname);
2015
2016 #ifdef MKVDEMUX_MODIFICATION
2017   if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO)           
2018         demux->audio_stream = context;
2019   if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
2020         demux->video = TRUE;
2021 #endif
2022
2023   /* tadaah! */
2024   return ret;
2025 }
2026
2027 static const GstQueryType *
2028 gst_matroska_demux_get_src_query_types (GstPad * pad)
2029 {
2030   static const GstQueryType query_types[] = {
2031     GST_QUERY_POSITION,
2032     GST_QUERY_DURATION,
2033     GST_QUERY_SEEKING,
2034     0
2035   };
2036
2037   return query_types;
2038 }
2039
2040 static gboolean
2041 gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
2042     GstQuery * query)
2043 {
2044   gboolean res = FALSE;
2045   GstMatroskaTrackContext *context = NULL;
2046
2047   if (pad) {
2048     context = gst_pad_get_element_private (pad);
2049   }
2050
2051   switch (GST_QUERY_TYPE (query)) {
2052     case GST_QUERY_POSITION:
2053     {
2054       GstFormat format;
2055
2056       gst_query_parse_position (query, &format, NULL);
2057
2058       if (format == GST_FORMAT_TIME) {
2059         GST_OBJECT_LOCK (demux);
2060         if (context)
2061           gst_query_set_position (query, GST_FORMAT_TIME, context->pos);
2062         else
2063           gst_query_set_position (query, GST_FORMAT_TIME,
2064               demux->segment.last_stop);
2065         GST_OBJECT_UNLOCK (demux);
2066       } else if (format == GST_FORMAT_DEFAULT && context
2067           && context->default_duration) {
2068         GST_OBJECT_LOCK (demux);
2069         gst_query_set_position (query, GST_FORMAT_DEFAULT,
2070             context->pos / context->default_duration);
2071         GST_OBJECT_UNLOCK (demux);
2072       } else {
2073         GST_DEBUG_OBJECT (demux,
2074             "only position query in TIME and DEFAULT format is supported");
2075       }
2076
2077       res = TRUE;
2078       break;
2079     }
2080     case GST_QUERY_DURATION:
2081     {
2082       GstFormat format;
2083
2084       gst_query_parse_duration (query, &format, NULL);
2085
2086       if (format == GST_FORMAT_TIME) {
2087         GST_OBJECT_LOCK (demux);
2088         gst_query_set_duration (query, GST_FORMAT_TIME,
2089             demux->segment.duration);
2090         GST_OBJECT_UNLOCK (demux);
2091       } else if (format == GST_FORMAT_DEFAULT && context
2092           && context->default_duration) {
2093         GST_OBJECT_LOCK (demux);
2094         gst_query_set_duration (query, GST_FORMAT_DEFAULT,
2095             demux->segment.duration / context->default_duration);
2096         GST_OBJECT_UNLOCK (demux);
2097       } else {
2098         GST_DEBUG_OBJECT (demux,
2099             "only duration query in TIME and DEFAULT format is supported");
2100       }
2101
2102       res = TRUE;
2103       break;
2104     }
2105
2106     case GST_QUERY_SEEKING:
2107     {
2108       GstFormat fmt;
2109
2110       gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
2111       if (fmt == GST_FORMAT_TIME) {
2112         gboolean seekable;
2113
2114         if (demux->streaming) {
2115           /* assuming we'll be able to get an index ... */
2116           seekable = demux->seekable;
2117         } else {
2118           seekable = ! !demux->index;
2119         }
2120
2121         gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
2122             0, demux->segment.duration);
2123         res = TRUE;
2124       }
2125       break;
2126     }
2127     default:
2128       res = gst_pad_query_default (pad, query);
2129       break;
2130   }
2131
2132   return res;
2133 }
2134
2135 static gboolean
2136 gst_matroska_demux_element_query (GstElement * element, GstQuery * query)
2137 {
2138   return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query);
2139 }
2140
2141 static gboolean
2142 gst_matroska_demux_handle_src_query (GstPad * pad, GstQuery * query)
2143 {
2144   gboolean ret;
2145   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
2146
2147   ret = gst_matroska_demux_query (demux, pad, query);
2148
2149   gst_object_unref (demux);
2150
2151   return ret;
2152 }
2153
2154 static gint
2155 gst_matroska_index_seek_find (GstMatroskaIndex * i1, GstClockTime * time,
2156     gpointer user_data)
2157 {
2158   if (i1->time < *time)
2159     return -1;
2160   else if (i1->time > *time)
2161     return 1;
2162   else
2163     return 0;
2164 }
2165
2166 static GstMatroskaIndex *
2167 gst_matroskademux_do_index_seek (GstMatroskaDemux * demux,
2168     GstMatroskaTrackContext * track, gint64 seek_pos, gint64 segment_stop,
2169     gboolean keyunit)
2170 {
2171   GstMatroskaIndex *entry = NULL;
2172   GArray *index;
2173
2174   if (!demux->index || !demux->index->len)
2175     return NULL;
2176
2177   /* find entry just before or at the requested position */
2178   if (track && track->index_table)
2179     index = track->index_table;
2180   else
2181     index = demux->index;
2182
2183   entry =
2184       gst_util_array_binary_search (index->data, index->len,
2185       sizeof (GstMatroskaIndex),
2186       (GCompareDataFunc) gst_matroska_index_seek_find, GST_SEARCH_MODE_BEFORE,
2187       &seek_pos, NULL);
2188
2189   if (entry == NULL)
2190     entry = &g_array_index (index, GstMatroskaIndex, 0);
2191
2192   return entry;
2193 }
2194
2195 /* takes ownership of taglist */
2196 static void
2197 gst_matroska_demux_found_global_tag (GstMatroskaDemux * demux,
2198     GstTagList * taglist)
2199 {
2200   if (demux->global_tags) {
2201     /* nothing sent yet, add to cache */
2202     gst_tag_list_insert (demux->global_tags, taglist, GST_TAG_MERGE_APPEND);
2203     gst_tag_list_free (taglist);
2204   } else {
2205     /* hm, already sent, no need to cache and wait anymore */
2206     GST_DEBUG_OBJECT (demux, "Sending late global tags %" GST_PTR_FORMAT,
2207         taglist);
2208     gst_element_found_tags (GST_ELEMENT (demux), taglist);
2209   }
2210 }
2211
2212 /* returns FALSE if there are no pads to deliver event to,
2213  * otherwise TRUE (whatever the outcome of event sending),
2214  * takes ownership of the passed event! */
2215 static gboolean
2216 gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
2217 {
2218   gboolean is_newsegment;
2219   gboolean ret = FALSE;
2220   gint i;
2221
2222   g_return_val_if_fail (event != NULL, FALSE);
2223
2224   GST_INFO_OBJECT (demux, "Sending event of type %s to all source pads",
2225       GST_EVENT_TYPE_NAME (event));
2226
2227   is_newsegment = (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
2228
2229   g_assert (demux->src->len == demux->num_streams);
2230   for (i = 0; i < demux->src->len; i++) {
2231     GstMatroskaTrackContext *stream;
2232
2233     stream = g_ptr_array_index (demux->src, i);
2234     gst_event_ref (event);
2235     gst_pad_push_event (stream->pad, event);
2236     ret = TRUE;
2237
2238     /* FIXME: send global tags before stream tags */
2239     if (G_UNLIKELY (is_newsegment && stream->pending_tags != NULL)) {
2240       GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
2241           GST_PTR_FORMAT, stream->pending_tags,
2242           GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
2243       gst_element_found_tags_for_pad (GST_ELEMENT (demux), stream->pad,
2244           stream->pending_tags);
2245       stream->pending_tags = NULL;
2246     }
2247   }
2248
2249   if (G_UNLIKELY (is_newsegment && demux->global_tags != NULL)) {
2250     gst_tag_list_add (demux->global_tags, GST_TAG_MERGE_REPLACE,
2251         GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
2252     GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
2253         demux->global_tags, demux->global_tags);
2254     gst_element_found_tags (GST_ELEMENT (demux), demux->global_tags);
2255     demux->global_tags = NULL;
2256   }
2257
2258   gst_event_unref (event);
2259   return ret;
2260 }
2261
2262 static gboolean
2263 gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
2264 {
2265   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
2266   gboolean res;
2267
2268   g_return_val_if_fail (event != NULL, FALSE);
2269
2270   if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
2271     res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
2272   } else {
2273     GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
2274         GST_EVENT_TYPE_NAME (event));
2275     res = FALSE;
2276   }
2277   gst_event_unref (event);
2278   return res;
2279 }
2280
2281 #ifdef MKVDEMUX_MODIFICATION
2282 static GstMatroskaIndex *
2283 gst_matroskademux_get_next_index (GstMatroskaDemux * demux, GstMatroskaTrackContext * track, GstMatroskaIndex *entry)
2284 {
2285
2286   int i =0;
2287   GArray *index;
2288   GstMatroskaIndex *tmp = NULL;
2289
2290     /* find entry just before or at the requested position */
2291   if (track && track->index_table)
2292     index = track->index_table;
2293   else
2294     index = demux->index;
2295
2296   for (i=0; i < index->len; i++)
2297   {
2298       tmp = &g_array_index (index, GstMatroskaIndex, i);
2299       if ((tmp->time == entry->time) && (tmp->pos == entry->pos))
2300       {
2301           if ((index->len - i) == 1)
2302           {
2303              GST_DEBUG_OBJECT (demux, "entry found in last index...returning last index");
2304           }
2305           else
2306           {
2307                 GST_DEBUG_OBJECT (demux, "Found entry at index = %d");
2308                 i = i+1;
2309                 tmp = &g_array_index (index, GstMatroskaIndex, i);
2310           }
2311           return tmp;
2312       }
2313   }
2314   return NULL;
2315 }
2316 #endif
2317
2318 /* determine track to seek in */
2319 static GstMatroskaTrackContext *
2320 gst_matroska_demux_get_seek_track (GstMatroskaDemux * demux,
2321     GstMatroskaTrackContext * track)
2322 {
2323   gint i;
2324
2325   if (track && track->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
2326     return track;
2327
2328   for (i = 0; i < demux->src->len; i++) {
2329     GstMatroskaTrackContext *stream;
2330
2331     stream = g_ptr_array_index (demux->src, i);
2332     if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO && stream->index_table)
2333       track = stream;
2334   }
2335
2336   return track;
2337 }
2338
2339 static void
2340 gst_matroska_demux_reset_streams (GstMatroskaDemux * demux, GstClockTime time,
2341     gboolean full)
2342 {
2343   gint i;
2344
2345   GST_DEBUG_OBJECT (demux, "resetting stream state");
2346
2347   g_assert (demux->src->len == demux->num_streams);
2348   for (i = 0; i < demux->src->len; i++) {
2349     GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
2350     context->pos = time;
2351     context->set_discont = TRUE;
2352     context->eos = FALSE;
2353     context->from_time = GST_CLOCK_TIME_NONE;
2354 #ifdef MKVDEMUX_MODIFICATION
2355     context->found_next_kframe = FALSE;
2356     context->num_frames_bw_keyframes = 0;
2357     context->avg_duration_bw_keyframes = GST_CLOCK_TIME_NONE;
2358     context->frames_to_show_bw_keyframes = 0;
2359     context->prev_kframe_timestamp = GST_CLOCK_TIME_NONE;
2360     context->next_kframe_timestamp = GST_CLOCK_TIME_NONE;
2361     context->last_ts = GST_CLOCK_TIME_NONE;
2362 #endif
2363     if (full)
2364       context->last_flow = GST_FLOW_OK;
2365     if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
2366       GstMatroskaTrackVideoContext *videocontext =
2367           (GstMatroskaTrackVideoContext *) context;
2368       /* demux object lock held by caller */
2369       videocontext->earliest_time = GST_CLOCK_TIME_NONE;
2370     }
2371   }
2372 }
2373
2374 static gboolean
2375 gst_matroska_demux_move_to_entry (GstMatroskaDemux * demux,
2376     GstMatroskaIndex * entry, gboolean reset)
2377 {
2378   gint i;
2379
2380   GST_OBJECT_LOCK (demux);
2381
2382   /* seek (relative to matroska segment) */
2383   /* position might be invalid; will error when streaming resumes ... */
2384   demux->offset = entry->pos + demux->ebml_segment_start;
2385
2386   GST_DEBUG_OBJECT (demux, "Seeked to offset %" G_GUINT64_FORMAT ", block %d, "
2387       "time %" GST_TIME_FORMAT, entry->pos + demux->ebml_segment_start,
2388       entry->block, GST_TIME_ARGS (entry->time));
2389
2390   /* update the time */
2391   gst_matroska_demux_reset_streams (demux, entry->time, TRUE);
2392   demux->segment.last_stop = entry->time;
2393   demux->seek_block = entry->block;
2394   demux->seek_first = TRUE;
2395   demux->last_stop_end = GST_CLOCK_TIME_NONE;
2396
2397   for (i = 0; i < demux->src->len; i++) {
2398     GstMatroskaTrackContext *stream = g_ptr_array_index (demux->src, i);
2399
2400     if (reset) {
2401       stream->to_offset = G_MAXINT64;
2402     } else {
2403       if (stream->from_offset != -1)
2404         stream->to_offset = stream->from_offset;
2405     }
2406     stream->from_offset = -1;
2407   }
2408
2409   GST_OBJECT_UNLOCK (demux);
2410
2411   return TRUE;
2412 }
2413
2414 static gint
2415 gst_matroska_cluster_compare (gint64 * i1, gint64 * i2)
2416 {
2417   if (*i1 < *i2)
2418     return -1;
2419   else if (*i1 > *i2)
2420     return 1;
2421   else
2422     return 0;
2423 }
2424
2425 /* searches for a cluster start from @pos,
2426  * return GST_FLOW_OK and cluster position in @pos if found */
2427 static GstFlowReturn
2428 gst_matroska_demux_search_cluster (GstMatroskaDemux * demux, gint64 * pos)
2429 {
2430   gint64 newpos = *pos;
2431   gint64 orig_offset;
2432   GstFlowReturn ret = GST_FLOW_OK;
2433   const guint chunk = 64 * 1024;
2434   GstBuffer *buf = NULL;
2435   guint64 length;
2436   guint32 id;
2437   guint needed;
2438
2439   orig_offset = demux->offset;
2440
2441   GST_LOG_OBJECT (demux, "searching cluster following offset %" G_GINT64_FORMAT,
2442       *pos);
2443
2444   if (demux->clusters) {
2445     gint64 *cpos;
2446
2447     cpos = gst_util_array_binary_search (demux->clusters->data,
2448         demux->clusters->len, sizeof (gint64),
2449         (GCompareDataFunc) gst_matroska_cluster_compare,
2450         GST_SEARCH_MODE_AFTER, pos, NULL);
2451     /* sanity check */
2452     if (cpos) {
2453       GST_DEBUG_OBJECT (demux,
2454           "cluster reported at offset %" G_GINT64_FORMAT, *cpos);
2455       demux->offset = *cpos;
2456       ret =
2457           gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
2458       if (ret == GST_FLOW_OK && id == GST_MATROSKA_ID_CLUSTER) {
2459         newpos = *cpos;
2460         goto exit;
2461       }
2462     }
2463   }
2464
2465   /* read in at newpos and scan for ebml cluster id */
2466   while (1) {
2467     GstByteReader reader;
2468     gint cluster_pos;
2469
2470     ret = gst_pad_pull_range (demux->sinkpad, newpos, chunk, &buf);
2471     if (ret != GST_FLOW_OK)
2472       break;
2473     GST_DEBUG_OBJECT (demux, "read buffer size %d at offset %" G_GINT64_FORMAT,
2474         GST_BUFFER_SIZE (buf), newpos);
2475     gst_byte_reader_init_from_buffer (&reader, buf);
2476   resume:
2477     cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
2478         GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
2479     if (cluster_pos >= 0) {
2480       newpos += cluster_pos;
2481       /* prepare resuming at next byte */
2482       gst_byte_reader_skip (&reader, cluster_pos + 1);
2483       GST_DEBUG_OBJECT (demux,
2484           "found cluster ebml id at offset %" G_GINT64_FORMAT, newpos);
2485       /* extra checks whether we really sync'ed to a cluster:
2486        * - either it is the first and only cluster
2487        * - either there is a cluster after this one
2488        * - either cluster length is undefined
2489        */
2490       /* ok if first cluster (there may not a subsequent one) */
2491       if (newpos == demux->first_cluster_offset) {
2492         GST_DEBUG_OBJECT (demux, "cluster is first cluster -> OK");
2493         break;
2494       }
2495       demux->offset = newpos;
2496       ret =
2497           gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
2498       if (ret != GST_FLOW_OK)
2499         goto resume;
2500       g_assert (id == GST_MATROSKA_ID_CLUSTER);
2501       GST_DEBUG_OBJECT (demux, "cluster size %" G_GUINT64_FORMAT ", prefix %d",
2502           length, needed);
2503       /* ok if undefined length or first cluster */
2504       if (length == G_MAXUINT64) {
2505         GST_DEBUG_OBJECT (demux, "cluster has undefined length -> OK");
2506         break;
2507       }
2508       /* skip cluster */
2509       demux->offset += length + needed;
2510       ret =
2511           gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
2512       if (ret != GST_FLOW_OK)
2513         goto resume;
2514       GST_DEBUG_OBJECT (demux, "next element is %scluster",
2515           id == GST_MATROSKA_ID_CLUSTER ? "" : "not ");
2516       if (id == GST_MATROSKA_ID_CLUSTER)
2517         break;
2518       /* not ok, resume */
2519       goto resume;
2520     } else {
2521       /* partial cluster id may have been in tail of buffer */
2522       newpos += MAX (gst_byte_reader_get_remaining (&reader), 4) - 3;
2523       gst_buffer_unref (buf);
2524       buf = NULL;
2525     }
2526   }
2527
2528   if (buf) {
2529     gst_buffer_unref (buf);
2530     buf = NULL;
2531   }
2532
2533 exit:
2534   demux->offset = orig_offset;
2535   *pos = newpos;
2536   return ret;
2537 }
2538
2539 /* bisect and scan through file for cluster starting before @time,
2540  * returns fake index entry with corresponding info on cluster */
2541 static GstMatroskaIndex *
2542 gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
2543 {
2544   GstMatroskaIndex *entry = NULL;
2545   GstMatroskaDemuxState current_state;
2546   GstClockTime otime, prev_cluster_time, current_cluster_time, cluster_time;
2547   gint64 opos, newpos, startpos = 0, current_offset;
2548   gint64 prev_cluster_offset = -1, current_cluster_offset, cluster_offset;
2549   const guint chunk = 64 * 1024;
2550   GstBuffer *buf = NULL;
2551   GstFlowReturn ret;
2552   guint64 length;
2553   guint32 id;
2554   guint needed;
2555
2556   /* (under)estimate new position, resync using cluster ebml id,
2557    * and scan forward to appropriate cluster
2558    * (and re-estimate if need to go backward) */
2559
2560   prev_cluster_time = GST_CLOCK_TIME_NONE;
2561
2562   /* store some current state */
2563   current_state = demux->state;
2564   g_return_val_if_fail (current_state == GST_MATROSKA_DEMUX_STATE_DATA, NULL);
2565
2566   current_cluster_offset = demux->cluster_offset;
2567   current_cluster_time = demux->cluster_time;
2568   current_offset = demux->offset;
2569
2570   demux->state = GST_MATROSKA_DEMUX_STATE_SCANNING;
2571
2572   /* estimate using start and current position */
2573   opos = demux->offset - demux->ebml_segment_start;
2574   otime = demux->segment.last_stop;
2575
2576 retry:
2577   GST_LOG_OBJECT (demux,
2578       "opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT, opos,
2579       GST_TIME_ARGS (otime));
2580   newpos = gst_util_uint64_scale (opos, time, otime) - chunk;
2581   if (newpos < 0)
2582     newpos = 0;
2583   /* favour undershoot */
2584   newpos = newpos * 90 / 100;
2585   newpos += demux->ebml_segment_start;
2586
2587   GST_DEBUG_OBJECT (demux,
2588       "estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
2589       GST_TIME_ARGS (time), newpos);
2590
2591   /* and at least start scanning before previous scan start to avoid looping */
2592   startpos = startpos * 90 / 100;
2593   if (startpos && startpos < newpos)
2594     newpos = startpos;
2595
2596   /* read in at newpos and scan for ebml cluster id */
2597   startpos = newpos;
2598   while (1) {
2599
2600     ret = gst_matroska_demux_search_cluster (demux, &newpos);
2601     if (ret == GST_FLOW_UNEXPECTED) {
2602       /* heuristic HACK */
2603       newpos = startpos * 80 / 100;
2604       GST_DEBUG_OBJECT (demux, "EOS; "
2605           "new estimated offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
2606           GST_TIME_ARGS (time), newpos);
2607       startpos = newpos;
2608       continue;
2609     } else if (ret != GST_FLOW_OK) {
2610       goto exit;
2611     } else {
2612       break;
2613     }
2614   }
2615
2616   /* then start scanning and parsing for cluster time,
2617    * re-estimate if overshoot, otherwise next cluster and so on */
2618   demux->offset = newpos;
2619   demux->cluster_time = cluster_time = GST_CLOCK_TIME_NONE;
2620   while (1) {
2621     guint64 cluster_size = 0;
2622
2623     /* peek and parse some elements */
2624     ret = gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
2625     if (ret != GST_FLOW_OK)
2626       goto error;
2627     GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
2628         "size %" G_GUINT64_FORMAT ", needed %d", demux->offset, id,
2629         length, needed);
2630     ret = gst_matroska_demux_parse_id (demux, id, length, needed);
2631     if (ret != GST_FLOW_OK)
2632       goto error;
2633
2634     if (id == GST_MATROSKA_ID_CLUSTER) {
2635       cluster_time = GST_CLOCK_TIME_NONE;
2636       if (length == G_MAXUINT64)
2637         cluster_size = 0;
2638       else
2639         cluster_size = length + needed;
2640     }
2641     if (demux->cluster_time != GST_CLOCK_TIME_NONE &&
2642         cluster_time == GST_CLOCK_TIME_NONE) {
2643       cluster_time = demux->cluster_time * demux->time_scale;
2644       cluster_offset = demux->cluster_offset;
2645       GST_DEBUG_OBJECT (demux, "found cluster at offset %" G_GINT64_FORMAT
2646           " with time %" GST_TIME_FORMAT, cluster_offset,
2647           GST_TIME_ARGS (cluster_time));
2648       if (cluster_time > time) {
2649         GST_DEBUG_OBJECT (demux, "overshot target");
2650         /* cluster overshoots */
2651         if (cluster_offset == demux->first_cluster_offset) {
2652           /* but no prev one */
2653           GST_DEBUG_OBJECT (demux, "but using first cluster anyway");
2654           prev_cluster_time = cluster_time;
2655           prev_cluster_offset = cluster_offset;
2656           break;
2657         }
2658         if (prev_cluster_time != GST_CLOCK_TIME_NONE) {
2659           /* prev cluster did not overshoot, so prev cluster is target */
2660           break;
2661         } else {
2662           /* re-estimate using this new position info */
2663           opos = cluster_offset;
2664           otime = cluster_time;
2665           goto retry;
2666         }
2667       } else {
2668         /* cluster undershoots, goto next one */
2669         prev_cluster_time = cluster_time;
2670         prev_cluster_offset = cluster_offset;
2671         /* skip cluster if length is defined,
2672          * otherwise will be skippingly parsed into */
2673         if (cluster_size) {
2674           GST_DEBUG_OBJECT (demux, "skipping to next cluster");
2675           demux->offset = cluster_offset + cluster_size;
2676           demux->cluster_time = GST_CLOCK_TIME_NONE;
2677         } else {
2678           GST_DEBUG_OBJECT (demux, "parsing/skipping cluster elements");
2679         }
2680       }
2681     }
2682     continue;
2683
2684   error:
2685     if (ret == GST_FLOW_UNEXPECTED) {
2686       if (prev_cluster_time != GST_CLOCK_TIME_NONE)
2687         break;
2688     }
2689     goto exit;
2690   }
2691
2692   entry = g_new0 (GstMatroskaIndex, 1);
2693   entry->time = prev_cluster_time;
2694   entry->pos = prev_cluster_offset - demux->ebml_segment_start;
2695   GST_DEBUG_OBJECT (demux, "simulated index entry; time %" GST_TIME_FORMAT
2696       ", pos %" G_GUINT64_FORMAT, GST_TIME_ARGS (entry->time), entry->pos);
2697
2698 exit:
2699   if (buf)
2700     gst_buffer_unref (buf);
2701
2702   /* restore some state */
2703   demux->cluster_offset = current_cluster_offset;
2704   demux->cluster_time = current_cluster_time;
2705   demux->offset = current_offset;
2706   demux->state = current_state;
2707
2708   return entry;
2709 }
2710
2711 static gboolean
2712 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
2713     GstPad * pad, GstEvent * event)
2714 {
2715   GstMatroskaIndex *entry = NULL;
2716   GstMatroskaIndex scan_entry;
2717 #ifdef MKVDEMUX_MODIFICATION
2718   GstMatroskaIndex *next_entry = NULL;
2719 #endif
2720   GstSeekFlags flags;
2721   GstSeekType cur_type, stop_type;
2722   GstFormat format;
2723   gboolean flush, keyunit;
2724   gdouble rate;
2725   gint64 cur, stop;
2726   gint i;
2727   GstMatroskaTrackContext *track = NULL;
2728   GstSegment seeksegment = { 0, };
2729   gboolean update;
2730   guint64 offset;
2731
2732   if (pad)
2733     track = gst_pad_get_element_private (pad);
2734
2735     //track = gst_matroska_demux_get_seek_track (demux, track);
2736
2737   gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2738       &stop_type, &stop);
2739
2740   /* we can only seek on time */
2741   if (format != GST_FORMAT_TIME) {
2742     GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2743     return FALSE;
2744   }
2745
2746 #ifndef MKVDEMUX_MODIFICATION
2747   /* cannot yet do backwards playback */
2748   if (rate <= 0.0) {
2749     GST_DEBUG_OBJECT (demux, "Can only seek with positive rate");
2750     return FALSE;
2751   }
2752 #endif
2753   /* copy segment, we need this because we still need the old
2754    * segment when we close the current segment. */
2755   memcpy (&seeksegment, &demux->segment, sizeof (GstSegment));
2756
2757   if (event) {
2758     GST_DEBUG_OBJECT (demux, "configuring seek");
2759     gst_segment_set_seek (&seeksegment, rate, format, flags,
2760         cur_type, cur, stop_type, stop, &update);
2761   }
2762
2763   GST_INFO_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
2764
2765   /* check sanity before we start flushing and all that */
2766   GST_OBJECT_LOCK (demux);
2767
2768         if ((entry =
2769           gst_matroskademux_do_index_seek (demux, track,
2770               seeksegment.last_stop, -1, FALSE)) == NULL) {
2771         /* pull mode without index can scan later on */
2772         
2773         GST_INFO_OBJECT (demux, "No matching seek entry in index");
2774         GST_OBJECT_UNLOCK (demux);
2775         return FALSE;
2776                 }
2777 #ifdef MKVDEMUX_MODIFICATION
2778   if (seeksegment.rate < 0.0)
2779   {
2780     next_entry = gst_matroskademux_get_next_index (demux, track, entry);
2781     if (next_entry == NULL)
2782     {
2783         GST_ERROR ("Entry Not found....");
2784         return FALSE;
2785     }
2786   }
2787 #endif  
2788   GST_DEBUG_OBJECT (demux, "Seek position looks sane");
2789   GST_OBJECT_UNLOCK (demux);
2790
2791   if (demux->streaming) {
2792     /* need to seek to cluster start to pick up cluster time */
2793     /* upstream takes care of flushing and all that
2794      * ... and newsegment event handling takes care of the rest */
2795     return perform_seek_to_offset (demux,
2796         entry->pos + demux->ebml_segment_start);
2797   }
2798
2799   flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
2800   keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
2801
2802 #ifdef MKVDEMUX_MODIFICATION
2803   keyunit = TRUE;//intentionally making it as true
2804 #endif  
2805
2806   if (flush) {
2807     gst_pad_push_event (demux->sinkpad, gst_event_new_flush_start ());
2808     gst_matroska_demux_send_event (demux, gst_event_new_flush_start ());
2809   } else {
2810     gst_pad_pause_task (demux->sinkpad);
2811   }
2812
2813   /* now grab the stream lock so that streaming cannot continue, for
2814    * non flushing seeks when the element is in PAUSED this could block
2815    * forever. */
2816   GST_INFO_OBJECT (demux, "Waiting for streaming to stop");
2817   GST_PAD_STREAM_LOCK (demux->sinkpad);
2818
2819   if (!demux->streaming && !demux->index)
2820   {
2821
2822
2823         GST_OBJECT_LOCK (demux);
2824
2825         offset =  entry->pos + demux->ebml_segment_start;
2826         if (offset >= gst_matroska_demux_get_length(demux))
2827         {
2828                 GST_INFO_OBJECT (demux, " Seek failed");
2829                 goto seek_error;
2830         }
2831         demux->offset = offset;
2832
2833          GST_OBJECT_UNLOCK (demux);
2834          
2835    }
2836
2837   if (keyunit) {
2838     GST_INFO_OBJECT (demux, "seek to key unit, adjusting segment start to %"
2839         GST_TIME_FORMAT, GST_TIME_ARGS (entry->time));
2840 #ifdef MKVDEMUX_MODIFICATION
2841     if (seeksegment.stop == -1)
2842     {
2843        seeksegment.stop = seeksegment.duration;
2844     }
2845     if (seeksegment.rate > 0.0)
2846     {
2847 #endif
2848     seeksegment.start = entry->time;
2849     seeksegment.last_stop = entry->time;
2850     seeksegment.time = entry->time;
2851 #ifdef MKVDEMUX_MODIFICATION
2852     }
2853     else if (seeksegment.rate < 0.0) /* Reverse trick play */
2854     {
2855        seeksegment.start = 0.0;
2856         seeksegment.stop = next_entry->time;
2857         seeksegment.last_stop = next_entry->time;
2858         seeksegment.time = 0.0;
2859     }
2860 #endif
2861   }
2862
2863  
2864
2865   if (flush) {
2866     GST_DEBUG_OBJECT (demux, "Stopping flush");
2867     gst_pad_push_event (demux->sinkpad, gst_event_new_flush_stop ());
2868     gst_matroska_demux_send_event (demux, gst_event_new_flush_stop ());
2869   } else if (demux->segment_running) {
2870     GST_DEBUG_OBJECT (demux, "Closing currently running segment");
2871
2872     GST_OBJECT_LOCK (demux);
2873     if (demux->close_segment)
2874       gst_event_unref (demux->close_segment);
2875
2876     demux->close_segment = gst_event_new_new_segment (TRUE,
2877         demux->segment.rate, GST_FORMAT_TIME, demux->segment.start,
2878         demux->segment.last_stop, demux->segment.time);
2879     GST_OBJECT_UNLOCK (demux);
2880   }
2881
2882   GST_OBJECT_LOCK (demux);
2883   /* now update the real segment info */
2884   memcpy (&demux->segment, &seeksegment, sizeof (GstSegment));
2885   GST_OBJECT_UNLOCK (demux);
2886
2887   /* update some (segment) state */
2888   if (!gst_matroska_demux_move_to_entry (demux, entry, TRUE))
2889     goto seek_error;
2890
2891   /* notify start of new segment */
2892   if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2893     GstMessage *msg;
2894
2895     msg = gst_message_new_segment_start (GST_OBJECT (demux),
2896         GST_FORMAT_TIME, demux->segment.start);
2897     gst_element_post_message (GST_ELEMENT (demux), msg);
2898   }
2899
2900   GST_OBJECT_LOCK (demux);
2901   if (demux->new_segment)
2902     gst_event_unref (demux->new_segment);
2903 #ifdef MKVDEMUX_MODIFICATION
2904   if (demux->segment.rate > 0.0)
2905   {
2906 #endif
2907         demux->new_segment = gst_event_new_new_segment_full (FALSE,
2908                 demux->segment.rate, demux->segment.applied_rate, demux->segment.format,
2909                 demux->segment.last_stop, demux->segment.stop, demux->segment.time);
2910 #ifdef MKVDEMUX_MODIFICATION
2911   }
2912   else if (demux->segment.rate < 0.0)
2913   {
2914         /* Reverse trick play */
2915         demux->new_segment = gst_event_new_new_segment_full (FALSE,
2916                 demux->segment.rate, demux->segment.applied_rate, demux->segment.format,
2917                 demux->segment.start, demux->segment.last_stop, demux->segment.time);
2918   }
2919 #endif
2920   GST_OBJECT_UNLOCK (demux);
2921
2922   /* update the time */
2923   g_assert (demux->src->len == demux->num_streams);
2924   for (i = 0; i < demux->src->len; i++) {
2925     GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
2926     context->pos = entry->time;
2927     context->set_discont = TRUE;
2928     context->last_flow = GST_FLOW_OK;
2929     context->eos = FALSE;
2930   }
2931 #ifdef MKVDEMUX_MODIFICATION
2932   if (demux->segment.rate > 0.0)
2933   {
2934 #endif
2935         demux->segment.last_stop = entry->time;
2936 #ifdef MKVDEMUX_MODIFICATION
2937   }
2938   else if (demux->segment.rate < 0.0)
2939   {
2940         demux->segment.last_stop = next_entry->time;
2941   }
2942  #endif
2943   demux->seek_block = entry->block;
2944   demux->last_stop_end = GST_CLOCK_TIME_NONE;
2945
2946   /* restart our task since it might have been stopped when we did the
2947    * flush. */
2948   demux->segment_running = TRUE;
2949   gst_pad_start_task (demux->sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
2950       demux->sinkpad);
2951   
2952 #ifdef MKVDEMUX_MODIFICATION
2953   track->found_key_frame = FALSE;
2954   track->intra_gap = 0;
2955   while (!g_queue_is_empty (track->queue)) {
2956         GstBuffer* buf = g_queue_pop_head (track->queue);
2957         gst_buffer_unref (buf);
2958   }
2959 #endif
2960
2961   /* streaming can continue now */
2962   GST_PAD_STREAM_UNLOCK (demux->sinkpad);
2963
2964   return TRUE;
2965
2966 seek_error:
2967   {
2968     GST_PAD_STREAM_UNLOCK (demux->sinkpad);
2969     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
2970     return FALSE;
2971   }
2972 }
2973
2974 /*
2975  * Handle whether we can perform the seek event or if we have to let the chain
2976  * function handle seeks to build the seek indexes first.
2977  */
2978 static gboolean
2979 gst_matroska_demux_handle_seek_push (GstMatroskaDemux * demux, GstPad * pad,
2980     GstEvent * event)
2981 {
2982   GstSeekFlags flags;
2983   GstSeekType cur_type, stop_type;
2984   GstFormat format;
2985   gdouble rate;
2986   gint64 cur, stop;
2987
2988   gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2989       &stop_type, &stop);
2990
2991   /* sanity checks */
2992
2993   /* we can only seek on time */
2994   if (format != GST_FORMAT_TIME) {
2995     GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
2996     return FALSE;
2997   }
2998
2999   if (stop_type != GST_SEEK_TYPE_NONE && stop != GST_CLOCK_TIME_NONE) {
3000     GST_DEBUG_OBJECT (demux, "Seek end-time not supported in streaming mode");
3001     return FALSE;
3002   }
3003
3004   if (!(flags & GST_SEEK_FLAG_FLUSH)) {
3005     GST_DEBUG_OBJECT (demux,
3006         "Non-flushing seek not supported in streaming mode");
3007     return FALSE;
3008   }
3009
3010   if (flags & GST_SEEK_FLAG_SEGMENT) {
3011     GST_DEBUG_OBJECT (demux, "Segment seek not supported in streaming mode");
3012     return FALSE;
3013   }
3014
3015   /* check for having parsed index already */
3016   if (!demux->index_parsed) {
3017     gboolean building_index;
3018     guint64 offset = 0;
3019
3020     if (!demux->index_offset) {
3021       GST_DEBUG_OBJECT (demux, "no index (location); no seek in push mode");
3022       return FALSE;
3023     }
3024
3025     GST_OBJECT_LOCK (demux);
3026     /* handle the seek event in the chain function */
3027     demux->state = GST_MATROSKA_DEMUX_STATE_SEEK;
3028     /* no more seek can be issued until state reset to _DATA */
3029
3030     /* copy the event */
3031     if (demux->seek_event)
3032       gst_event_unref (demux->seek_event);
3033     demux->seek_event = gst_event_ref (event);
3034
3035     /* set the building_index flag so that only one thread can setup the
3036      * structures for index seeking. */
3037     building_index = demux->building_index;
3038     if (!building_index) {
3039       demux->building_index = TRUE;
3040       offset = demux->index_offset;
3041     }
3042     GST_OBJECT_UNLOCK (demux);
3043
3044     if (!building_index) {
3045       /* seek to the first subindex or legacy index */
3046       GST_INFO_OBJECT (demux, "Seeking to Cues at %" G_GUINT64_FORMAT, offset);
3047       return perform_seek_to_offset (demux, offset);
3048     }
3049
3050     /* well, we are handling it already */
3051     return TRUE;
3052   }
3053
3054   /* delegate to tweaked regular seek */
3055   return gst_matroska_demux_handle_seek_event (demux, pad, event);
3056 }
3057
3058 static gboolean
3059 gst_matroska_demux_handle_src_event (GstPad * pad, GstEvent * event)
3060 {
3061   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
3062   gboolean res = TRUE;
3063
3064   switch (GST_EVENT_TYPE (event)) {
3065     case GST_EVENT_SEEK:
3066       /* no seeking until we are (safely) ready */
3067       if (demux->state != GST_MATROSKA_DEMUX_STATE_DATA) {
3068         GST_DEBUG_OBJECT (demux, "not ready for seeking yet");
3069         return FALSE;
3070       }
3071       if (!demux->streaming)
3072         res = gst_matroska_demux_handle_seek_event (demux, pad, event);
3073       else
3074         res = gst_matroska_demux_handle_seek_push (demux, pad, event);
3075       gst_event_unref (event);
3076       break;
3077
3078     case GST_EVENT_QOS:
3079     {
3080       GstMatroskaTrackContext *context = gst_pad_get_element_private (pad);
3081       if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
3082         GstMatroskaTrackVideoContext *videocontext =
3083             (GstMatroskaTrackVideoContext *) context;
3084         gdouble proportion;
3085         GstClockTimeDiff diff;
3086         GstClockTime timestamp;
3087
3088         gst_event_parse_qos (event, &proportion, &diff, &timestamp);
3089
3090         GST_OBJECT_LOCK (demux);
3091         videocontext->earliest_time = timestamp + diff;
3092         GST_OBJECT_UNLOCK (demux);
3093       }
3094       res = TRUE;
3095       gst_event_unref (event);
3096       break;
3097     }
3098
3099       /* events we don't need to handle */
3100     case GST_EVENT_NAVIGATION:
3101       gst_event_unref (event);
3102       res = FALSE;
3103       break;
3104
3105     case GST_EVENT_LATENCY:
3106     default:
3107       res = gst_pad_push_event (demux->sinkpad, event);
3108       break;
3109   }
3110
3111   gst_object_unref (demux);
3112
3113   return res;
3114 }
3115
3116 static GstFlowReturn
3117 gst_matroska_demux_seek_to_previous_keyframe (GstMatroskaDemux * demux)
3118 {
3119   GstFlowReturn ret = GST_FLOW_UNEXPECTED;
3120   gboolean done = TRUE;
3121   gint i;
3122
3123   g_return_val_if_fail (demux->seek_index, GST_FLOW_UNEXPECTED);
3124   g_return_val_if_fail (demux->seek_entry < demux->seek_index->len,
3125       GST_FLOW_UNEXPECTED);
3126
3127   GST_DEBUG_OBJECT (demux, "locating previous keyframe");
3128
3129   if (!demux->seek_entry) {
3130     GST_DEBUG_OBJECT (demux, "no earlier index entry");
3131     goto exit;
3132   }
3133
3134   for (i = 0; i < demux->src->len; i++) {
3135     GstMatroskaTrackContext *stream = g_ptr_array_index (demux->src, i);
3136
3137     GST_DEBUG_OBJECT (demux, "segment start %" GST_TIME_FORMAT
3138         ", stream %d at %" GST_TIME_FORMAT,
3139         GST_TIME_ARGS (demux->segment.start), stream->index,
3140         GST_TIME_ARGS (stream->from_time));
3141     if (GST_CLOCK_TIME_IS_VALID (stream->from_time)) {
3142       if (stream->from_time > demux->segment.start) {
3143         GST_DEBUG_OBJECT (demux, "stream %d not finished yet", stream->index);
3144         done = FALSE;
3145       }
3146     } else {
3147       /* nothing pushed for this stream;
3148        * likely seek entry did not start at keyframe, so all was skipped.
3149        * So we need an earlier entry */
3150       done = FALSE;
3151     }
3152   }
3153
3154   if (!done) {
3155     GstMatroskaIndex *entry;
3156
3157     entry = &g_array_index (demux->seek_index, GstMatroskaIndex,
3158         --demux->seek_entry);
3159     if (!gst_matroska_demux_move_to_entry (demux, entry, FALSE))
3160       goto exit;
3161
3162     ret = GST_FLOW_OK;
3163   }
3164
3165 exit:
3166   return ret;
3167 }
3168
3169 /* skip unknown or alike element */
3170 static GstFlowReturn
3171 gst_matroska_demux_parse_skip (GstMatroskaDemux * demux, GstEbmlRead * ebml,
3172     const gchar * parent_name, guint id)
3173 {
3174   if (id == GST_EBML_ID_VOID) {
3175     GST_DEBUG_OBJECT (demux, "Skipping EBML Void element");
3176   } else if (id == GST_EBML_ID_CRC32) {
3177     GST_DEBUG_OBJECT (demux, "Skipping EBML CRC32 element");
3178   } else {
3179     GST_WARNING_OBJECT (demux,
3180         "Unknown %s subelement 0x%x - ignoring", parent_name, id);
3181   }
3182
3183   return gst_ebml_read_skip (ebml);
3184 }
3185
3186 static GstFlowReturn
3187 gst_matroska_demux_parse_header (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3188 {
3189   GstFlowReturn ret;
3190   gchar *doctype;
3191   guint version;
3192   guint32 id;
3193
3194   /* this function is the first to be called */
3195
3196   /* default init */
3197   doctype = NULL;
3198   version = 1;
3199
3200   ret = gst_ebml_peek_id (ebml, &id);
3201   if (ret != GST_FLOW_OK)
3202     return ret;
3203
3204   GST_DEBUG_OBJECT (demux, "id: %08x", id);
3205
3206   if (id != GST_EBML_ID_HEADER) {
3207     GST_ERROR_OBJECT (demux, "Failed to read header");
3208     goto exit;
3209   }
3210
3211   ret = gst_ebml_read_master (ebml, &id);
3212   if (ret != GST_FLOW_OK)
3213     return ret;
3214
3215   while (gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3216     ret = gst_ebml_peek_id (ebml, &id);
3217     if (ret != GST_FLOW_OK)
3218       return ret;
3219
3220     switch (id) {
3221         /* is our read version uptodate? */
3222       case GST_EBML_ID_EBMLREADVERSION:{
3223         guint64 num;
3224
3225         ret = gst_ebml_read_uint (ebml, &id, &num);
3226         if (ret != GST_FLOW_OK)
3227           return ret;
3228         if (num != GST_EBML_VERSION) {
3229           GST_ERROR_OBJECT (ebml, "Unsupported EBML version %" G_GUINT64_FORMAT,
3230               num);
3231           return GST_FLOW_ERROR;
3232         }
3233
3234         GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
3235         break;
3236       }
3237
3238         /* we only handle 8 byte lengths at max */
3239       case GST_EBML_ID_EBMLMAXSIZELENGTH:{
3240         guint64 num;
3241
3242         ret = gst_ebml_read_uint (ebml, &id, &num);
3243         if (ret != GST_FLOW_OK)
3244           return ret;
3245         if (num > sizeof (guint64)) {
3246           GST_ERROR_OBJECT (ebml,
3247               "Unsupported EBML maximum size %" G_GUINT64_FORMAT, num);
3248           return GST_FLOW_ERROR;
3249         }
3250         GST_DEBUG_OBJECT (ebml, "EbmlMaxSizeLength: %" G_GUINT64_FORMAT, num);
3251         break;
3252       }
3253
3254         /* we handle 4 byte IDs at max */
3255       case GST_EBML_ID_EBMLMAXIDLENGTH:{
3256         guint64 num;
3257
3258         ret = gst_ebml_read_uint (ebml, &id, &num);
3259         if (ret != GST_FLOW_OK)
3260           return ret;
3261         if (num > sizeof (guint32)) {
3262           GST_ERROR_OBJECT (ebml,
3263               "Unsupported EBML maximum ID %" G_GUINT64_FORMAT, num);
3264           return GST_FLOW_ERROR;
3265         }
3266         GST_DEBUG_OBJECT (ebml, "EbmlMaxIdLength: %" G_GUINT64_FORMAT, num);
3267         break;
3268       }
3269
3270       case GST_EBML_ID_DOCTYPE:{
3271         gchar *text;
3272
3273         ret = gst_ebml_read_ascii (ebml, &id, &text);
3274         if (ret != GST_FLOW_OK)
3275           return ret;
3276
3277         GST_DEBUG_OBJECT (ebml, "EbmlDocType: %s", GST_STR_NULL (text));
3278
3279         if (doctype)
3280           g_free (doctype);
3281         doctype = text;
3282         break;
3283       }
3284
3285       case GST_EBML_ID_DOCTYPEREADVERSION:{
3286         guint64 num;
3287
3288         ret = gst_ebml_read_uint (ebml, &id, &num);
3289         if (ret != GST_FLOW_OK)
3290           return ret;
3291         version = num;
3292         GST_DEBUG_OBJECT (ebml, "EbmlReadVersion: %" G_GUINT64_FORMAT, num);
3293         break;
3294       }
3295
3296       default:
3297         ret = gst_matroska_demux_parse_skip (demux, ebml, "EBML header", id);
3298         if (ret != GST_FLOW_OK)
3299           return ret;
3300         break;
3301
3302         /* we ignore these two, as they don't tell us anything we care about */
3303       case GST_EBML_ID_EBMLVERSION:
3304       case GST_EBML_ID_DOCTYPEVERSION:
3305         ret = gst_ebml_read_skip (ebml);
3306         if (ret != GST_FLOW_OK)
3307           return ret;
3308         break;
3309     }
3310   }
3311
3312 exit:
3313
3314   if ((doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_MATROSKA)) ||
3315       (doctype != NULL && !strcmp (doctype, GST_MATROSKA_DOCTYPE_WEBM)) ||
3316       (doctype == NULL)) {
3317     if (version <= 2) {
3318       if (doctype) {
3319         GST_INFO_OBJECT (demux, "Input is %s version %d", doctype, version);
3320       } else {
3321         GST_WARNING_OBJECT (demux, "Input is EBML without doctype, assuming "
3322             "matroska (version %d)", version);
3323       }
3324       ret = GST_FLOW_OK;
3325     } else {
3326       GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3327           ("Demuxer version (2) is too old to read %s version %d",
3328               GST_STR_NULL (doctype), version));
3329       ret = GST_FLOW_ERROR;
3330     }
3331     g_free (doctype);
3332   } else {
3333     GST_ELEMENT_ERROR (demux, STREAM, WRONG_TYPE, (NULL),
3334         ("Input is not a matroska stream (doctype=%s)", doctype));
3335     ret = GST_FLOW_ERROR;
3336     g_free (doctype);
3337   }
3338
3339   return ret;
3340 }
3341
3342 static GstFlowReturn
3343 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3344 {
3345   GstFlowReturn ret = GST_FLOW_OK;
3346   guint32 id;
3347
3348   DEBUG_ELEMENT_START (demux, ebml, "Tracks");
3349
3350   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3351     DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3352     return ret;
3353   }
3354
3355   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3356     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3357       break;
3358
3359     switch (id) {
3360         /* one track within the "all-tracks" header */
3361       case GST_MATROSKA_ID_TRACKENTRY:
3362         ret = gst_matroska_demux_add_stream (demux, ebml);
3363         break;
3364
3365       default:
3366         ret = gst_matroska_demux_parse_skip (demux, ebml, "Track", id);
3367         break;
3368     }
3369   }
3370   DEBUG_ELEMENT_STOP (demux, ebml, "Tracks", ret);
3371
3372   demux->tracks_parsed = TRUE;
3373
3374   return ret;
3375 }
3376
3377 static GstFlowReturn
3378 gst_matroska_demux_parse_index_cuetrack (GstMatroskaDemux * demux,
3379     GstEbmlRead * ebml, guint * nentries)
3380 {
3381   guint32 id;
3382   GstFlowReturn ret;
3383   GstMatroskaIndex idx;
3384
3385   idx.pos = (guint64) - 1;
3386   idx.track = 0;
3387   idx.time = GST_CLOCK_TIME_NONE;
3388   idx.block = 1;
3389
3390   DEBUG_ELEMENT_START (demux, ebml, "CueTrackPositions");
3391
3392   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3393     DEBUG_ELEMENT_STOP (demux, ebml, "CueTrackPositions", ret);
3394     return ret;
3395   }
3396
3397   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3398     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3399       break;
3400
3401     switch (id) {
3402         /* track number */
3403       case GST_MATROSKA_ID_CUETRACK:
3404       {
3405         guint64 num;
3406
3407         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
3408           break;
3409
3410         if (num == 0) {
3411           idx.track = 0;
3412           GST_WARNING_OBJECT (demux, "Invalid CueTrack 0");
3413           break;
3414         }
3415
3416         GST_DEBUG_OBJECT (demux, "CueTrack: %" G_GUINT64_FORMAT, num);
3417         idx.track = num;
3418         break;
3419       }
3420
3421         /* position in file */
3422       case GST_MATROSKA_ID_CUECLUSTERPOSITION:
3423       {
3424         guint64 num;
3425
3426         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
3427           break;
3428
3429         if (num > G_MAXINT64) {
3430           GST_WARNING_OBJECT (demux, "CueClusterPosition %" G_GUINT64_FORMAT
3431               " too large", num);
3432           break;
3433         }
3434
3435         idx.pos = num;
3436         break;
3437       }
3438
3439         /* number of block in the cluster */
3440       case GST_MATROSKA_ID_CUEBLOCKNUMBER:
3441       {
3442         guint64 num;
3443
3444         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
3445           break;
3446
3447         if (num == 0) {
3448           GST_WARNING_OBJECT (demux, "Invalid CueBlockNumber 0");
3449           break;
3450         }
3451
3452         GST_DEBUG_OBJECT (demux, "CueBlockNumber: %" G_GUINT64_FORMAT, num);
3453         idx.block = num;
3454
3455         /* mild sanity check, disregard strange cases ... */
3456         if (idx.block > G_MAXUINT16) {
3457           GST_DEBUG_OBJECT (demux, "... looks suspicious, ignoring");
3458           idx.block = 1;
3459         }
3460         break;
3461       }
3462
3463       default:
3464         ret = gst_matroska_demux_parse_skip (demux, ebml, "CueTrackPositions",
3465             id);
3466         break;
3467
3468       case GST_MATROSKA_ID_CUECODECSTATE:
3469       case GST_MATROSKA_ID_CUEREFERENCE:
3470         ret = gst_ebml_read_skip (ebml);
3471         break;
3472     }
3473   }
3474
3475   DEBUG_ELEMENT_STOP (demux, ebml, "CueTrackPositions", ret);
3476
3477   if ((ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED)
3478       && idx.pos != (guint64) - 1 && idx.track > 0) {
3479     g_array_append_val (demux->index, idx);
3480     (*nentries)++;
3481   } else if (ret == GST_FLOW_OK || ret == GST_FLOW_UNEXPECTED) {
3482     GST_DEBUG_OBJECT (demux, "CueTrackPositions without valid content");
3483   }
3484
3485   return ret;
3486 }
3487
3488 static GstFlowReturn
3489 gst_matroska_demux_parse_index_pointentry (GstMatroskaDemux * demux,
3490     GstEbmlRead * ebml)
3491 {
3492   guint32 id;
3493   GstFlowReturn ret;
3494   GstClockTime time = GST_CLOCK_TIME_NONE;
3495   guint nentries = 0;
3496
3497   DEBUG_ELEMENT_START (demux, ebml, "CuePoint");
3498
3499   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3500     DEBUG_ELEMENT_STOP (demux, ebml, "CuePoint", ret);
3501     return ret;
3502   }
3503
3504   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3505     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3506       break;
3507
3508     switch (id) {
3509         /* one single index entry ('point') */
3510       case GST_MATROSKA_ID_CUETIME:
3511       {
3512         if ((ret = gst_ebml_read_uint (ebml, &id, &time)) != GST_FLOW_OK)
3513           break;
3514
3515         GST_DEBUG_OBJECT (demux, "CueTime: %" G_GUINT64_FORMAT, time);
3516         time = time * demux->time_scale;
3517         break;
3518       }
3519
3520         /* position in the file + track to which it belongs */
3521       case GST_MATROSKA_ID_CUETRACKPOSITIONS:
3522       {
3523         if ((ret =
3524                 gst_matroska_demux_parse_index_cuetrack (demux, ebml,
3525                     &nentries)) != GST_FLOW_OK)
3526           break;
3527         break;
3528       }
3529
3530       default:
3531         ret = gst_matroska_demux_parse_skip (demux, ebml, "CuePoint", id);
3532         break;
3533     }
3534   }
3535
3536   DEBUG_ELEMENT_STOP (demux, ebml, "CuePoint", ret);
3537
3538   if (nentries > 0) {
3539     if (time == GST_CLOCK_TIME_NONE) {
3540       GST_WARNING_OBJECT (demux, "CuePoint without valid time");
3541       g_array_remove_range (demux->index, demux->index->len - nentries,
3542           nentries);
3543     } else {
3544       gint i;
3545
3546       for (i = demux->index->len - nentries; i < demux->index->len; i++) {
3547         GstMatroskaIndex *idx =
3548             &g_array_index (demux->index, GstMatroskaIndex, i);
3549
3550         idx->time = time;
3551         GST_DEBUG_OBJECT (demux, "Index entry: pos=%" G_GUINT64_FORMAT
3552             ", time=%" GST_TIME_FORMAT ", track=%u, block=%u", idx->pos,
3553             GST_TIME_ARGS (idx->time), (guint) idx->track, (guint) idx->block);
3554       }
3555     }
3556   } else {
3557     GST_DEBUG_OBJECT (demux, "Empty CuePoint");
3558   }
3559
3560   return ret;
3561 }
3562
3563 static gint
3564 gst_matroska_index_compare (GstMatroskaIndex * i1, GstMatroskaIndex * i2)
3565 {
3566   if (i1->time < i2->time)
3567     return -1;
3568   else if (i1->time > i2->time)
3569     return 1;
3570   else if (i1->block < i2->block)
3571     return -1;
3572   else if (i1->block > i2->block)
3573     return 1;
3574   else
3575     return 0;
3576 }
3577
3578 static GstFlowReturn
3579 gst_matroska_demux_parse_index (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3580 {
3581   guint32 id;
3582   GstFlowReturn ret = GST_FLOW_OK;
3583   guint i;
3584
3585   if (demux->index)
3586     g_array_free (demux->index, TRUE);
3587   demux->index =
3588       g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
3589
3590   DEBUG_ELEMENT_START (demux, ebml, "Cues");
3591
3592   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3593     DEBUG_ELEMENT_STOP (demux, ebml, "Cues", ret);
3594     return ret;
3595   }
3596
3597   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3598     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3599       break;
3600
3601     switch (id) {
3602         /* one single index entry ('point') */
3603       case GST_MATROSKA_ID_POINTENTRY:
3604         ret = gst_matroska_demux_parse_index_pointentry (demux, ebml);
3605         break;
3606
3607       default:
3608         ret = gst_matroska_demux_parse_skip (demux, ebml, "Cues", id);
3609         break;
3610     }
3611   }
3612   DEBUG_ELEMENT_STOP (demux, ebml, "Cues", ret);
3613
3614   /* Sort index by time, smallest time first, for easier searching */
3615   g_array_sort (demux->index, (GCompareFunc) gst_matroska_index_compare);
3616
3617   /* Now sort the track specific index entries into their own arrays */
3618   for (i = 0; i < demux->index->len; i++) {
3619     GstMatroskaIndex *idx = &g_array_index (demux->index, GstMatroskaIndex, i);
3620     gint track_num;
3621     GstMatroskaTrackContext *ctx;
3622
3623     if (demux->element_index) {
3624       gint writer_id;
3625
3626       if (idx->track != 0 &&
3627           (track_num =
3628               gst_matroska_demux_stream_from_num (demux, idx->track)) != -1) {
3629         ctx = g_ptr_array_index (demux->src, track_num);
3630
3631         if (ctx->index_writer_id == -1)
3632           gst_index_get_writer_id (demux->element_index, GST_OBJECT (ctx->pad),
3633               &ctx->index_writer_id);
3634         writer_id = ctx->index_writer_id;
3635       } else {
3636         if (demux->element_index_writer_id == -1)
3637           gst_index_get_writer_id (demux->element_index, GST_OBJECT (demux),
3638               &demux->element_index_writer_id);
3639         writer_id = demux->element_index_writer_id;
3640       }
3641
3642       GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
3643           G_GUINT64_FORMAT " for writer id %d", GST_TIME_ARGS (idx->time),
3644           idx->pos, writer_id);
3645       gst_index_add_association (demux->element_index, writer_id,
3646           GST_ASSOCIATION_FLAG_KEY_UNIT, GST_FORMAT_TIME, idx->time,
3647           GST_FORMAT_BYTES, idx->pos + demux->ebml_segment_start, NULL);
3648     }
3649
3650     if (idx->track == 0)
3651       continue;
3652
3653     track_num = gst_matroska_demux_stream_from_num (demux, idx->track);
3654     if (track_num == -1)
3655       continue;
3656
3657     ctx = g_ptr_array_index (demux->src, track_num);
3658
3659     if (ctx->index_table == NULL)
3660       ctx->index_table =
3661           g_array_sized_new (FALSE, FALSE, sizeof (GstMatroskaIndex), 128);
3662
3663     g_array_append_vals (ctx->index_table, idx, 1);
3664   }
3665
3666   demux->index_parsed = TRUE;
3667
3668   /* sanity check; empty index normalizes to no index */
3669   if (demux->index->len == 0) {
3670     g_array_free (demux->index, TRUE);
3671     demux->index = NULL;
3672   }
3673
3674   return ret;
3675 }
3676
3677 static GstFlowReturn
3678 gst_matroska_demux_parse_info (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3679 {
3680   GstFlowReturn ret = GST_FLOW_OK;
3681   guint32 id;
3682
3683   DEBUG_ELEMENT_START (demux, ebml, "SegmentInfo");
3684
3685   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3686     DEBUG_ELEMENT_STOP (demux, ebml, "SegmentInfo", ret);
3687     return ret;
3688   }
3689
3690   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3691     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3692       break;
3693
3694     switch (id) {
3695         /* cluster timecode */
3696       case GST_MATROSKA_ID_TIMECODESCALE:{
3697         guint64 num;
3698
3699         if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
3700           break;
3701
3702
3703         GST_DEBUG_OBJECT (demux, "TimeCodeScale: %" G_GUINT64_FORMAT, num);
3704         demux->time_scale = num;
3705         break;
3706       }
3707
3708       case GST_MATROSKA_ID_DURATION:{
3709         gdouble num;
3710         GstClockTime dur;
3711
3712         if ((ret = gst_ebml_read_float (ebml, &id, &num)) != GST_FLOW_OK)
3713           break;
3714
3715         if (num <= 0.0) {
3716           GST_WARNING_OBJECT (demux, "Invalid duration %lf", num);
3717           break;
3718         }
3719
3720         GST_DEBUG_OBJECT (demux, "Duration: %lf", num);
3721
3722         dur = gst_gdouble_to_guint64 (num *
3723             gst_guint64_to_gdouble (demux->time_scale));
3724         if (GST_CLOCK_TIME_IS_VALID (dur) && dur <= G_MAXINT64)
3725         {
3726           demux->duration = dur;
3727 #ifdef MKVDEMUX_MODIFICATION
3728           gst_segment_set_duration (&demux->segment, GST_FORMAT_TIME, demux->duration); 
3729 #endif
3730         }
3731         break;
3732       }
3733
3734       case GST_MATROSKA_ID_WRITINGAPP:{
3735         gchar *text;
3736
3737         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
3738           break;
3739
3740         GST_DEBUG_OBJECT (demux, "WritingApp: %s", GST_STR_NULL (text));
3741         demux->writing_app = text;
3742         break;
3743       }
3744
3745       case GST_MATROSKA_ID_MUXINGAPP:{
3746         gchar *text;
3747
3748         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
3749           break;
3750
3751         GST_DEBUG_OBJECT (demux, "MuxingApp: %s", GST_STR_NULL (text));
3752         demux->muxing_app = text;
3753         break;
3754       }
3755
3756       case GST_MATROSKA_ID_DATEUTC:{
3757         gint64 time;
3758
3759         if ((ret = gst_ebml_read_date (ebml, &id, &time)) != GST_FLOW_OK)
3760           break;
3761
3762         GST_DEBUG_OBJECT (demux, "DateUTC: %" G_GINT64_FORMAT, time);
3763         demux->created = time;
3764         break;
3765       }
3766
3767       case GST_MATROSKA_ID_TITLE:{
3768         gchar *text;
3769         GstTagList *taglist;
3770
3771         if ((ret = gst_ebml_read_utf8 (ebml, &id, &text)) != GST_FLOW_OK)
3772           break;
3773
3774         GST_DEBUG_OBJECT (demux, "Title: %s", GST_STR_NULL (text));
3775         taglist = gst_tag_list_new ();
3776         gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, text,
3777             NULL);
3778         gst_matroska_demux_found_global_tag (demux, taglist);
3779         g_free (text);
3780         break;
3781       }
3782
3783       default:
3784         ret = gst_matroska_demux_parse_skip (demux, ebml, "SegmentInfo", id);
3785         break;
3786
3787         /* fall through */
3788       case GST_MATROSKA_ID_SEGMENTUID:
3789       case GST_MATROSKA_ID_SEGMENTFILENAME:
3790       case GST_MATROSKA_ID_PREVUID:
3791       case GST_MATROSKA_ID_PREVFILENAME:
3792       case GST_MATROSKA_ID_NEXTUID:
3793       case GST_MATROSKA_ID_NEXTFILENAME:
3794       case GST_MATROSKA_ID_SEGMENTFAMILY:
3795       case GST_MATROSKA_ID_CHAPTERTRANSLATE:
3796         ret = gst_ebml_read_skip (ebml);
3797         break;
3798     }
3799   }
3800
3801   DEBUG_ELEMENT_STOP (demux, ebml, "SegmentInfo", ret);
3802
3803   demux->segmentinfo_parsed = TRUE;
3804
3805   return ret;
3806 }
3807
3808 static GstFlowReturn
3809 gst_matroska_demux_parse_metadata_id_simple_tag (GstMatroskaDemux * demux,
3810     GstEbmlRead * ebml, GstTagList ** p_taglist)
3811 {
3812   /* FIXME: check if there are more useful mappings */
3813   struct
3814   {
3815     const gchar *matroska_tagname;
3816     const gchar *gstreamer_tagname;
3817   }
3818   tag_conv[] = {
3819     {
3820     GST_MATROSKA_TAG_ID_TITLE, GST_TAG_TITLE}, {
3821     GST_MATROSKA_TAG_ID_ARTIST, GST_TAG_ARTIST}, {
3822     GST_MATROSKA_TAG_ID_AUTHOR, GST_TAG_ARTIST}, {
3823     GST_MATROSKA_TAG_ID_ALBUM, GST_TAG_ALBUM}, {
3824     GST_MATROSKA_TAG_ID_COMMENTS, GST_TAG_COMMENT}, {
3825     GST_MATROSKA_TAG_ID_BITSPS, GST_TAG_BITRATE}, {
3826     GST_MATROSKA_TAG_ID_BPS, GST_TAG_BITRATE}, {
3827     GST_MATROSKA_TAG_ID_ENCODER, GST_TAG_ENCODER}, {
3828     GST_MATROSKA_TAG_ID_DATE, GST_TAG_DATE}, {
3829     GST_MATROSKA_TAG_ID_ISRC, GST_TAG_ISRC}, {
3830     GST_MATROSKA_TAG_ID_COPYRIGHT, GST_TAG_COPYRIGHT}, {
3831     GST_MATROSKA_TAG_ID_BPM, GST_TAG_BEATS_PER_MINUTE}, {
3832     GST_MATROSKA_TAG_ID_TERMS_OF_USE, GST_TAG_LICENSE}, {
3833     GST_MATROSKA_TAG_ID_COMPOSER, GST_TAG_COMPOSER}, {
3834     GST_MATROSKA_TAG_ID_LEAD_PERFORMER, GST_TAG_PERFORMER}, {
3835     GST_MATROSKA_TAG_ID_GENRE, GST_TAG_GENRE}
3836   };
3837   GstFlowReturn ret;
3838   guint32 id;
3839   gchar *value = NULL;
3840   gchar *tag = NULL;
3841
3842   DEBUG_ELEMENT_START (demux, ebml, "SimpleTag");
3843
3844   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3845     DEBUG_ELEMENT_STOP (demux, ebml, "SimpleTag", ret);
3846     return ret;
3847   }
3848
3849   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3850     /* read all sub-entries */
3851
3852     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3853       break;
3854
3855     switch (id) {
3856       case GST_MATROSKA_ID_TAGNAME:
3857         g_free (tag);
3858         tag = NULL;
3859         ret = gst_ebml_read_ascii (ebml, &id, &tag);
3860         GST_DEBUG_OBJECT (demux, "TagName: %s", GST_STR_NULL (tag));
3861         break;
3862
3863       case GST_MATROSKA_ID_TAGSTRING:
3864         g_free (value);
3865         value = NULL;
3866         ret = gst_ebml_read_utf8 (ebml, &id, &value);
3867         GST_DEBUG_OBJECT (demux, "TagString: %s", GST_STR_NULL (value));
3868         break;
3869
3870       default:
3871         ret = gst_matroska_demux_parse_skip (demux, ebml, "SimpleTag", id);
3872         break;
3873         /* fall-through */
3874
3875       case GST_MATROSKA_ID_TAGLANGUAGE:
3876       case GST_MATROSKA_ID_TAGDEFAULT:
3877       case GST_MATROSKA_ID_TAGBINARY:
3878         ret = gst_ebml_read_skip (ebml);
3879         break;
3880     }
3881   }
3882
3883   DEBUG_ELEMENT_STOP (demux, ebml, "SimpleTag", ret);
3884
3885   if (tag && value) {
3886     guint i;
3887
3888     for (i = 0; i < G_N_ELEMENTS (tag_conv); i++) {
3889       const gchar *tagname_gst = tag_conv[i].gstreamer_tagname;
3890
3891       const gchar *tagname_mkv = tag_conv[i].matroska_tagname;
3892
3893       if (strcmp (tagname_mkv, tag) == 0) {
3894         GValue dest = { 0, };
3895         GType dest_type = gst_tag_get_type (tagname_gst);
3896
3897         /* Ensure that any date string is complete */
3898         if (dest_type == GST_TYPE_DATE) {
3899           guint year = 1901, month = 1, day = 1;
3900
3901           /* Dates can be yyyy-MM-dd, yyyy-MM or yyyy, but we need
3902            * the first type */
3903           if (sscanf (value, "%04u-%02u-%02u", &year, &month, &day) != 0) {
3904             g_free (value);
3905             value = g_strdup_printf ("%04u-%02u-%02u", year, month, day);
3906           }
3907         }
3908
3909         g_value_init (&dest, dest_type);
3910         if (gst_value_deserialize (&dest, value)) {
3911           gst_tag_list_add_values (*p_taglist, GST_TAG_MERGE_APPEND,
3912               tagname_gst, &dest, NULL);
3913         } else {
3914           GST_WARNING_OBJECT (demux, "Can't transform tag '%s' with "
3915               "value '%s' to target type '%s'", tag, value,
3916               g_type_name (dest_type));
3917         }
3918         g_value_unset (&dest);
3919         break;
3920       }
3921     }
3922   }
3923
3924   g_free (tag);
3925   g_free (value);
3926
3927   return ret;
3928 }
3929
3930 static GstFlowReturn
3931 gst_matroska_demux_parse_metadata_id_tag (GstMatroskaDemux * demux,
3932     GstEbmlRead * ebml, GstTagList ** p_taglist)
3933 {
3934   guint32 id;
3935   GstFlowReturn ret;
3936
3937   DEBUG_ELEMENT_START (demux, ebml, "Tag");
3938
3939   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3940     DEBUG_ELEMENT_STOP (demux, ebml, "Tag", ret);
3941     return ret;
3942   }
3943
3944   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
3945     /* read all sub-entries */
3946
3947     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
3948       break;
3949
3950     switch (id) {
3951       case GST_MATROSKA_ID_SIMPLETAG:
3952         ret = gst_matroska_demux_parse_metadata_id_simple_tag (demux, ebml,
3953             p_taglist);
3954         break;
3955
3956       default:
3957         ret = gst_matroska_demux_parse_skip (demux, ebml, "Tag", id);
3958         break;
3959     }
3960   }
3961
3962   DEBUG_ELEMENT_STOP (demux, ebml, "Tag", ret);
3963
3964   return ret;
3965 }
3966
3967 static GstFlowReturn
3968 gst_matroska_demux_parse_metadata (GstMatroskaDemux * demux, GstEbmlRead * ebml)
3969 {
3970   GstTagList *taglist;
3971   GstFlowReturn ret = GST_FLOW_OK;
3972   guint32 id;
3973   GList *l;
3974   guint64 curpos;
3975
3976   curpos = gst_ebml_read_get_pos (ebml);
3977
3978   /* Make sure we don't parse a tags element twice and
3979    * post it's tags twice */
3980   curpos = gst_ebml_read_get_pos (ebml);
3981   for (l = demux->tags_parsed; l; l = l->next) {
3982     guint64 *pos = l->data;
3983
3984     if (*pos == curpos) {
3985       GST_DEBUG_OBJECT (demux, "Skipping already parsed Tags at offset %"
3986           G_GUINT64_FORMAT, curpos);
3987       return GST_FLOW_OK;
3988     }
3989   }
3990
3991   demux->tags_parsed =
3992       g_list_prepend (demux->tags_parsed, g_slice_new (guint64));
3993   *((guint64 *) demux->tags_parsed->data) = curpos;
3994   /* fall-through */
3995
3996   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
3997     DEBUG_ELEMENT_STOP (demux, ebml, "Tags", ret);
3998     return ret;
3999   }
4000
4001   taglist = gst_tag_list_new ();
4002
4003   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4004     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4005       break;
4006
4007     switch (id) {
4008       case GST_MATROSKA_ID_TAG:
4009         ret = gst_matroska_demux_parse_metadata_id_tag (demux, ebml, &taglist);
4010         break;
4011
4012       default:
4013         ret = gst_matroska_demux_parse_skip (demux, ebml, "Tags", id);
4014         break;
4015         /* FIXME: Use to limit the tags to specific pads */
4016       case GST_MATROSKA_ID_TARGETS:
4017         ret = gst_ebml_read_skip (ebml);
4018         break;
4019     }
4020   }
4021
4022   DEBUG_ELEMENT_STOP (demux, ebml, "Tags", ret);
4023
4024   gst_matroska_demux_found_global_tag (demux, taglist);
4025
4026   return ret;
4027 }
4028
4029 static GstFlowReturn
4030 gst_matroska_demux_parse_attached_file (GstMatroskaDemux * demux,
4031     GstEbmlRead * ebml, GstTagList * taglist)
4032 {
4033   guint32 id;
4034   GstFlowReturn ret;
4035   gchar *description = NULL;
4036   gchar *filename = NULL;
4037   gchar *mimetype = NULL;
4038   guint8 *data = NULL;
4039   guint64 datalen = 0;
4040
4041   DEBUG_ELEMENT_START (demux, ebml, "AttachedFile");
4042
4043   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4044     DEBUG_ELEMENT_STOP (demux, ebml, "AttachedFile", ret);
4045     return ret;
4046   }
4047
4048   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4049     /* read all sub-entries */
4050
4051     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4052       break;
4053
4054     switch (id) {
4055       case GST_MATROSKA_ID_FILEDESCRIPTION:
4056         if (description) {
4057           GST_WARNING_OBJECT (demux, "FileDescription can only appear once");
4058           break;
4059         }
4060
4061         ret = gst_ebml_read_utf8 (ebml, &id, &description);
4062         GST_DEBUG_OBJECT (demux, "FileDescription: %s",
4063             GST_STR_NULL (description));
4064         break;
4065       case GST_MATROSKA_ID_FILENAME:
4066         if (filename) {
4067           GST_WARNING_OBJECT (demux, "FileName can only appear once");
4068           break;
4069         }
4070
4071         ret = gst_ebml_read_utf8 (ebml, &id, &filename);
4072
4073         GST_DEBUG_OBJECT (demux, "FileName: %s", GST_STR_NULL (filename));
4074         break;
4075       case GST_MATROSKA_ID_FILEMIMETYPE:
4076         if (mimetype) {
4077           GST_WARNING_OBJECT (demux, "FileMimeType can only appear once");
4078           break;
4079         }
4080
4081         ret = gst_ebml_read_ascii (ebml, &id, &mimetype);
4082         GST_DEBUG_OBJECT (demux, "FileMimeType: %s", GST_STR_NULL (mimetype));
4083         break;
4084       case GST_MATROSKA_ID_FILEDATA:
4085         if (data) {
4086           GST_WARNING_OBJECT (demux, "FileData can only appear once");
4087           break;
4088         }
4089
4090         ret = gst_ebml_read_binary (ebml, &id, &data, &datalen);
4091         GST_DEBUG_OBJECT (demux, "FileData of size %" G_GUINT64_FORMAT,
4092             datalen);
4093         break;
4094
4095       default:
4096         ret = gst_matroska_demux_parse_skip (demux, ebml, "AttachedFile", id);
4097         break;
4098       case GST_MATROSKA_ID_FILEUID:
4099         ret = gst_ebml_read_skip (ebml);
4100         break;
4101     }
4102   }
4103
4104   DEBUG_ELEMENT_STOP (demux, ebml, "AttachedFile", ret);
4105
4106   if (filename && mimetype && data && datalen > 0) {
4107     GstTagImageType image_type = GST_TAG_IMAGE_TYPE_NONE;
4108     GstBuffer *tagbuffer = NULL;
4109     GstCaps *caps;
4110     gchar *filename_lc = g_utf8_strdown (filename, -1);
4111
4112     GST_DEBUG_OBJECT (demux, "Creating tag for attachment with filename '%s', "
4113         "mimetype '%s', description '%s', size %" G_GUINT64_FORMAT, filename,
4114         mimetype, GST_STR_NULL (description), datalen);
4115
4116     /* TODO: better heuristics for different image types */
4117     if (strstr (filename_lc, "cover")) {
4118       if (strstr (filename_lc, "back"))
4119         image_type = GST_TAG_IMAGE_TYPE_BACK_COVER;
4120       else
4121         image_type = GST_TAG_IMAGE_TYPE_FRONT_COVER;
4122     } else if (g_str_has_prefix (mimetype, "image/") ||
4123         g_str_has_suffix (filename_lc, "png") ||
4124         g_str_has_suffix (filename_lc, "jpg") ||
4125         g_str_has_suffix (filename_lc, "jpeg") ||
4126         g_str_has_suffix (filename_lc, "gif") ||
4127         g_str_has_suffix (filename_lc, "bmp")) {
4128       image_type = GST_TAG_IMAGE_TYPE_UNDEFINED;
4129     }
4130     g_free (filename_lc);
4131
4132     /* First try to create an image tag buffer from this */
4133     if (image_type != GST_TAG_IMAGE_TYPE_NONE) {
4134       tagbuffer =
4135           gst_tag_image_data_to_image_buffer (data, datalen, image_type);
4136
4137       if (!tagbuffer)
4138         image_type = GST_TAG_IMAGE_TYPE_NONE;
4139     }
4140
4141     /* if this failed create an attachment buffer */
4142     if (!tagbuffer) {
4143       tagbuffer = gst_buffer_new_and_alloc (datalen);
4144
4145       memcpy (GST_BUFFER_DATA (tagbuffer), data, datalen);
4146       GST_BUFFER_SIZE (tagbuffer) = datalen;
4147
4148       caps = gst_type_find_helper_for_buffer (NULL, tagbuffer, NULL);
4149       if (caps == NULL)
4150         caps = gst_caps_new_simple (mimetype, NULL);
4151       gst_buffer_set_caps (tagbuffer, caps);
4152       gst_caps_unref (caps);
4153     }
4154
4155     /* Set filename and description on the caps */
4156     caps = GST_BUFFER_CAPS (tagbuffer);
4157     gst_caps_set_simple (caps, "filename", G_TYPE_STRING, filename, NULL);
4158     if (description)
4159       gst_caps_set_simple (caps, "description", G_TYPE_STRING, description,
4160           NULL);
4161
4162     GST_DEBUG_OBJECT (demux,
4163         "Created attachment buffer with caps: %" GST_PTR_FORMAT, caps);
4164
4165     /* and append to the tag list */
4166     if (image_type != GST_TAG_IMAGE_TYPE_NONE)
4167       gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, tagbuffer,
4168           NULL);
4169     else
4170       gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_ATTACHMENT,
4171           tagbuffer, NULL);
4172   }
4173
4174   g_free (filename);
4175   g_free (mimetype);
4176   g_free (data);
4177   g_free (description);
4178
4179   return ret;
4180 }
4181
4182 static GstFlowReturn
4183 gst_matroska_demux_parse_attachments (GstMatroskaDemux * demux,
4184     GstEbmlRead * ebml)
4185 {
4186   guint32 id;
4187   GstFlowReturn ret = GST_FLOW_OK;
4188   GstTagList *taglist;
4189
4190   DEBUG_ELEMENT_START (demux, ebml, "Attachments");
4191
4192   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4193     DEBUG_ELEMENT_STOP (demux, ebml, "Attachments", ret);
4194     return ret;
4195   }
4196
4197   taglist = gst_tag_list_new ();
4198
4199   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4200     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4201       break;
4202
4203     switch (id) {
4204       case GST_MATROSKA_ID_ATTACHEDFILE:
4205         ret = gst_matroska_demux_parse_attached_file (demux, ebml, taglist);
4206         break;
4207
4208       default:
4209         ret = gst_matroska_demux_parse_skip (demux, ebml, "Attachments", id);
4210         break;
4211     }
4212   }
4213   DEBUG_ELEMENT_STOP (demux, ebml, "Attachments", ret);
4214
4215   if (gst_structure_n_fields (GST_STRUCTURE (taglist)) > 0) {
4216     GST_DEBUG_OBJECT (demux, "Storing attachment tags");
4217     gst_matroska_demux_found_global_tag (demux, taglist);
4218   } else {
4219     GST_DEBUG_OBJECT (demux, "No valid attachments found");
4220     gst_tag_list_free (taglist);
4221   }
4222
4223   demux->attachments_parsed = TRUE;
4224
4225   return ret;
4226 }
4227
4228 static GstFlowReturn
4229 gst_matroska_demux_parse_chapters (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4230 {
4231   guint32 id;
4232   GstFlowReturn ret = GST_FLOW_OK;
4233
4234   GST_WARNING_OBJECT (demux, "Parsing of chapters not implemented yet");
4235
4236   /* TODO: implement parsing of chapters */
4237
4238   DEBUG_ELEMENT_START (demux, ebml, "Chapters");
4239
4240   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4241     DEBUG_ELEMENT_STOP (demux, ebml, "Chapters", ret);
4242     return ret;
4243   }
4244
4245   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4246     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4247       break;
4248
4249     switch (id) {
4250       default:
4251         ret = gst_ebml_read_skip (ebml);
4252         break;
4253     }
4254   }
4255
4256   DEBUG_ELEMENT_STOP (demux, ebml, "Chapters", ret);
4257   return ret;
4258 }
4259
4260 /*
4261  * Read signed/unsigned "EBML" numbers.
4262  * Return: number of bytes processed.
4263  */
4264
4265 static gint
4266 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
4267 {
4268   gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
4269   guint64 total;
4270
4271   if (size <= 0) {
4272     return -1;
4273   }
4274
4275   total = data[0];
4276   while (read <= 8 && !(total & len_mask)) {
4277     read++;
4278     len_mask >>= 1;
4279   }
4280   if (read > 8)
4281     return -1;
4282
4283   if ((total &= (len_mask - 1)) == len_mask - 1)
4284     num_ffs++;
4285   if (size < read)
4286     return -1;
4287   while (n < read) {
4288     if (data[n] == 0xff)
4289       num_ffs++;
4290     total = (total << 8) | data[n];
4291     n++;
4292   }
4293
4294   if (read == num_ffs && total != 0)
4295     *num = G_MAXUINT64;
4296   else
4297     *num = total;
4298
4299   return read;
4300 }
4301
4302 static gint
4303 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
4304 {
4305   guint64 unum;
4306   gint res;
4307
4308   /* read as unsigned number first */
4309   if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
4310     return -1;
4311
4312   /* make signed */
4313   if (unum == G_MAXUINT64)
4314     *num = G_MAXINT64;
4315   else
4316     *num = unum - ((1 << ((7 * res) - 1)) - 1);
4317
4318   return res;
4319 }
4320
4321 /*
4322  * Mostly used for subtitles. We add void filler data for each
4323  * lagging stream to make sure we don't deadlock.
4324  */
4325
4326 static void
4327 gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
4328 {
4329   gint stream_nr;
4330
4331   GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
4332       GST_TIME_ARGS (demux->segment.last_stop));
4333
4334   g_assert (demux->num_streams == demux->src->len);
4335   for (stream_nr = 0; stream_nr < demux->src->len; stream_nr++) {
4336     GstMatroskaTrackContext *context;
4337
4338     context = g_ptr_array_index (demux->src, stream_nr);
4339
4340     GST_LOG_OBJECT (demux,
4341         "Checking for resync on stream %d (%" GST_TIME_FORMAT ")", stream_nr,
4342         GST_TIME_ARGS (context->pos));
4343
4344     if (G_LIKELY (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE)) {
4345       GST_LOG_OBJECT (demux, "Skipping sync on non-subtitle stream");
4346       continue;
4347     }
4348 #ifndef MKVDEMUX_MODIFICATION
4349     /* does it lag? 0.5 seconds is a random threshold...
4350      * lag need only be considered if we have advanced into requested segment */
4351     if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
4352         GST_CLOCK_TIME_IS_VALID (demux->segment.last_stop) &&
4353         demux->segment.last_stop > demux->segment.start &&
4354         context->pos + (GST_SECOND / 2) < demux->segment.last_stop) {
4355       gint64 new_start;
4356
4357       new_start = demux->segment.last_stop - (GST_SECOND / 2);
4358       if (GST_CLOCK_TIME_IS_VALID (demux->segment.stop))
4359         new_start = MIN (new_start, demux->segment.stop);
4360       GST_DEBUG_OBJECT (demux,
4361           "Synchronizing stream %d with others by advancing time " "from %"
4362           GST_TIME_FORMAT " to %" GST_TIME_FORMAT, stream_nr,
4363           GST_TIME_ARGS (context->pos), GST_TIME_ARGS (new_start));
4364
4365       context->pos = new_start;
4366
4367       /* advance stream time */
4368       gst_pad_push_event (context->pad,
4369           gst_event_new_new_segment (TRUE, demux->segment.rate,
4370               demux->segment.format, new_start,
4371               demux->segment.stop, new_start));
4372     }
4373 #endif
4374   }
4375 }
4376
4377 static GstFlowReturn
4378 gst_matroska_demux_push_hdr_buf (GstMatroskaDemux * demux,
4379     GstMatroskaTrackContext * stream, guint8 * data, guint len)
4380 {
4381   GstFlowReturn ret, cret;
4382   GstBuffer *header_buf;
4383
4384   header_buf = gst_buffer_new_and_alloc (len);
4385   gst_buffer_set_caps (header_buf, stream->caps);
4386   memcpy (GST_BUFFER_DATA (header_buf), data, len);
4387
4388   if (stream->set_discont) {
4389     GST_BUFFER_FLAG_SET (header_buf, GST_BUFFER_FLAG_DISCONT);
4390     stream->set_discont = FALSE;
4391   }
4392
4393   ret = gst_pad_push (stream->pad, header_buf);
4394
4395   /* combine flows */
4396   cret = gst_matroska_demux_combine_flows (demux, stream, ret);
4397
4398   return cret;
4399 }
4400
4401 static GstFlowReturn
4402 gst_matroska_demux_push_flac_codec_priv_data (GstMatroskaDemux * demux,
4403     GstMatroskaTrackContext * stream)
4404 {
4405   GstFlowReturn ret;
4406   guint8 *pdata;
4407   guint off, len;
4408
4409   GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
4410
4411   pdata = (guint8 *) stream->codec_priv;
4412
4413   /* need at least 'fLaC' marker + STREAMINFO metadata block */
4414   if (stream->codec_priv_size < ((4) + (4 + 34))) {
4415     GST_WARNING_OBJECT (demux, "not enough codec priv data for flac headers");
4416     return GST_FLOW_ERROR;
4417   }
4418
4419   if (memcmp (pdata, "fLaC", 4) != 0) {
4420     GST_WARNING_OBJECT (demux, "no flac marker at start of stream headers");
4421     return GST_FLOW_ERROR;
4422   }
4423
4424   ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 4);
4425   if (ret != GST_FLOW_OK)
4426     return ret;
4427
4428   off = 4;                      /* skip fLaC marker */
4429   while (off < stream->codec_priv_size) {
4430     len = GST_READ_UINT8 (pdata + off + 1) << 16;
4431     len |= GST_READ_UINT8 (pdata + off + 2) << 8;
4432     len |= GST_READ_UINT8 (pdata + off + 3);
4433
4434     GST_DEBUG_OBJECT (demux, "header packet: len=%u bytes, flags=0x%02x",
4435         len, (guint) pdata[off]);
4436
4437     ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata + off, len + 4);
4438     if (ret != GST_FLOW_OK)
4439       return ret;
4440
4441     off += 4 + len;
4442   }
4443   return GST_FLOW_OK;
4444 }
4445
4446 static GstFlowReturn
4447 gst_matroska_demux_push_speex_codec_priv_data (GstMatroskaDemux * demux,
4448     GstMatroskaTrackContext * stream)
4449 {
4450   GstFlowReturn ret;
4451   guint8 *pdata;
4452
4453   GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
4454
4455   pdata = (guint8 *) stream->codec_priv;
4456
4457   /* need at least 'fLaC' marker + STREAMINFO metadata block */
4458   if (stream->codec_priv_size < 80) {
4459     GST_WARNING_OBJECT (demux, "not enough codec priv data for speex headers");
4460     return GST_FLOW_ERROR;
4461   }
4462
4463   if (memcmp (pdata, "Speex   ", 8) != 0) {
4464     GST_WARNING_OBJECT (demux, "no Speex marker at start of stream headers");
4465     return GST_FLOW_ERROR;
4466   }
4467
4468   ret = gst_matroska_demux_push_hdr_buf (demux, stream, pdata, 80);
4469   if (ret != GST_FLOW_OK)
4470     return ret;
4471
4472   if (stream->codec_priv_size == 80)
4473     return ret;
4474   else
4475     return gst_matroska_demux_push_hdr_buf (demux, stream, pdata + 80,
4476         stream->codec_priv_size - 80);
4477 }
4478
4479 static GstFlowReturn
4480 gst_matroska_demux_push_xiph_codec_priv_data (GstMatroskaDemux * demux,
4481     GstMatroskaTrackContext * stream)
4482 {
4483   GstFlowReturn ret;
4484   guint8 *p = (guint8 *) stream->codec_priv;
4485   gint i, offset, num_packets;
4486   guint *length, last;
4487
4488   if (stream->codec_priv == NULL || stream->codec_priv_size == 0) {
4489     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4490         ("Missing codec private data for xiph headers, broken file"));
4491     return GST_FLOW_ERROR;
4492   }
4493
4494   /* start of the stream and vorbis audio or theora video, need to
4495    * send the codec_priv data as first three packets */
4496   num_packets = p[0] + 1;
4497   GST_DEBUG_OBJECT (demux, "%u stream headers, total length=%u bytes",
4498       (guint) num_packets, stream->codec_priv_size);
4499
4500   length = g_alloca (num_packets * sizeof (guint));
4501   last = 0;
4502   offset = 1;
4503
4504   /* first packets, read length values */
4505   for (i = 0; i < num_packets - 1; i++) {
4506     length[i] = 0;
4507     while (offset < stream->codec_priv_size) {
4508       length[i] += p[offset];
4509       if (p[offset++] != 0xff)
4510         break;
4511     }
4512     last += length[i];
4513   }
4514   if (offset + last > stream->codec_priv_size)
4515     return GST_FLOW_ERROR;
4516
4517   /* last packet is the remaining size */
4518   length[i] = stream->codec_priv_size - offset - last;
4519
4520   for (i = 0; i < num_packets; i++) {
4521     GST_DEBUG_OBJECT (demux, "buffer %d: length=%u bytes", i,
4522         (guint) length[i]);
4523     if (offset + length[i] > stream->codec_priv_size)
4524       return GST_FLOW_ERROR;
4525
4526     ret =
4527         gst_matroska_demux_push_hdr_buf (demux, stream, p + offset, length[i]);
4528     if (ret != GST_FLOW_OK)
4529       return ret;
4530
4531     offset += length[i];
4532   }
4533   return GST_FLOW_OK;
4534 }
4535
4536 static void
4537 gst_matroska_demux_push_dvd_clut_change_event (GstMatroskaDemux * demux,
4538     GstMatroskaTrackContext * stream)
4539 {
4540   gchar *buf, *start;
4541
4542   g_assert (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB));
4543
4544   if (!stream->codec_priv)
4545     return;
4546
4547   /* ideally, VobSub private data should be parsed and stored more convenient
4548    * elsewhere, but for now, only interested in a small part */
4549
4550   /* make sure we have terminating 0 */
4551   buf = g_strndup ((gchar *) stream->codec_priv, stream->codec_priv_size);
4552
4553   /* just locate and parse palette part */
4554   start = strstr (buf, "palette:");
4555   if (start) {
4556     gint i;
4557     guint32 clut[16];
4558     guint32 col;
4559     guint8 r, g, b, y, u, v;
4560
4561     start += 8;
4562     while (g_ascii_isspace (*start))
4563       start++;
4564     for (i = 0; i < 16; i++) {
4565       if (sscanf (start, "%06x", &col) != 1)
4566         break;
4567       start += 6;
4568       while ((*start == ',') || g_ascii_isspace (*start))
4569         start++;
4570       /* sigh, need to convert this from vobsub pseudo-RGB to YUV */
4571       r = (col >> 16) & 0xff;
4572       g = (col >> 8) & 0xff;
4573       b = col & 0xff;
4574       y = CLAMP ((0.1494 * r + 0.6061 * g + 0.2445 * b) * 219 / 255 + 16, 0,
4575           255);
4576       u = CLAMP (0.6066 * r - 0.4322 * g - 0.1744 * b + 128, 0, 255);
4577       v = CLAMP (-0.08435 * r - 0.3422 * g + 0.4266 * b + 128, 0, 255);
4578       clut[i] = (y << 16) | (u << 8) | v;
4579     }
4580
4581     /* got them all without problems; build and send event */
4582     if (i == 16) {
4583       GstStructure *s;
4584
4585       s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING,
4586           "dvd-spu-clut-change", "clut00", G_TYPE_INT, clut[0], "clut01",
4587           G_TYPE_INT, clut[1], "clut02", G_TYPE_INT, clut[2], "clut03",
4588           G_TYPE_INT, clut[3], "clut04", G_TYPE_INT, clut[4], "clut05",
4589           G_TYPE_INT, clut[5], "clut06", G_TYPE_INT, clut[6], "clut07",
4590           G_TYPE_INT, clut[7], "clut08", G_TYPE_INT, clut[8], "clut09",
4591           G_TYPE_INT, clut[9], "clut10", G_TYPE_INT, clut[10], "clut11",
4592           G_TYPE_INT, clut[11], "clut12", G_TYPE_INT, clut[12], "clut13",
4593           G_TYPE_INT, clut[13], "clut14", G_TYPE_INT, clut[14], "clut15",
4594           G_TYPE_INT, clut[15], NULL);
4595
4596       gst_pad_push_event (stream->pad,
4597           gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s));
4598     }
4599   }
4600   g_free (buf);
4601 }
4602
4603 static GstFlowReturn
4604 gst_matroska_demux_add_mpeg_seq_header (GstElement * element,
4605     GstMatroskaTrackContext * stream, GstBuffer ** buf)
4606 {
4607   guint8 *seq_header;
4608   guint seq_header_len;
4609   guint32 header;
4610
4611   if (stream->codec_state) {
4612     seq_header = stream->codec_state;
4613     seq_header_len = stream->codec_state_size;
4614   } else if (stream->codec_priv) {
4615     seq_header = stream->codec_priv;
4616     seq_header_len = stream->codec_priv_size;
4617   } else {
4618     return GST_FLOW_OK;
4619   }
4620
4621   /* Sequence header only needed for keyframes */
4622   if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
4623     return GST_FLOW_OK;
4624
4625   if (GST_BUFFER_SIZE (*buf) < 4)
4626     return GST_FLOW_OK;
4627
4628   header = GST_READ_UINT32_BE (GST_BUFFER_DATA (*buf));
4629   /* Sequence start code, if not found prepend */
4630   if (header != 0x000001b3) {
4631     GstBuffer *newbuf;
4632
4633     newbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (*buf) + seq_header_len);
4634     gst_buffer_set_caps (newbuf, stream->caps);
4635
4636     GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
4637     gst_buffer_copy_metadata (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
4638         GST_BUFFER_COPY_FLAGS);
4639     g_memmove (GST_BUFFER_DATA (newbuf), seq_header, seq_header_len);
4640     g_memmove (GST_BUFFER_DATA (newbuf) + seq_header_len,
4641         GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
4642     gst_buffer_unref (*buf);
4643     *buf = newbuf;
4644   }
4645
4646   return GST_FLOW_OK;
4647 }
4648
4649 static GstFlowReturn
4650 gst_matroska_demux_add_wvpk_header (GstElement * element,
4651     GstMatroskaTrackContext * stream, GstBuffer ** buf)
4652 {
4653   GstMatroskaTrackAudioContext *audiocontext =
4654       (GstMatroskaTrackAudioContext *) stream;
4655   GstBuffer *newbuf = NULL;
4656   guint8 *data;
4657   guint newlen;
4658   Wavpack4Header wvh;
4659
4660   wvh.ck_id[0] = 'w';
4661   wvh.ck_id[1] = 'v';
4662   wvh.ck_id[2] = 'p';
4663   wvh.ck_id[3] = 'k';
4664
4665   wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
4666   wvh.track_no = 0;
4667   wvh.index_no = 0;
4668   wvh.total_samples = -1;
4669   wvh.block_index = audiocontext->wvpk_block_index;
4670
4671   if (audiocontext->channels <= 2) {
4672     guint32 block_samples;
4673
4674     block_samples = GST_READ_UINT32_LE (GST_BUFFER_DATA (*buf));
4675     /* we need to reconstruct the header of the wavpack block */
4676
4677     /* -20 because ck_size is the size of the wavpack block -8
4678      * and lace_size is the size of the wavpack block + 12
4679      * (the three guint32 of the header that already are in the buffer) */
4680     wvh.ck_size = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 20;
4681
4682     /* block_samples, flags and crc are already in the buffer */
4683     newlen = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 12;
4684     newbuf = gst_buffer_new_and_alloc (newlen);
4685     gst_buffer_set_caps (newbuf, stream->caps);
4686
4687     data = GST_BUFFER_DATA (newbuf);
4688     data[0] = 'w';
4689     data[1] = 'v';
4690     data[2] = 'p';
4691     data[3] = 'k';
4692     GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
4693     GST_WRITE_UINT16_LE (data + 8, wvh.version);
4694     GST_WRITE_UINT8 (data + 10, wvh.track_no);
4695     GST_WRITE_UINT8 (data + 11, wvh.index_no);
4696     GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
4697     GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
4698     g_memmove (data + 20, GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
4699     gst_buffer_copy_metadata (newbuf, *buf,
4700         GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
4701     gst_buffer_unref (*buf);
4702     *buf = newbuf;
4703     audiocontext->wvpk_block_index += block_samples;
4704   } else {
4705     guint8 *outdata;
4706     guint outpos = 0;
4707     guint size;
4708     guint32 block_samples, flags, crc, blocksize;
4709
4710     data = GST_BUFFER_DATA (*buf);
4711     size = GST_BUFFER_SIZE (*buf);
4712
4713     if (size < 4) {
4714       GST_ERROR_OBJECT (element, "Too small wavpack buffer");
4715       return GST_FLOW_ERROR;
4716     }
4717
4718     block_samples = GST_READ_UINT32_LE (data);
4719     data += 4;
4720     size -= 4;
4721
4722     while (size > 12) {
4723       flags = GST_READ_UINT32_LE (data);
4724       data += 4;
4725       size -= 4;
4726       crc = GST_READ_UINT32_LE (data);
4727       data += 4;
4728       size -= 4;
4729       blocksize = GST_READ_UINT32_LE (data);
4730       data += 4;
4731       size -= 4;
4732
4733       if (blocksize == 0 || size < blocksize)
4734         break;
4735
4736       if (newbuf == NULL) {
4737         newbuf = gst_buffer_new_and_alloc (sizeof (Wavpack4Header) + blocksize);
4738         gst_buffer_set_caps (newbuf, stream->caps);
4739
4740         gst_buffer_copy_metadata (newbuf, *buf,
4741             GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
4742
4743         outpos = 0;
4744         outdata = GST_BUFFER_DATA (newbuf);
4745       } else {
4746         GST_BUFFER_SIZE (newbuf) += sizeof (Wavpack4Header) + blocksize;
4747         GST_BUFFER_DATA (newbuf) =
4748             g_realloc (GST_BUFFER_DATA (newbuf), GST_BUFFER_SIZE (newbuf));
4749         GST_BUFFER_MALLOCDATA (newbuf) = GST_BUFFER_DATA (newbuf);
4750         outdata = GST_BUFFER_DATA (newbuf);
4751       }
4752
4753       outdata[outpos] = 'w';
4754       outdata[outpos + 1] = 'v';
4755       outdata[outpos + 2] = 'p';
4756       outdata[outpos + 3] = 'k';
4757       outpos += 4;
4758
4759       GST_WRITE_UINT32_LE (outdata + outpos,
4760           blocksize + sizeof (Wavpack4Header) - 8);
4761       GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
4762       GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
4763       GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
4764       GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
4765       GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
4766       GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
4767       GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
4768       GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
4769       outpos += 28;
4770
4771       g_memmove (outdata + outpos, data, blocksize);
4772       outpos += blocksize;
4773       data += blocksize;
4774       size -= blocksize;
4775     }
4776     gst_buffer_unref (*buf);
4777     *buf = newbuf;
4778     audiocontext->wvpk_block_index += block_samples;
4779   }
4780
4781   return GST_FLOW_OK;
4782 }
4783
4784 static GstFlowReturn
4785 gst_matroska_demux_check_subtitle_buffer (GstElement * element,
4786     GstMatroskaTrackContext * stream, GstBuffer ** buf)
4787 {
4788   GstMatroskaTrackSubtitleContext *sub_stream;
4789   const gchar *encoding, *data;
4790   GError *err = NULL;
4791   GstBuffer *newbuf;
4792   gchar *utf8;
4793   guint size;
4794
4795   sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
4796
4797   data = (const gchar *) GST_BUFFER_DATA (*buf);
4798   size = GST_BUFFER_SIZE (*buf);
4799
4800   if (!sub_stream->invalid_utf8) {
4801     if (g_utf8_validate (data, size, NULL)) {
4802       return GST_FLOW_OK;
4803     }
4804     GST_WARNING_OBJECT (element, "subtitle stream %d is not valid UTF-8, this "
4805         "is broken according to the matroska specification", stream->num);
4806     sub_stream->invalid_utf8 = TRUE;
4807   }
4808
4809   /* file with broken non-UTF8 subtitle, do the best we can do to fix it */
4810   encoding = g_getenv ("GST_SUBTITLE_ENCODING");
4811   if (encoding == NULL || *encoding == '\0') {
4812     /* if local encoding is UTF-8 and no encoding specified
4813      * via the environment variable, assume ISO-8859-15 */
4814     if (g_get_charset (&encoding)) {
4815       encoding = "ISO-8859-15";
4816     }
4817   }
4818
4819   utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
4820       NULL, NULL, &err);
4821
4822   if (err) {
4823     GST_LOG_OBJECT (element, "could not convert string from '%s' to UTF-8: %s",
4824         encoding, err->message);
4825     g_error_free (err);
4826     g_free (utf8);
4827
4828     /* invalid input encoding, fall back to ISO-8859-15 (always succeeds) */
4829     encoding = "ISO-8859-15";
4830     utf8 = g_convert_with_fallback (data, size, "UTF-8", encoding, (char *) "*",
4831         NULL, NULL, NULL);
4832   }
4833
4834   GST_LOG_OBJECT (element, "converted subtitle text from %s to UTF-8 %s",
4835       encoding, (err) ? "(using ISO-8859-15 as fallback)" : "");
4836
4837   if (utf8 == NULL)
4838     utf8 = g_strdup ("invalid subtitle");
4839
4840   newbuf = gst_buffer_new ();
4841   GST_BUFFER_MALLOCDATA (newbuf) = (guint8 *) utf8;
4842   GST_BUFFER_DATA (newbuf) = (guint8 *) utf8;
4843   GST_BUFFER_SIZE (newbuf) = strlen (utf8);
4844   gst_buffer_copy_metadata (newbuf, *buf,
4845       GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
4846   gst_buffer_unref (*buf);
4847
4848   *buf = newbuf;
4849   return GST_FLOW_OK;
4850 }
4851
4852 #ifdef MKVDEMUX_MODIFICATION
4853 static GstFlowReturn 
4854 gst_matroska_rewind_trickplay (GstMatroskaDemux* demux, GstMatroskaTrackContext * stream, GstBuffer* sub) 
4855 {
4856         GstFlowReturn ret = GST_FLOW_OK;
4857         
4858         /* Reverse trick play...*/
4859         g_queue_push_tail (stream->queue, sub);         
4860
4861         if ((demux->found_videokeyframe == TRUE) && (demux->found_audioframe == TRUE))
4862         {
4863                 //reached condition...so display in reverse direction
4864                 GstBuffer *QBuf;
4865                 int i = 0;
4866                 for (i = 0; i < demux->src->len; i++) 
4867                 {
4868                         GstMatroskaTrackContext *tmp = g_ptr_array_index (demux->src, i);
4869
4870                         /* make sure that we empty the queue */
4871                         while (!g_queue_is_empty (tmp->queue))
4872                         {
4873                                 QBuf = g_queue_pop_tail (tmp->queue);
4874                                 GST_DEBUG_OBJECT (demux,
4875                                           "Pushing data of size %d for stream %d, time=%"
4876                                           GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT,
4877                                           GST_BUFFER_SIZE (QBuf), tmp->type,
4878                                           GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (QBuf)),
4879                                           GST_TIME_ARGS (GST_BUFFER_DURATION (QBuf)));     
4880                                         
4881                                 ret = gst_pad_push(tmp->pad, QBuf);
4882                                 
4883                                 if (ret != GST_FLOW_OK)
4884                                 {
4885                                         GST_DEBUG_OBJECT (demux, "Error in pad_push. Reason : %s\n", gst_flow_get_name (ret));
4886                                 }
4887                         }
4888                 }
4889         }
4890         
4891         return ret;
4892 }
4893 #endif
4894
4895 static GstFlowReturn
4896 gst_matroska_demux_check_aac (GstElement * element,
4897     GstMatroskaTrackContext * stream, GstBuffer ** buf)
4898 {
4899   const guint8 *data;
4900   guint size;
4901
4902   data = GST_BUFFER_DATA (*buf);
4903   size = GST_BUFFER_SIZE (*buf);
4904
4905   if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
4906     GstCaps *new_caps;
4907     GstStructure *s;
4908
4909     /* tss, ADTS data, remove codec_data
4910      * still assume it is at least parsed */
4911     new_caps = gst_caps_copy (stream->caps);
4912     s = gst_caps_get_structure (new_caps, 0);
4913     g_assert (s);
4914     gst_structure_remove_field (s, "codec_data");
4915     gst_caps_replace (&stream->caps, new_caps);
4916     gst_pad_set_caps (stream->pad, new_caps);
4917     gst_buffer_set_caps (*buf, new_caps);
4918     GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
4919         "new caps: %" GST_PTR_FORMAT, new_caps);
4920     gst_caps_unref (new_caps);
4921   }
4922
4923   /* disable subsequent checking */
4924   stream->postprocess_frame = NULL;
4925
4926   return GST_FLOW_OK;
4927 }
4928
4929 static GstFlowReturn
4930 gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
4931     GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
4932     gboolean is_simpleblock)
4933 {
4934   GstMatroskaTrackContext *stream = NULL;
4935   GstFlowReturn ret = GST_FLOW_OK;
4936   gboolean readblock = FALSE;
4937   guint32 id;
4938   guint64 block_duration = 0;
4939   GstBuffer *buf = NULL;
4940   gint stream_num = -1, n, laces = 0;
4941   guint size = 0;
4942   gint *lace_size = NULL;
4943   gint64 time = 0;
4944   gint flags = 0;
4945   gint64 referenceblock = 0;
4946   gint64 offset;
4947
4948   offset = gst_ebml_read_get_offset (ebml);
4949
4950   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4951     if (!is_simpleblock) {
4952       if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
4953         goto data_error;
4954       }
4955     } else {
4956       id = GST_MATROSKA_ID_SIMPLEBLOCK;
4957     }
4958
4959     switch (id) {
4960         /* one block inside the group. Note, block parsing is one
4961          * of the harder things, so this code is a bit complicated.
4962          * See http://www.matroska.org/ for documentation. */
4963       case GST_MATROSKA_ID_SIMPLEBLOCK:
4964       case GST_MATROSKA_ID_BLOCK:
4965       {
4966         guint64 num;
4967         guint8 *data;
4968
4969         if (buf) {
4970           gst_buffer_unref (buf);
4971           buf = NULL;
4972         }
4973         if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
4974           break;
4975
4976         data = GST_BUFFER_DATA (buf);
4977         size = GST_BUFFER_SIZE (buf);
4978
4979         /* first byte(s): blocknum */
4980         if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
4981           goto data_error;
4982         data += n;
4983         size -= n;
4984
4985         /* fetch stream from num */
4986         stream_num = gst_matroska_demux_stream_from_num (demux, num);
4987         if (G_UNLIKELY (size < 3)) {
4988           GST_WARNING_OBJECT (demux, "Invalid size %u", size);
4989           /* non-fatal, try next block(group) */
4990           ret = GST_FLOW_OK;
4991           goto done;
4992         } else if (G_UNLIKELY (stream_num < 0 ||
4993                 stream_num >= demux->num_streams)) {
4994           /* let's not give up on a stray invalid track number */
4995           GST_WARNING_OBJECT (demux,
4996               "Invalid stream %d for track number %" G_GUINT64_FORMAT
4997               "; ignoring block", stream_num, num);
4998           goto done;
4999         }
5000
5001         stream = g_ptr_array_index (demux->src, stream_num);
5002                 
5003 #ifdef MKVDEMUX_MODIFICATION
5004          if (demux->segment.rate < 0.0)
5005          {
5006                  if ((stream_num+1) == GST_MATROSKA_TRACK_TYPE_AUDIO)
5007                  {
5008                          /* found at least one audio block */
5009                         demux->found_audioframe = TRUE;
5010                  }
5011          }
5012 #endif   
5013         /* time (relative to cluster time) */
5014         time = ((gint16) GST_READ_UINT16_BE (data));
5015         data += 2;
5016         size -= 2;
5017         flags = GST_READ_UINT8 (data);
5018         data += 1;
5019         size -= 1;
5020
5021         GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
5022             flags);
5023
5024         switch ((flags & 0x06) >> 1) {
5025           case 0x0:            /* no lacing */
5026             laces = 1;
5027             lace_size = g_new (gint, 1);
5028             lace_size[0] = size;
5029             break;
5030
5031           case 0x1:            /* xiph lacing */
5032           case 0x2:            /* fixed-size lacing */
5033           case 0x3:            /* EBML lacing */
5034             if (size == 0)
5035               goto invalid_lacing;
5036             laces = GST_READ_UINT8 (data) + 1;
5037             data += 1;
5038             size -= 1;
5039             lace_size = g_new0 (gint, laces);
5040
5041             switch ((flags & 0x06) >> 1) {
5042               case 0x1:        /* xiph lacing */  {
5043                 guint temp, total = 0;
5044
5045                 for (n = 0; ret == GST_FLOW_OK && n < laces - 1; n++) {
5046                   while (1) {
5047                     if (size == 0)
5048                       goto invalid_lacing;
5049                     temp = GST_READ_UINT8 (data);
5050                     lace_size[n] += temp;
5051                     data += 1;
5052                     size -= 1;
5053                     if (temp != 0xff)
5054                       break;
5055                   }
5056                   total += lace_size[n];
5057                 }
5058                 lace_size[n] = size - total;
5059                 break;
5060               }
5061
5062               case 0x2:        /* fixed-size lacing */
5063                 for (n = 0; n < laces; n++)
5064                   lace_size[n] = size / laces;
5065                 break;
5066
5067               case 0x3:        /* EBML lacing */  {
5068                 guint total;
5069
5070                 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
5071                   goto data_error;
5072                 data += n;
5073                 size -= n;
5074                 total = lace_size[0] = num;
5075                 for (n = 1; ret == GST_FLOW_OK && n < laces - 1; n++) {
5076                   gint64 snum;
5077                   gint r;
5078
5079                   if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0)
5080                     goto data_error;
5081                   data += r;
5082                   size -= r;
5083                   lace_size[n] = lace_size[n - 1] + snum;
5084                   total += lace_size[n];
5085                 }
5086                 if (n < laces)
5087                   lace_size[n] = size - total;
5088                 break;
5089               }
5090             }
5091             break;
5092         }
5093
5094         if (stream->send_xiph_headers) {
5095           ret = gst_matroska_demux_push_xiph_codec_priv_data (demux, stream);
5096           stream->send_xiph_headers = FALSE;
5097         }
5098
5099         if (stream->send_flac_headers) {
5100           ret = gst_matroska_demux_push_flac_codec_priv_data (demux, stream);
5101           stream->send_flac_headers = FALSE;
5102         }
5103
5104         if (stream->send_speex_headers) {
5105           ret = gst_matroska_demux_push_speex_codec_priv_data (demux, stream);
5106           stream->send_speex_headers = FALSE;
5107         }
5108
5109         if (stream->send_dvd_event) {
5110           gst_matroska_demux_push_dvd_clut_change_event (demux, stream);
5111           /* FIXME: should we send this event again after (flushing) seek ? */
5112           stream->send_dvd_event = FALSE;
5113         }
5114
5115         if (ret != GST_FLOW_OK)
5116           break;
5117
5118         readblock = TRUE;
5119         break;
5120       }
5121
5122       case GST_MATROSKA_ID_BLOCKDURATION:{
5123         ret = gst_ebml_read_uint (ebml, &id, &block_duration);
5124         GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
5125             block_duration);
5126         break;
5127       }
5128
5129       case GST_MATROSKA_ID_REFERENCEBLOCK:{
5130         ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
5131         GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
5132             referenceblock);
5133         break;
5134       }
5135
5136       case GST_MATROSKA_ID_CODECSTATE:{
5137         guint8 *data;
5138         guint64 data_len = 0;
5139
5140         if ((ret =
5141                 gst_ebml_read_binary (ebml, &id, &data,
5142                     &data_len)) != GST_FLOW_OK)
5143           break;
5144
5145         if (G_UNLIKELY (stream == NULL)) {
5146           GST_WARNING_OBJECT (demux,
5147               "Unexpected CodecState subelement - ignoring");
5148           break;
5149         }
5150
5151         g_free (stream->codec_state);
5152         stream->codec_state = data;
5153         stream->codec_state_size = data_len;
5154
5155         /* Decode if necessary */
5156         if (stream->encodings && stream->encodings->len > 0
5157             && stream->codec_state && stream->codec_state_size > 0) {
5158           if (!gst_matroska_decode_data (stream->encodings,
5159                   &stream->codec_state, &stream->codec_state_size,
5160                   GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA, TRUE)) {
5161             GST_WARNING_OBJECT (demux, "Decoding codec state failed");
5162           }
5163         }
5164
5165         GST_DEBUG_OBJECT (demux, "CodecState of %u bytes",
5166             stream->codec_state_size);
5167         break;
5168       }
5169
5170       default:
5171         ret = gst_matroska_demux_parse_skip (demux, ebml, "BlockGroup", id);
5172         break;
5173
5174       case GST_MATROSKA_ID_BLOCKVIRTUAL:
5175       case GST_MATROSKA_ID_BLOCKADDITIONS:
5176       case GST_MATROSKA_ID_REFERENCEPRIORITY:
5177       case GST_MATROSKA_ID_REFERENCEVIRTUAL:
5178       case GST_MATROSKA_ID_SLICES:
5179         GST_DEBUG_OBJECT (demux,
5180             "Skipping BlockGroup subelement 0x%x - ignoring", id);
5181         ret = gst_ebml_read_skip (ebml);
5182         break;
5183     }
5184
5185     if (is_simpleblock)
5186       break;
5187   }
5188
5189   /* reading a number or so could have failed */
5190   if (ret != GST_FLOW_OK)
5191     goto data_error;
5192
5193   if (ret == GST_FLOW_OK && readblock) {
5194     guint64 duration = 0;
5195     gint64 lace_time = 0;
5196     gboolean delta_unit;
5197
5198     stream = g_ptr_array_index (demux->src, stream_num);
5199
5200     if (cluster_time != GST_CLOCK_TIME_NONE) {
5201       /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
5202        * Drop unless the lace contains timestamp 0? */
5203       if (time < 0 && (-time) > cluster_time) {
5204         lace_time = 0;
5205       } else {
5206         if (stream->timecodescale == 1.0)
5207           lace_time = (cluster_time + time) * demux->time_scale;
5208         else
5209           lace_time =
5210               gst_util_guint64_to_gdouble ((cluster_time + time) *
5211               demux->time_scale) * stream->timecodescale;
5212       }
5213     } else {
5214       lace_time = GST_CLOCK_TIME_NONE;
5215     }
5216
5217     /* need to refresh segment info ASAP */
5218     if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_newsegment) {
5219       GST_DEBUG_OBJECT (demux,
5220           "generating segment starting at %" GST_TIME_FORMAT,
5221           GST_TIME_ARGS (lace_time));
5222       /* pretend we seeked here */
5223       gst_segment_set_seek (&demux->segment, demux->segment.rate,
5224           GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, lace_time,
5225           GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE, NULL);
5226       /* now convey our segment notion downstream */
5227       gst_matroska_demux_send_event (demux, gst_event_new_new_segment (FALSE,
5228               demux->segment.rate, demux->segment.format, demux->segment.start,
5229               demux->segment.stop, demux->segment.start));
5230       demux->need_newsegment = FALSE;
5231     }
5232
5233     if (block_duration) {
5234       if (stream->timecodescale == 1.0)
5235         duration = gst_util_uint64_scale (block_duration, demux->time_scale, 1);
5236       else
5237         duration =
5238             gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble
5239             (gst_util_uint64_scale (block_duration, demux->time_scale,
5240                     1)) * stream->timecodescale);
5241     } else if (stream->default_duration) {
5242       duration = stream->default_duration * laces;
5243     }
5244     /* else duration is diff between timecode of this and next block */
5245
5246     /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
5247        a ReferenceBlock implies that this is not a keyframe. In either
5248        case, it only makes sense for video streams. */
5249     delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
5250         ((is_simpleblock && !(flags & 0x80)) || referenceblock);
5251
5252     if (delta_unit && stream->set_discont) {
5253       /* When doing seeks or such, we need to restart on key frames or
5254        * decoders might choke. */
5255       GST_DEBUG_OBJECT (demux, "skipping delta unit");
5256       goto done;
5257     }
5258
5259     for (n = 0; n < laces; n++) {
5260       GstBuffer *sub;
5261 #ifdef MKVDEMUX_MODIFICATION
5262       gboolean skip_flag = FALSE;
5263 #endif
5264
5265       if (G_UNLIKELY (lace_size[n] > size)) {
5266         GST_WARNING_OBJECT (demux, "Invalid lace size");
5267         break;
5268       }
5269
5270       /* QoS for video track with an index. the assumption is that
5271          index entries point to keyframes, but if that is not true we
5272          will instad skip until the next keyframe. */
5273       if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
5274           stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
5275           stream->index_table && demux->segment.rate > 0.0) {
5276         GstMatroskaTrackVideoContext *videocontext =
5277             (GstMatroskaTrackVideoContext *) stream;
5278         GstClockTime earliest_time;
5279         GstClockTime earliest_stream_time;
5280
5281         GST_OBJECT_LOCK (demux);
5282         earliest_time = videocontext->earliest_time;
5283         GST_OBJECT_UNLOCK (demux);
5284         earliest_stream_time = gst_segment_to_position (&demux->segment,
5285             GST_FORMAT_TIME, earliest_time);
5286
5287         if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
5288             GST_CLOCK_TIME_IS_VALID (earliest_stream_time) &&
5289             lace_time <= earliest_stream_time) {
5290           /* find index entry (keyframe) <= earliest_stream_time */
5291           GstMatroskaIndex *entry =
5292               gst_util_array_binary_search (stream->index_table->data,
5293               stream->index_table->len, sizeof (GstMatroskaIndex),
5294               (GCompareDataFunc) gst_matroska_index_seek_find,
5295               GST_SEARCH_MODE_BEFORE, &earliest_stream_time, NULL);
5296
5297           /* if that entry (keyframe) is after the current the current
5298              buffer, we can skip pushing (and thus decoding) all
5299              buffers until that keyframe. */
5300           if (entry && GST_CLOCK_TIME_IS_VALID (entry->time) &&
5301               entry->time > lace_time) {
5302             GST_LOG_OBJECT (demux, "Skipping lace before late keyframe");
5303             stream->set_discont = TRUE;
5304             goto next_lace;
5305           }
5306         }
5307       }
5308
5309       sub = gst_buffer_create_sub (buf,
5310           GST_BUFFER_SIZE (buf) - size, lace_size[n]);
5311       GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
5312
5313       if (delta_unit)
5314         GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
5315       else
5316         GST_BUFFER_FLAG_UNSET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
5317
5318       if (stream->encodings != NULL && stream->encodings->len > 0)
5319         sub = gst_matroska_decode_buffer (stream, sub);
5320
5321       if (sub == NULL) {
5322         GST_WARNING_OBJECT (demux, "Decoding buffer failed");
5323         goto next_lace;
5324       }
5325
5326       GST_BUFFER_TIMESTAMP (sub) = lace_time;
5327
5328       if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
5329         GstClockTime last_stop_end;
5330
5331 #ifndef MKVDEMUX_MODIFICATION
5332         /* Check if this stream is after segment stop */
5333         if (GST_CLOCK_TIME_IS_VALID (demux->segment.stop) &&
5334             lace_time >= demux->segment.stop) {
5335           GST_DEBUG_OBJECT (demux,
5336               "Stream %d after segment stop %" GST_TIME_FORMAT, stream->index,
5337               GST_TIME_ARGS (demux->segment.stop));
5338           gst_buffer_unref (sub);
5339           goto eos;
5340         }
5341         if (offset >= stream->to_offset) {
5342           GST_DEBUG_OBJECT (demux, "Stream %d after playback section",
5343               stream->index);
5344           gst_buffer_unref (sub);
5345           goto eos;
5346         }
5347 #endif
5348
5349         /* handle gaps, e.g. non-zero start-time, or an cue index entry
5350          * that landed us with timestamps not quite intended */
5351         if (GST_CLOCK_TIME_IS_VALID (demux->segment.last_stop) &&
5352             demux->segment.rate > 0.0) {
5353           GstClockTimeDiff diff;
5354
5355           /* only send newsegments with increasing start times,
5356            * otherwise if these go back and forth downstream (sinks) increase
5357            * accumulated time and running_time */
5358           diff = GST_CLOCK_DIFF (demux->segment.last_stop, lace_time);
5359           if (diff > 2 * GST_SECOND && lace_time > demux->segment.start &&
5360               (!GST_CLOCK_TIME_IS_VALID (demux->segment.stop) ||
5361                   lace_time < demux->segment.stop)) {
5362             GST_DEBUG_OBJECT (demux,
5363                 "Gap of %" G_GINT64_FORMAT " ns detected in"
5364                 "stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
5365                 "Sending updated NEWSEGMENT events", diff,
5366                 stream->index, GST_TIME_ARGS (stream->pos),
5367                 GST_TIME_ARGS (lace_time));
5368             /* send newsegment events such that the gap is not accounted in
5369              * accum time, hence running_time */
5370             /* close ahead of gap */
5371             gst_matroska_demux_send_event (demux,
5372                 gst_event_new_new_segment (TRUE, demux->segment.rate,
5373                     demux->segment.format, demux->segment.last_stop,
5374                     demux->segment.last_stop, demux->segment.last_stop));
5375             /* skip gap */
5376             gst_matroska_demux_send_event (demux,
5377                 gst_event_new_new_segment (FALSE, demux->segment.rate,
5378                     demux->segment.format, lace_time, demux->segment.stop,
5379                     lace_time));
5380             /* align segment view with downstream,
5381              * prevents double-counting accum when closing segment */
5382             gst_segment_set_newsegment (&demux->segment, FALSE,
5383                 demux->segment.rate, demux->segment.format, lace_time,
5384                 demux->segment.stop, lace_time);
5385             demux->segment.last_stop = lace_time;
5386           }
5387         }
5388
5389         if (!GST_CLOCK_TIME_IS_VALID (demux->segment.last_stop)
5390             || demux->segment.last_stop < lace_time) {
5391           demux->segment.last_stop = lace_time;
5392         }
5393
5394         last_stop_end = lace_time;
5395         if (duration) {
5396           GST_BUFFER_DURATION (sub) = duration / laces;
5397           last_stop_end += GST_BUFFER_DURATION (sub);
5398         }
5399
5400         if (!GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) ||
5401             demux->last_stop_end < last_stop_end)
5402           demux->last_stop_end = last_stop_end;
5403
5404         if (demux->segment.duration == -1 ||
5405             demux->segment.duration < lace_time) {
5406           gst_segment_set_duration (&demux->segment, GST_FORMAT_TIME,
5407               last_stop_end);
5408           gst_element_post_message (GST_ELEMENT_CAST (demux),
5409               gst_message_new_duration (GST_OBJECT_CAST (demux),
5410                   GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
5411         }
5412       }
5413
5414       stream->pos = lace_time;
5415
5416       gst_matroska_demux_sync_streams (demux);
5417
5418       if (stream->set_discont) {
5419         GST_DEBUG_OBJECT (demux, "marking DISCONT");
5420         GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
5421         stream->set_discont = FALSE;
5422       }
5423
5424       /* reverse playback book-keeping */
5425       if (!GST_CLOCK_TIME_IS_VALID (stream->from_time))
5426         stream->from_time = lace_time;
5427       if (stream->from_offset == -1)
5428         stream->from_offset = offset;
5429
5430           
5431 #ifdef MKVDEMUX_MODIFICATION
5432         if ((demux->segment.rate < 0.0) && ((stream_num+1) == GST_MATROSKA_TRACK_TYPE_VIDEO))
5433         {
5434                 if (GST_BUFFER_FLAG_IS_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT))
5435                 {
5436                         GST_DEBUG_OBJECT (demux, "skipping delta unit");
5437                         gst_buffer_unref (sub);
5438                         goto done;
5439                 }
5440                 else
5441                 {
5442                         /* found key frame*/
5443                         demux->found_videokeyframe = TRUE;
5444                 }
5445         }
5446 #endif
5447       GST_DEBUG_OBJECT (demux,
5448           "Pushing lace %d, data of size %d for stream %d, time=%"
5449           GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
5450           GST_BUFFER_SIZE (sub), stream_num,
5451           GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
5452           GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
5453
5454       if (demux->element_index) {
5455         if (stream->index_writer_id == -1)
5456           gst_index_get_writer_id (demux->element_index,
5457               GST_OBJECT (stream->pad), &stream->index_writer_id);
5458
5459         GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
5460             G_GUINT64_FORMAT " for writer id %d",
5461             GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)), cluster_offset,
5462             stream->index_writer_id);
5463         gst_index_add_association (demux->element_index,
5464             stream->index_writer_id, GST_BUFFER_FLAG_IS_SET (sub,
5465                 GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : GST_ASSOCIATION_FLAG_KEY_UNIT,
5466             GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (sub), GST_FORMAT_BYTES,
5467             cluster_offset, NULL);
5468       }
5469
5470       gst_buffer_set_caps (sub, GST_PAD_CAPS (stream->pad));
5471
5472       /* Postprocess the buffers depending on the codec used */
5473       if (stream->postprocess_frame) {
5474         GST_LOG_OBJECT (demux, "running post process");
5475         ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
5476       }
5477 #ifdef MKVDEMUX_MODIFICATION
5478       if (demux->video && demux->segment.rate > 1.0 && 
5479           stream->type <= GST_MATROSKA_TRACK_TYPE_AUDIO) 
5480       {
5481         skip_flag = FALSE;
5482         ret = gst_sec_matroska_forward_trickplay (demux, stream, sub, &skip_flag);      
5483       if (skip_flag == FALSE)
5484       {
5485         ret = gst_pad_push (stream->pad, sub);
5486       }
5487       else
5488       {
5489         gst_buffer_unref (sub);
5490       }
5491       } 
5492       else if (demux->segment.rate < 0.0)
5493       {
5494           ret = gst_matroska_rewind_trickplay (demux, stream, sub);
5495       }
5496       else 
5497 #endif
5498       {
5499         ret = gst_pad_push (stream->pad, sub);
5500           }
5501       if (demux->segment.rate < 0) {
5502         if (lace_time > demux->segment.stop && ret == GST_FLOW_UNEXPECTED) {
5503           /* In reverse playback we can get a GST_FLOW_UNEXPECTED when
5504            * we are at the end of the segment, so we just need to jump
5505            * back to the previous section. */
5506           GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
5507           ret = GST_FLOW_OK;
5508         }
5509       }
5510       /* combine flows */
5511       ret = gst_matroska_demux_combine_flows (demux, stream, ret);
5512
5513     next_lace:
5514       size -= lace_size[n];
5515       if (lace_time != GST_CLOCK_TIME_NONE && duration)
5516         lace_time += duration / laces;
5517       else
5518         lace_time = GST_CLOCK_TIME_NONE;
5519     }
5520   }
5521
5522 done:
5523   if (buf)
5524     gst_buffer_unref (buf);
5525   g_free (lace_size);
5526
5527   return ret;
5528
5529   /* EXITS */
5530 eos:
5531   {
5532     stream->eos = TRUE;
5533     ret = GST_FLOW_OK;
5534     /* combine flows */
5535     ret = gst_matroska_demux_combine_flows (demux, stream, ret);
5536     goto done;
5537   }
5538 invalid_lacing:
5539   {
5540     GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
5541     /* non-fatal, try next block(group) */
5542     ret = GST_FLOW_OK;
5543     goto done;
5544   }
5545 data_error:
5546   {
5547     GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
5548     /* non-fatal, try next block(group) */
5549     ret = GST_FLOW_OK;
5550     goto done;
5551   }
5552 }
5553
5554 /* return FALSE if block(group) should be skipped (due to a seek) */
5555 static inline gboolean
5556 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
5557 {
5558   if (G_UNLIKELY (demux->seek_block)) {
5559     if (!(--demux->seek_block)) {
5560       return TRUE;
5561     } else {
5562       GST_LOG_OBJECT (demux, "should skip block due to seek");
5563       return FALSE;
5564     }
5565   } else {
5566     return TRUE;
5567   }
5568 }
5569
5570 static GstFlowReturn
5571 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
5572     GstEbmlRead * ebml)
5573 {
5574   GstFlowReturn ret;
5575   guint64 seek_pos = (guint64) - 1;
5576   guint32 seek_id = 0;
5577   guint32 id;
5578
5579   DEBUG_ELEMENT_START (demux, ebml, "Seek");
5580
5581   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
5582     DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
5583     return ret;
5584   }
5585
5586   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
5587     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
5588       break;
5589
5590     switch (id) {
5591       case GST_MATROSKA_ID_SEEKID:
5592       {
5593         guint64 t;
5594
5595         if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
5596           break;
5597
5598         GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
5599         seek_id = t;
5600         break;
5601       }
5602
5603       case GST_MATROSKA_ID_SEEKPOSITION:
5604       {
5605         guint64 t;
5606
5607         if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
5608           break;
5609
5610         if (t > G_MAXINT64) {
5611           GST_WARNING_OBJECT (demux,
5612               "Too large SeekPosition %" G_GUINT64_FORMAT, t);
5613           break;
5614         }
5615
5616         GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
5617         seek_pos = t;
5618         break;
5619       }
5620
5621       default:
5622         ret = gst_matroska_demux_parse_skip (demux, ebml, "SeekHead", id);
5623         break;
5624     }
5625   }
5626
5627   if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED)
5628     return ret;
5629
5630   if (!seek_id || seek_pos == (guint64) - 1) {
5631     GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
5632         G_GUINT64_FORMAT ")", seek_id, seek_pos);
5633     return GST_FLOW_OK;
5634   }
5635
5636   switch (seek_id) {
5637     case GST_MATROSKA_ID_SEEKHEAD:
5638     {
5639     }
5640     case GST_MATROSKA_ID_CUES:
5641     case GST_MATROSKA_ID_TAGS:
5642     case GST_MATROSKA_ID_TRACKS:
5643     case GST_MATROSKA_ID_SEGMENTINFO:
5644     case GST_MATROSKA_ID_ATTACHMENTS:
5645     case GST_MATROSKA_ID_CHAPTERS:
5646     {
5647       guint64 before_pos, length;
5648       guint needed;
5649
5650       /* remember */
5651       length = gst_matroska_demux_get_length (demux);
5652       before_pos = demux->offset;
5653
5654       if (length == (guint64) - 1) {
5655         GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
5656         break;
5657       }
5658
5659       /* check for validity */
5660       if (seek_pos + demux->ebml_segment_start + 12 >= length) {
5661         GST_WARNING_OBJECT (demux,
5662             "SeekHead reference lies outside file!" " (%"
5663             G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
5664             G_GUINT64_FORMAT ")", seek_pos, demux->ebml_segment_start, length);
5665         break;
5666       }
5667
5668       /* only pick up index location when streaming */
5669       if (demux->streaming) {
5670         if (seek_id == GST_MATROSKA_ID_CUES) {
5671           demux->index_offset = seek_pos + demux->ebml_segment_start;
5672           GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
5673               demux->index_offset);
5674         }
5675         break;
5676       }
5677
5678       /* seek */
5679       demux->offset = seek_pos + demux->ebml_segment_start;
5680
5681       /* check ID */
5682       if ((ret = gst_matroska_demux_peek_id_length_pull (demux, &id, &length,
5683                   &needed)) != GST_FLOW_OK)
5684         goto finish;
5685
5686       if (id != seek_id) {
5687         GST_WARNING_OBJECT (demux,
5688             "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
5689             seek_id, id, seek_pos + demux->ebml_segment_start);
5690       } else {
5691         /* now parse */
5692         ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5693       }
5694
5695     finish:
5696       /* seek back */
5697       demux->offset = before_pos;
5698       break;
5699     }
5700
5701     case GST_MATROSKA_ID_CLUSTER:
5702     {
5703       guint64 pos = seek_pos + demux->ebml_segment_start;
5704
5705       GST_LOG_OBJECT (demux, "Cluster position");
5706       if (G_UNLIKELY (!demux->clusters))
5707         demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
5708       g_array_append_val (demux->clusters, pos);
5709       break;
5710     }
5711
5712     default:
5713       GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
5714       break;
5715   }
5716   DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
5717
5718   return ret;
5719 }
5720
5721 static GstFlowReturn
5722 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
5723 {
5724   GstFlowReturn ret = GST_FLOW_OK;
5725   guint32 id;
5726
5727   DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
5728
5729   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
5730     DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
5731     return ret;
5732   }
5733
5734   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
5735     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
5736       break;
5737
5738     switch (id) {
5739       case GST_MATROSKA_ID_SEEKENTRY:
5740       {
5741         ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
5742         /* Ignore EOS and errors here */
5743         if (ret != GST_FLOW_OK) {
5744           GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
5745           ret = GST_FLOW_OK;
5746         }
5747         break;
5748       }
5749
5750       default:
5751         ret = gst_matroska_demux_parse_skip (demux, ebml, "SeekHead", id);
5752         break;
5753     }
5754   }
5755
5756   DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
5757
5758   /* Sort clusters by position for easier searching */
5759   if (demux->clusters)
5760     g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
5761
5762   return ret;
5763 }
5764
5765 #define GST_FLOW_OVERFLOW   GST_FLOW_CUSTOM_ERROR
5766
5767 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
5768
5769 static inline GstFlowReturn
5770 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
5771 {
5772   if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
5773     /* only a few blocks are expected/allowed to be large,
5774      * and will be recursed into, whereas others will be read and must fit */
5775     if (demux->streaming) {
5776       /* fatal in streaming case, as we can't step over easily */
5777       GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
5778           ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
5779               "file might be corrupt.", bytes));
5780       return GST_FLOW_ERROR;
5781     } else {
5782       /* indicate higher level to quietly give up */
5783       GST_DEBUG_OBJECT (demux,
5784           "too large block of size %" G_GUINT64_FORMAT, bytes);
5785       return GST_FLOW_ERROR;
5786     }
5787   } else {
5788     return GST_FLOW_OK;
5789   }
5790 }
5791
5792 /* returns TRUE if we truely are in error state, and should give up */
5793 static inline gboolean
5794 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
5795 {
5796   if (!demux->streaming && demux->next_cluster_offset > 0) {
5797     /* just repositioning to where next cluster should be and try from there */
5798     GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
5799         G_GUINT64_FORMAT, demux->next_cluster_offset);
5800     demux->offset = demux->next_cluster_offset;
5801     demux->next_cluster_offset = 0;
5802     return FALSE;
5803   } else {
5804     gint64 pos;
5805
5806     /* sigh, one last attempt above and beyond call of duty ...;
5807      * search for cluster mark following current pos */
5808     pos = demux->offset;
5809     GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
5810     if (gst_matroska_demux_search_cluster (demux, &pos) != GST_FLOW_OK) {
5811       /* did not work, give up */
5812       return TRUE;
5813     } else {
5814       GST_DEBUG_OBJECT (demux, "... found at  %" G_GUINT64_FORMAT, pos);
5815       /* try that position */
5816       demux->offset = pos;
5817       return FALSE;
5818     }
5819   }
5820 }
5821
5822 static inline GstFlowReturn
5823 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
5824 {
5825   GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
5826   demux->offset += flush;
5827   if (demux->streaming) {
5828     GstFlowReturn ret;
5829
5830     /* hard to skip large blocks when streaming */
5831     ret = gst_matroska_demux_check_read_size (demux, flush);
5832     if (ret != GST_FLOW_OK)
5833       return ret;
5834     if (flush <= gst_adapter_available (demux->adapter))
5835       gst_adapter_flush (demux->adapter, flush);
5836     else
5837       return GST_FLOW_UNEXPECTED;
5838   }
5839   return GST_FLOW_OK;
5840 }
5841
5842 /* initializes @ebml with @bytes from input stream at current offset.
5843  * Returns UNEXPECTED if insufficient available,
5844  * ERROR if too much was attempted to read. */
5845 static inline GstFlowReturn
5846 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
5847     GstEbmlRead * ebml)
5848 {
5849   GstBuffer *buffer = NULL;
5850   GstFlowReturn ret = GST_FLOW_OK;
5851
5852   GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
5853       bytes);
5854   ret = gst_matroska_demux_check_read_size (demux, bytes);
5855   if (G_UNLIKELY (ret != GST_FLOW_OK)) {
5856     if (!demux->streaming) {
5857       /* in pull mode, we can skip */
5858       if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
5859         ret = GST_FLOW_OVERFLOW;
5860     } else {
5861       /* otherwise fatal */
5862       ret = GST_FLOW_ERROR;
5863     }
5864     goto exit;
5865   }
5866   if (demux->streaming) {
5867     if (gst_adapter_available (demux->adapter) >= bytes)
5868       buffer = gst_adapter_take_buffer (demux->adapter, bytes);
5869     else
5870       ret = GST_FLOW_UNEXPECTED;
5871   } else
5872     ret = gst_matroska_demux_peek_bytes (demux, demux->offset, bytes, &buffer,
5873         NULL);
5874   if (G_LIKELY (buffer)) {
5875     gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer, demux->offset);
5876     demux->offset += bytes;
5877   }
5878 exit:
5879   return ret;
5880 }
5881
5882 static void
5883 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
5884 {
5885   GstQuery *query;
5886   gboolean seekable = FALSE;
5887   gint64 start = -1, stop = -1;
5888
5889   query = gst_query_new_seeking (GST_FORMAT_BYTES);
5890   if (!gst_pad_peer_query (demux->sinkpad, query)) {
5891     GST_DEBUG_OBJECT (demux, "seeking query failed");
5892     goto done;
5893   }
5894
5895   gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
5896
5897   /* try harder to query upstream size if we didn't get it the first time */
5898   if (seekable && stop == -1) {
5899     GstFormat fmt = GST_FORMAT_BYTES;
5900
5901     GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
5902     gst_pad_query_peer_duration (demux->sinkpad, &fmt, &stop);
5903   }
5904
5905   /* if upstream doesn't know the size, it's likely that it's not seekable in
5906    * practice even if it technically may be seekable */
5907   if (seekable && (start != 0 || stop <= start)) {
5908     GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
5909     seekable = FALSE;
5910   }
5911
5912 done:
5913   GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
5914       G_GUINT64_FORMAT ")", seekable, start, stop);
5915   demux->seekable = seekable;
5916
5917   gst_query_unref (query);
5918 }
5919
5920 static GstFlowReturn
5921 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
5922 {
5923   guint32 id;
5924   guint64 before_pos;
5925   guint64 length;
5926   guint needed;
5927   GstFlowReturn ret = GST_FLOW_OK;
5928
5929   GST_WARNING_OBJECT (demux,
5930       "Found Cluster element before Tracks, searching Tracks");
5931
5932   /* remember */
5933   before_pos = demux->offset;
5934
5935   /* Search Tracks element */
5936   while (TRUE) {
5937     ret = gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
5938     if (ret != GST_FLOW_OK)
5939       break;
5940
5941     if (id != GST_MATROSKA_ID_TRACKS) {
5942       /* we may be skipping large cluster here, so forego size check etc */
5943       /* ... but we can't skip undefined size; force error */
5944       if (length == G_MAXUINT64) {
5945         ret = gst_matroska_demux_check_read_size (demux, length);
5946         break;
5947       } else {
5948         demux->offset += needed;
5949         demux->offset += length;
5950       }
5951       continue;
5952     }
5953
5954     /* will lead to track parsing ... */
5955     ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5956     break;
5957   }
5958
5959   /* seek back */
5960   demux->offset = before_pos;
5961
5962   return ret;
5963 }
5964
5965 #define GST_READ_CHECK(stmt)  \
5966 G_STMT_START { \
5967   if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
5968     if (ret == GST_FLOW_OVERFLOW) { \
5969       ret = GST_FLOW_OK; \
5970     } \
5971     goto read_error; \
5972   } \
5973 } G_STMT_END
5974
5975 static GstFlowReturn
5976 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
5977     guint64 length, guint needed)
5978 {
5979   GstEbmlRead ebml = { 0, };
5980   GstFlowReturn ret = GST_FLOW_OK;
5981   guint64 read;
5982
5983   GST_DEBUG_OBJECT (demux, "Parsing Element id 0x%x, "
5984       "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
5985
5986   /* if we plan to read and parse this element, we need prefix (id + length)
5987    * and the contents */
5988   /* mind about overflow wrap-around when dealing with undefined size */
5989   read = length;
5990   if (G_LIKELY (length != G_MAXUINT64))
5991     read += needed;
5992
5993   switch (demux->state) {
5994     case GST_MATROSKA_DEMUX_STATE_START:
5995       switch (id) {
5996         case GST_EBML_ID_HEADER:
5997           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
5998           ret = gst_matroska_demux_parse_header (demux, &ebml);
5999           if (ret != GST_FLOW_OK)
6000             goto parse_failed;
6001           demux->state = GST_MATROSKA_DEMUX_STATE_SEGMENT;
6002           gst_matroska_demux_check_seekability (demux);
6003           break;
6004         default:
6005           goto invalid_header;
6006           break;
6007       }
6008       break;
6009     case GST_MATROSKA_DEMUX_STATE_SEGMENT:
6010       switch (id) {
6011         case GST_MATROSKA_ID_SEGMENT:
6012           /* eat segment prefix */
6013           GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
6014           GST_DEBUG_OBJECT (demux,
6015               "Found Segment start at offset %" G_GUINT64_FORMAT,
6016               demux->offset);
6017           /* seeks are from the beginning of the segment,
6018            * after the segment ID/length */
6019           demux->ebml_segment_start = demux->offset;
6020           demux->state = GST_MATROSKA_DEMUX_STATE_HEADER;
6021           break;
6022         default:
6023           GST_WARNING_OBJECT (demux,
6024               "Expected a Segment ID (0x%x), but received 0x%x!",
6025               GST_MATROSKA_ID_SEGMENT, id);
6026           GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
6027           break;
6028       }
6029       break;
6030     case GST_MATROSKA_DEMUX_STATE_SCANNING:
6031       if (id != GST_MATROSKA_ID_CLUSTER &&
6032           id != GST_MATROSKA_ID_CLUSTERTIMECODE)
6033         goto skip;
6034       /* fall-through */
6035     case GST_MATROSKA_DEMUX_STATE_HEADER:
6036     case GST_MATROSKA_DEMUX_STATE_DATA:
6037     case GST_MATROSKA_DEMUX_STATE_SEEK:
6038       switch (id) {
6039         case GST_MATROSKA_ID_SEGMENTINFO:
6040           if (!demux->segmentinfo_parsed) {
6041             GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6042             ret = gst_matroska_demux_parse_info (demux, &ebml);
6043           } else {
6044             GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
6045           }
6046           break;
6047         case GST_MATROSKA_ID_TRACKS:
6048           if (!demux->tracks_parsed) {
6049             GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6050             ret = gst_matroska_demux_parse_tracks (demux, &ebml);
6051           } else {
6052             GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
6053           }
6054           break;
6055         case GST_MATROSKA_ID_CLUSTER:
6056           if (G_UNLIKELY (!demux->tracks_parsed)) {
6057             if (demux->streaming) {
6058               GST_DEBUG_OBJECT (demux, "Cluster before Track");
6059               goto not_streamable;
6060             } else {
6061               ret = gst_matroska_demux_find_tracks (demux);
6062               if (!demux->tracks_parsed)
6063                 goto no_tracks;
6064             }
6065           }
6066           if (G_UNLIKELY (demux->state == GST_MATROSKA_DEMUX_STATE_HEADER)) {
6067             demux->state = GST_MATROSKA_DEMUX_STATE_DATA;
6068             demux->first_cluster_offset = demux->offset;
6069             GST_DEBUG_OBJECT (demux, "signaling no more pads");
6070             gst_element_no_more_pads (GST_ELEMENT (demux));
6071             /* send initial newsegment */
6072             gst_matroska_demux_send_event (demux,
6073                 gst_event_new_new_segment (FALSE, 1.0,
6074                     GST_FORMAT_TIME, 0,
6075                     (demux->segment.duration >
6076                         0) ? demux->segment.duration : -1, 0));
6077           }
6078           demux->cluster_time = GST_CLOCK_TIME_NONE;
6079           demux->cluster_offset = demux->offset;
6080           if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
6081             GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
6082                 " not found in Cluster, trying next Cluster's first block instead",
6083                 demux->seek_block);
6084             demux->seek_block = 0;
6085           }
6086           demux->seek_first = FALSE;
6087           /* record next cluster for recovery */
6088           if (read != G_MAXUINT64)
6089             demux->next_cluster_offset = demux->cluster_offset + read;
6090           /* eat cluster prefix */
6091           gst_matroska_demux_flush (demux, needed);
6092
6093           break;
6094         case GST_MATROSKA_ID_CLUSTERTIMECODE:
6095         {
6096           guint64 num;
6097
6098           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6099           if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
6100             goto parse_failed;
6101           GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
6102           demux->cluster_time = num;
6103           if (demux->element_index) {
6104             if (demux->element_index_writer_id == -1)
6105               gst_index_get_writer_id (demux->element_index,
6106                   GST_OBJECT (demux), &demux->element_index_writer_id);
6107             GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
6108                 G_GUINT64_FORMAT " for writer id %d",
6109                 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
6110                 demux->element_index_writer_id);
6111             gst_index_add_association (demux->element_index,
6112                 demux->element_index_writer_id, GST_ASSOCIATION_FLAG_KEY_UNIT,
6113                 GST_FORMAT_TIME, demux->cluster_time,
6114                 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
6115           }
6116           break;
6117         }
6118         case GST_MATROSKA_ID_BLOCKGROUP:
6119           if (!gst_matroska_demux_seek_block (demux))
6120             goto skip;
6121           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6122           DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
6123           if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
6124             ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
6125                 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
6126           }
6127
6128 #ifdef MKVDEMUX_MODIFICATION
6129           if ((demux->segment.rate < 0.0) && (demux->found_videokeyframe == TRUE) && (demux->found_audioframe == TRUE))
6130          {
6131                 /* Naveen: we displayed at least one one audio block and one video key frame
6132                    Now, goto previous cluster */
6133                  int i =0;
6134                  int minusone = -1;
6135                  guint64 duration = 0;
6136                  GstClockTime time_position;
6137                  GstMatroskaIndex *entry = NULL;
6138
6139
6140                  for (i = 0; i < demux->src->len; i++) 
6141                  {
6142                 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->src, i);
6143                         if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
6144                         {
6145                                 GST_DEBUG ("video track duration = %"G_GUINT64_FORMAT"position = %"GST_TIME_FORMAT"\n", 
6146                                         stream->default_duration, GST_TIME_ARGS(stream->pos));
6147                                 duration = stream->default_duration;
6148                                 time_position = stream->pos;
6149                         }
6150                  }
6151
6152                 if((time_position - (minusone *demux->segment.rate)*((double)duration/1000000000))> 0)
6153                 {
6154                     time_position -= (minusone *demux->segment.rate)*((double)duration/1000000000);
6155                 }
6156                 else
6157                 {
6158                         time_position=0;
6159                 }
6160                 
6161                  for (i = 0; i < demux->src->len; i++) 
6162                  {
6163                 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->src, i);
6164                                 guint64 offset;
6165                         
6166                         GST_OBJECT_LOCK (demux);
6167                         if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
6168                         {
6169                         if ((entry = gst_matroskademux_do_index_seek (demux, stream, time_position, -1, FALSE)) == NULL) {
6170                                 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
6171                         }
6172
6173                         GST_DEBUG_OBJECT (demux, "pos = %"G_GUINT64_FORMAT", track = %d, block = %d, time = %"GST_TIME_FORMAT"\n", 
6174                                         entry->pos, entry->track, entry->block, GST_TIME_ARGS(entry->time));
6175
6176                                 offset =  entry->pos + demux->ebml_segment_start;
6177                                 if (offset >= gst_matroska_demux_get_length(demux))
6178                                 {
6179                                         GST_INFO_OBJECT (demux, " Seek failed");
6180                                         goto seek_failed;
6181                                 }
6182                                 demux->offset = offset;
6183                         }
6184                         stream->pos = entry->time;
6185                         stream->set_discont = TRUE;
6186                         stream->last_flow = GST_FLOW_OK;
6187                         if (stream->pos > 0.0)
6188                         {
6189                                 stream->eos = FALSE;
6190                         }
6191                         else
6192                         {
6193                                 stream->eos = TRUE;
6194                                 GST_INFO_OBJECT (demux, "Reached EOS.....");
6195                         }
6196                         demux->segment.last_stop = entry->time;
6197
6198                          GST_OBJECT_UNLOCK (demux);
6199
6200                  }
6201
6202                 if (entry->time == 0.0)
6203                 {
6204                         gst_segment_init (&demux->segment, GST_FORMAT_TIME);
6205                         gst_segment_set_duration (&demux->segment, GST_FORMAT_TIME, demux->duration); 
6206                         
6207                         /* send new_segment event with start =0 and stop = duration */
6208                                 demux->new_segment = gst_event_new_new_segment_full (TRUE,
6209                                         demux->segment.rate, demux->segment.applied_rate, demux->segment.format,
6210                                         demux->segment.start, demux->segment.stop, demux->segment.time);
6211                 }
6212
6213                 demux->found_videokeyframe = FALSE;
6214                 demux->found_audioframe = FALSE;
6215                 
6216                 return ret;
6217          }
6218 #endif    
6219           DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
6220           break;
6221         case GST_MATROSKA_ID_SIMPLEBLOCK:
6222           if (!gst_matroska_demux_seek_block (demux))
6223             goto skip;
6224           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6225           DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
6226                  
6227           ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
6228               &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
6229                   
6230
6231 #ifdef MKVDEMUX_MODIFICATION
6232           if ((demux->segment.rate < 0.0) && (demux->found_videokeyframe == TRUE) && (demux->found_audioframe == TRUE))
6233          {
6234                 /* Naveen: we displayed at least one one audio block and one video key frame
6235                    Now, goto previous cluster */
6236                  int i =0;
6237                  int minusone = -1;
6238                  guint64 duration = 0;
6239                  GstClockTime time_position;
6240                  GstMatroskaIndex *entry = NULL;
6241
6242
6243                  for (i = 0; i < demux->src->len; i++) 
6244                  {
6245                 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->src, i);
6246                         if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
6247                         {
6248                                 GST_DEBUG ("video track duration = %"G_GUINT64_FORMAT"position = %"GST_TIME_FORMAT"\n", 
6249                                         stream->default_duration, GST_TIME_ARGS(stream->pos));
6250                                 duration = stream->default_duration;
6251                                 time_position = stream->pos;
6252                         }
6253                  }
6254
6255
6256                 if((time_position - (minusone *demux->segment.rate)*((double)duration/1000000000))> 0)
6257                 {
6258                     time_position -= (minusone *demux->segment.rate)*((double)duration/1000000000);
6259                 }
6260                 else
6261                 {
6262                         time_position=0;
6263                 }
6264                 
6265                  for (i = 0; i < demux->src->len; i++) 
6266                  {
6267                 GstMatroskaTrackContext *stream = g_ptr_array_index (demux->src, i);
6268                                 guint64 offset;
6269                         
6270                         GST_OBJECT_LOCK (demux);
6271                         if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
6272                         {
6273
6274                         if ((entry = gst_matroskademux_do_index_seek (demux, stream, time_position, -1, FALSE)) == NULL) {
6275                                 GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
6276                         }
6277
6278                         GST_DEBUG_OBJECT (demux, "pos = %"G_GUINT64_FORMAT", track = %d, block = %d, time = %"GST_TIME_FORMAT"\n", 
6279                                         entry->pos, entry->track, entry->block, GST_TIME_ARGS(entry->time));
6280
6281                         /* seek (relative to matroska segment) */
6282
6283
6284
6285
6286
6287                                 offset =  entry->pos + demux->ebml_segment_start;
6288                                 if (offset >= gst_matroska_demux_get_length(demux))
6289                                 {
6290                                         GST_INFO_OBJECT (demux, " Seek failed");
6291                                         goto seek_failed;
6292                                 }
6293                                 demux->offset = offset;
6294                                 
6295                         
6296                         }
6297
6298
6299                         stream->pos = entry->time;
6300                         stream->set_discont = TRUE;
6301                         stream->last_flow = GST_FLOW_OK;
6302                         if (stream->pos > 0.0)
6303                         {
6304                                 stream->eos = FALSE;
6305                         }
6306                         else
6307                         {
6308
6309                                 stream->eos = TRUE;
6310                                 GST_INFO_OBJECT (demux, "Reached EOS.....");
6311                         }
6312                         demux->segment.last_stop = entry->time;
6313
6314                          GST_OBJECT_UNLOCK (demux);
6315
6316                  }
6317
6318                 if (entry->time == 0.0)
6319                 {
6320
6321
6322                         gst_segment_init (&demux->segment, GST_FORMAT_TIME);
6323                         gst_segment_set_duration (&demux->segment, GST_FORMAT_TIME, demux->duration); 
6324                         
6325                         /* send new_segment event with start =0 and stop = duration */
6326                                 demux->new_segment = gst_event_new_new_segment_full (TRUE,
6327                                         demux->segment.rate, demux->segment.applied_rate, demux->segment.format,
6328                                         demux->segment.start, demux->segment.stop, demux->segment.time);
6329                 }
6330         
6331
6332                 demux->found_videokeyframe = FALSE;
6333                 demux->found_audioframe = FALSE;
6334                 
6335                 return ret;
6336          }
6337 #endif    
6338           DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
6339           break;
6340         case GST_MATROSKA_ID_ATTACHMENTS:
6341           if (!demux->attachments_parsed) {
6342             GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6343             ret = gst_matroska_demux_parse_attachments (demux, &ebml);
6344           } else {
6345             GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
6346           }
6347           break;
6348         case GST_MATROSKA_ID_TAGS:
6349           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6350           ret = gst_matroska_demux_parse_metadata (demux, &ebml);
6351           break;
6352         case GST_MATROSKA_ID_CHAPTERS:
6353           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6354           ret = gst_matroska_demux_parse_chapters (demux, &ebml);
6355           break;
6356         case GST_MATROSKA_ID_SEEKHEAD:
6357           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6358           ret = gst_matroska_demux_parse_contents (demux, &ebml);
6359           break;
6360         case GST_MATROSKA_ID_CUES:
6361           if (demux->index_parsed) {
6362             GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
6363             break;
6364           }
6365           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
6366           ret = gst_matroska_demux_parse_index (demux, &ebml);
6367           /* only push based; delayed index building */
6368           if (ret == GST_FLOW_OK
6369               && demux->state == GST_MATROSKA_DEMUX_STATE_SEEK) {
6370             GstEvent *event;
6371
6372             GST_OBJECT_LOCK (demux);
6373             event = demux->seek_event;
6374             demux->seek_event = NULL;
6375             GST_OBJECT_UNLOCK (demux);
6376
6377             g_assert (event);
6378             /* unlikely to fail, since we managed to seek to this point */
6379             if (!gst_matroska_demux_handle_seek_event (demux, NULL, event))
6380               goto seek_failed;
6381             /* resume data handling, main thread clear to seek again */
6382             GST_OBJECT_LOCK (demux);
6383             demux->state = GST_MATROSKA_DEMUX_STATE_DATA;
6384             GST_OBJECT_UNLOCK (demux);
6385           }
6386           break;
6387         case GST_MATROSKA_ID_POSITION:
6388         case GST_MATROSKA_ID_PREVSIZE:
6389         case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
6390         case GST_MATROSKA_ID_SILENTTRACKS:
6391           GST_DEBUG_OBJECT (demux,
6392               "Skipping Cluster subelement 0x%x - ignoring", id);
6393           /* fall-through */
6394         default:
6395         skip:
6396           GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
6397           GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
6398           break;
6399       }
6400       break;
6401   }
6402
6403   if (ret == GST_FLOW_PARSE)
6404     goto parse_failed;
6405
6406 exit:
6407   gst_ebml_read_clear (&ebml);
6408   return ret;
6409
6410   /* ERRORS */
6411 read_error:
6412   {
6413     /* simply exit, maybe not enough data yet */
6414     /* no ebml to clear if read error */
6415     return ret;
6416   }
6417 parse_failed:
6418   {
6419     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
6420         ("Failed to parse Element 0x%x", id));
6421     ret = GST_FLOW_ERROR;
6422     goto exit;
6423   }
6424 not_streamable:
6425   {
6426     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
6427         ("File layout does not permit streaming"));
6428     ret = GST_FLOW_ERROR;
6429     goto exit;
6430   }
6431 no_tracks:
6432   {
6433     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
6434         ("No Tracks element found"));
6435     ret = GST_FLOW_ERROR;
6436     goto exit;
6437   }
6438 invalid_header:
6439   {
6440     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
6441     ret = GST_FLOW_ERROR;
6442     goto exit;
6443   }
6444 seek_failed:
6445   {
6446     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
6447     ret = GST_FLOW_ERROR;
6448     goto exit;
6449   }
6450 }
6451
6452 static void
6453 gst_matroska_demux_loop (GstPad * pad)
6454 {
6455   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
6456   GstFlowReturn ret;
6457   guint32 id;
6458   guint64 length;
6459   guint needed;
6460
6461   /* If we have to close a segment, send a new segment to do this now */
6462   if (G_LIKELY (demux->state == GST_MATROSKA_DEMUX_STATE_DATA)) {
6463     if (G_UNLIKELY (demux->close_segment)) {
6464       gst_matroska_demux_send_event (demux, demux->close_segment);
6465       demux->close_segment = NULL;
6466     }
6467     if (G_UNLIKELY (demux->new_segment)) {
6468       gst_matroska_demux_send_event (demux, demux->new_segment);
6469       demux->new_segment = NULL;
6470     }
6471   }
6472
6473   ret = gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
6474   if (ret == GST_FLOW_UNEXPECTED)
6475     goto eos;
6476   if (ret != GST_FLOW_OK) {
6477     if (gst_matroska_demux_check_parse_error (demux))
6478       goto pause;
6479     else
6480       return;
6481   }
6482
6483   GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
6484       "size %" G_GUINT64_FORMAT ", needed %d", demux->offset, id,
6485       length, needed);
6486
6487   ret = gst_matroska_demux_parse_id (demux, id, length, needed);
6488   if (ret == GST_FLOW_UNEXPECTED)
6489     goto eos;
6490   if (ret != GST_FLOW_OK)
6491     goto pause;
6492
6493   /* check if we're at the end of a configured segment */
6494   if (G_LIKELY (demux->src->len)) {
6495     guint i;
6496
6497     g_assert (demux->num_streams == demux->src->len);
6498     for (i = 0; i < demux->src->len; i++) {
6499       GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
6500       GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
6501           GST_TIME_ARGS (context->pos));
6502       if (context->eos == FALSE)
6503         goto next;
6504     }
6505
6506     GST_INFO_OBJECT (demux, "All streams are EOS");
6507     ret = GST_FLOW_UNEXPECTED;
6508     goto eos;
6509   }
6510
6511 next:
6512   if (G_UNLIKELY (demux->offset == gst_matroska_demux_get_length (demux))) {
6513     GST_LOG_OBJECT (demux, "Reached end of stream");
6514     ret = GST_FLOW_UNEXPECTED;
6515     goto eos;
6516   }
6517
6518   return;
6519
6520   /* ERRORS */
6521 eos:
6522   {
6523     if (demux->segment.rate < 0.0) {
6524       ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
6525       if (ret == GST_FLOW_OK)
6526         return;
6527     }
6528     /* fall-through */
6529   }
6530 pause:
6531   {
6532     const gchar *reason = gst_flow_get_name (ret);
6533     gboolean push_eos = FALSE;
6534
6535     GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
6536     demux->segment_running = FALSE;
6537     gst_pad_pause_task (demux->sinkpad);
6538
6539     if (ret == GST_FLOW_UNEXPECTED) {
6540       /* perform EOS logic */
6541
6542       /* Close the segment, i.e. update segment stop with the duration
6543        * if no stop was set */
6544       if (GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
6545           !GST_CLOCK_TIME_IS_VALID (demux->segment.stop)) {
6546         GstEvent *event =
6547             gst_event_new_new_segment_full (TRUE, demux->segment.rate,
6548             demux->segment.applied_rate, demux->segment.format,
6549             demux->segment.start,
6550             MAX (demux->last_stop_end, demux->segment.start),
6551             demux->segment.time);
6552         gst_matroska_demux_send_event (demux, event);
6553       }
6554
6555       if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
6556         gint64 stop;
6557
6558         /* for segment playback we need to post when (in stream time)
6559          * we stopped, this is either stop (when set) or the duration. */
6560         if ((stop = demux->segment.stop) == -1)
6561           stop = demux->last_stop_end;
6562
6563         GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
6564         gst_element_post_message (GST_ELEMENT (demux),
6565             gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
6566                 stop));
6567       } else {
6568         push_eos = TRUE;
6569       }
6570     } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_UNEXPECTED) {
6571       /* for fatal errors we post an error message */
6572       GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
6573           ("stream stopped, reason %s", reason));
6574       push_eos = TRUE;
6575     }
6576     if (push_eos) {
6577       /* send EOS, and prevent hanging if no streams yet */
6578       GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
6579       if (!gst_matroska_demux_send_event (demux, gst_event_new_eos ()) &&
6580           (ret == GST_FLOW_UNEXPECTED)) {
6581         GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
6582             (NULL), ("got eos but no streams (yet)"));
6583       }
6584     }
6585     return;
6586   }
6587 }
6588
6589 /*
6590  * Create and push a flushing seek event upstream
6591  */
6592 static gboolean
6593 perform_seek_to_offset (GstMatroskaDemux * demux, guint64 offset)
6594 {
6595   GstEvent *event;
6596   gboolean res = 0;
6597
6598   GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
6599
6600   event =
6601       gst_event_new_seek (1.0, GST_FORMAT_BYTES,
6602       GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
6603       GST_SEEK_TYPE_NONE, -1);
6604
6605   res = gst_pad_push_event (demux->sinkpad, event);
6606
6607   /* newsegment event will update offset */
6608   return res;
6609 }
6610
6611 static const guint8 *
6612 gst_matroska_demux_peek_adapter (GstMatroskaDemux * demux, guint peek)
6613 {
6614   return gst_adapter_peek (demux->adapter, peek);
6615 }
6616
6617 static GstFlowReturn
6618 gst_matroska_demux_peek_id_length_push (GstMatroskaDemux * demux, guint32 * _id,
6619     guint64 * _length, guint * _needed)
6620 {
6621   return gst_ebml_peek_id_length (_id, _length, _needed,
6622       (GstPeekData) gst_matroska_demux_peek_adapter, (gpointer) demux,
6623       GST_ELEMENT_CAST (demux), demux->offset);
6624 }
6625
6626 static GstFlowReturn
6627 gst_matroska_demux_chain (GstPad * pad, GstBuffer * buffer)
6628 {
6629   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
6630   guint available;
6631   GstFlowReturn ret = GST_FLOW_OK;
6632   guint needed = 0;
6633   guint32 id;
6634   guint64 length;
6635
6636   if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
6637     GST_DEBUG_OBJECT (demux, "got DISCONT");
6638     gst_adapter_clear (demux->adapter);
6639     GST_OBJECT_LOCK (demux);
6640     gst_matroska_demux_reset_streams (demux, GST_CLOCK_TIME_NONE, FALSE);
6641     GST_OBJECT_UNLOCK (demux);
6642   }
6643
6644   gst_adapter_push (demux->adapter, buffer);
6645   buffer = NULL;
6646
6647 next:
6648   available = gst_adapter_available (demux->adapter);
6649
6650   ret = gst_matroska_demux_peek_id_length_push (demux, &id, &length, &needed);
6651   if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED))
6652     return ret;
6653
6654   GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
6655       "size %" G_GUINT64_FORMAT ", needed %d, available %d", demux->offset, id,
6656       length, needed, available);
6657
6658   if (needed > available)
6659     return GST_FLOW_OK;
6660
6661   ret = gst_matroska_demux_parse_id (demux, id, length, needed);
6662   if (ret == GST_FLOW_UNEXPECTED) {
6663     /* need more data */
6664     return GST_FLOW_OK;
6665   } else if (ret != GST_FLOW_OK) {
6666     return ret;
6667   } else
6668     goto next;
6669 }
6670
6671 static gboolean
6672 gst_matroska_demux_handle_sink_event (GstPad * pad, GstEvent * event)
6673 {
6674   gboolean res = TRUE;
6675   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
6676
6677   GST_DEBUG_OBJECT (demux,
6678       "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
6679
6680   switch (GST_EVENT_TYPE (event)) {
6681     case GST_EVENT_NEWSEGMENT:
6682     {
6683       GstFormat format;
6684       gdouble rate, arate;
6685       gint64 start, stop, time = 0;
6686       gboolean update;
6687       GstSegment segment;
6688
6689       /* some debug output */
6690       gst_segment_init (&segment, GST_FORMAT_UNDEFINED);
6691       gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
6692           &start, &stop, &time);
6693       gst_segment_set_newsegment_full (&segment, update, rate, arate, format,
6694           start, stop, time);
6695       GST_DEBUG_OBJECT (demux,
6696           "received format %d newsegment %" GST_SEGMENT_FORMAT, format,
6697           &segment);
6698
6699       if (demux->state < GST_MATROSKA_DEMUX_STATE_DATA) {
6700         GST_DEBUG_OBJECT (demux, "still starting");
6701         goto exit;
6702       }
6703
6704       /* we only expect a BYTE segment, e.g. following a seek */
6705       if (format != GST_FORMAT_BYTES) {
6706         GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
6707         goto exit;
6708       }
6709
6710       GST_DEBUG_OBJECT (demux, "clearing segment state");
6711       /* clear current segment leftover */
6712       gst_adapter_clear (demux->adapter);
6713       /* and some streaming setup */
6714       demux->offset = start;
6715       /* do not know where we are;
6716        * need to come across a cluster and generate newsegment */
6717       demux->segment.last_stop = GST_CLOCK_TIME_NONE;
6718       demux->cluster_time = GST_CLOCK_TIME_NONE;
6719       demux->cluster_offset = 0;
6720       demux->need_newsegment = TRUE;
6721       /* but keep some of the upstream segment */
6722       demux->segment.rate = rate;
6723     exit:
6724       /* chain will send initial newsegment after pads have been added,
6725        * or otherwise come up with one */
6726       GST_DEBUG_OBJECT (demux, "eating event");
6727       gst_event_unref (event);
6728       res = TRUE;
6729       break;
6730     }
6731     case GST_EVENT_EOS:
6732     {
6733       if (demux->state != GST_MATROSKA_DEMUX_STATE_DATA) {
6734         gst_event_unref (event);
6735         GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
6736             (NULL), ("got eos and didn't receive a complete header object"));
6737       } else if (demux->num_streams == 0) {
6738         GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
6739             (NULL), ("got eos but no streams (yet)"));
6740       } else {
6741         gst_matroska_demux_send_event (demux, event);
6742       }
6743       break;
6744     }
6745     case GST_EVENT_FLUSH_STOP:
6746     {
6747       gst_adapter_clear (demux->adapter);
6748       GST_OBJECT_LOCK (demux);
6749       gst_matroska_demux_reset_streams (demux, GST_CLOCK_TIME_NONE, TRUE);
6750       GST_OBJECT_UNLOCK (demux);
6751       demux->segment.last_stop = GST_CLOCK_TIME_NONE;
6752       demux->cluster_time = GST_CLOCK_TIME_NONE;
6753       demux->cluster_offset = 0;
6754       /* fall-through */
6755     }
6756     default:
6757       res = gst_pad_event_default (pad, event);
6758       break;
6759   }
6760
6761   return res;
6762 }
6763
6764 static gboolean
6765 gst_matroska_demux_sink_activate (GstPad * sinkpad)
6766 {
6767   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
6768
6769   if (gst_pad_check_pull_range (sinkpad)) {
6770     GST_DEBUG ("going to pull mode");
6771     demux->streaming = FALSE;
6772     return gst_pad_activate_pull (sinkpad, TRUE);
6773   } else {
6774     GST_DEBUG ("going to push (streaming) mode");
6775     demux->streaming = TRUE;
6776     return gst_pad_activate_push (sinkpad, TRUE);
6777   }
6778
6779   return FALSE;
6780 }
6781
6782 static gboolean
6783 gst_matroska_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
6784 {
6785   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
6786
6787   if (active) {
6788     /* if we have a scheduler we can start the task */
6789     demux->segment_running = TRUE;
6790     gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
6791         sinkpad);
6792   } else {
6793     demux->segment_running = FALSE;
6794     gst_pad_stop_task (sinkpad);
6795   }
6796
6797   return TRUE;
6798 }
6799
6800 static void
6801 gst_duration_to_fraction (guint64 duration, gint * dest_n, gint * dest_d)
6802 {
6803   static const int common_den[] = { 1, 2, 3, 4, 1001 };
6804   int n, d;
6805   int i;
6806   guint64 a;
6807
6808   for (i = 0; i < G_N_ELEMENTS (common_den); i++) {
6809     d = common_den[i];
6810     n = floor (0.5 + (d * 1e9) / duration);
6811     a = gst_util_uint64_scale_int (1000000000, d, n);
6812     if (duration >= a - 1 && duration <= a + 1) {
6813       goto out;
6814     }
6815   }
6816
6817   gst_util_double_to_fraction (1e9 / duration, &n, &d);
6818
6819 out:
6820   /* set results */
6821   *dest_n = n;
6822   *dest_d = d;
6823 }
6824
6825 static GstCaps *
6826 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
6827     videocontext, const gchar * codec_id, guint8 * data, guint size,
6828     gchar ** codec_name, guint32 * riff_fourcc)
6829 {
6830   GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
6831   GstCaps *caps = NULL;
6832
6833   g_assert (videocontext != NULL);
6834   g_assert (codec_name != NULL);
6835
6836   context->send_xiph_headers = FALSE;
6837   context->send_flac_headers = FALSE;
6838   context->send_speex_headers = FALSE;
6839
6840   if (riff_fourcc)
6841     *riff_fourcc = 0;
6842
6843   /* TODO: check if we have all codec types from matroska-ids.h
6844    *       check if we have to do more special things with codec_private
6845    *
6846    * Add support for
6847    *  GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
6848    *  GST_MATROSKA_CODEC_ID_VIDEO_SNOW
6849    */
6850
6851   if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
6852     gst_riff_strf_vids *vids = NULL;
6853
6854     if (data) {
6855       GstBuffer *buf = NULL;
6856
6857       vids = (gst_riff_strf_vids *) data;
6858
6859       /* assure size is big enough */
6860       if (size < 24) {
6861         GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
6862         return NULL;
6863       }
6864       if (size < sizeof (gst_riff_strf_vids)) {
6865         vids = g_new (gst_riff_strf_vids, 1);
6866         memcpy (vids, data, size);
6867       }
6868
6869       /* little-endian -> byte-order */
6870       vids->size = GUINT32_FROM_LE (vids->size);
6871       vids->width = GUINT32_FROM_LE (vids->width);
6872       vids->height = GUINT32_FROM_LE (vids->height);
6873       vids->planes = GUINT16_FROM_LE (vids->planes);
6874       vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
6875       vids->compression = GUINT32_FROM_LE (vids->compression);
6876       vids->image_size = GUINT32_FROM_LE (vids->image_size);
6877       vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
6878       vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
6879       vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
6880       vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
6881
6882       if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
6883         buf = gst_buffer_new_and_alloc (size - sizeof (gst_riff_strf_vids));
6884         memcpy (GST_BUFFER_DATA (buf),
6885             (guint8 *) vids + sizeof (gst_riff_strf_vids),
6886             GST_BUFFER_SIZE (buf));
6887       }
6888
6889       if (riff_fourcc)
6890         *riff_fourcc = vids->compression;
6891
6892       caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
6893           buf, NULL, codec_name);
6894
6895       if (caps == NULL) {
6896         GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
6897             GST_FOURCC_ARGS (vids->compression));
6898       }
6899
6900       if (buf)
6901         gst_buffer_unref (buf);
6902
6903       if (vids != (gst_riff_strf_vids *) data)
6904         g_free (vids);
6905     }
6906   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
6907     guint32 fourcc = 0;
6908
6909     switch (videocontext->fourcc) {
6910       case GST_MAKE_FOURCC ('I', '4', '2', '0'):
6911         *codec_name = g_strdup ("Raw planar YUV 4:2:0");
6912         fourcc = videocontext->fourcc;
6913         break;
6914       case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
6915         *codec_name = g_strdup ("Raw packed YUV 4:2:2");
6916         fourcc = videocontext->fourcc;
6917         break;
6918       case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
6919         *codec_name = g_strdup ("Raw packed YUV 4:2:0");
6920         fourcc = videocontext->fourcc;
6921         break;
6922       case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
6923         *codec_name = g_strdup ("Raw packed YUV 4:2:2");
6924         fourcc = videocontext->fourcc;
6925         break;
6926       case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
6927         *codec_name = g_strdup ("Raw packed YUV 4:4:4 with alpha channel");
6928         fourcc = videocontext->fourcc;
6929         break;
6930
6931       default:
6932         GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
6933             GST_FOURCC_ARGS (videocontext->fourcc));
6934         return NULL;
6935     }
6936
6937     caps = gst_caps_new_simple ("video/x-raw-yuv",
6938         "format", GST_TYPE_FOURCC, fourcc, NULL);
6939   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
6940     caps = gst_caps_new_simple ("video/x-divx",
6941         "divxversion", G_TYPE_INT, 4, NULL);
6942     *codec_name = g_strdup ("MPEG-4 simple profile");
6943   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
6944       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
6945 #if 0
6946     caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
6947             "divxversion", G_TYPE_INT, 5, NULL),
6948         gst_structure_new ("video/x-xvid", NULL),
6949         gst_structure_new ("video/mpeg",
6950             "mpegversion", G_TYPE_INT, 4,
6951             "systemstream", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
6952 #endif
6953     caps = gst_caps_new_simple ("video/mpeg",
6954         "mpegversion", G_TYPE_INT, 4,
6955         "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
6956     if (data) {
6957       GstBuffer *priv = gst_buffer_new_and_alloc (size);
6958
6959       memcpy (GST_BUFFER_DATA (priv), data, size);
6960       gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6961       gst_buffer_unref (priv);
6962     }
6963     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
6964       *codec_name = g_strdup ("MPEG-4 advanced simple profile");
6965     else
6966       *codec_name = g_strdup ("MPEG-4 advanced profile");
6967   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
6968 #if 0
6969     caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
6970             "divxversion", G_TYPE_INT, 3, NULL),
6971         gst_structure_new ("video/x-msmpeg",
6972             "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
6973 #endif
6974     caps = gst_caps_new_simple ("video/x-msmpeg",
6975         "msmpegversion", G_TYPE_INT, 43, NULL);
6976     *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
6977   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
6978       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
6979     gint mpegversion;
6980
6981     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
6982       mpegversion = 1;
6983     else
6984       mpegversion = 2;
6985
6986     caps = gst_caps_new_simple ("video/mpeg",
6987         "systemstream", G_TYPE_BOOLEAN, FALSE,
6988         "mpegversion", G_TYPE_INT, mpegversion, NULL);
6989     *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
6990     context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
6991   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
6992     caps = gst_caps_new_simple ("image/jpeg", NULL);
6993     *codec_name = g_strdup ("Motion-JPEG");
6994   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
6995     caps = gst_caps_new_simple ("video/x-h264", NULL);
6996     if (data) {
6997       GstBuffer *priv = gst_buffer_new_and_alloc (size);
6998
6999       /* First byte is the version, second is the profile indication, and third
7000        * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
7001        * level indication. */
7002       gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
7003           size - 1);
7004
7005       memcpy (GST_BUFFER_DATA (priv), data, size);
7006       gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
7007       gst_buffer_unref (priv);
7008
7009       gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
7010           "alignment", G_TYPE_STRING, "au", NULL);
7011     } else {
7012       GST_WARNING ("No codec data found, assuming output is byte-stream");
7013       gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
7014           NULL);
7015     }
7016     *codec_name = g_strdup ("H264");
7017   } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
7018       (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
7019       (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
7020       (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
7021     gint rmversion = -1;
7022
7023     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
7024       rmversion = 1;
7025     else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
7026       rmversion = 2;
7027     else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
7028       rmversion = 3;
7029     else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
7030       rmversion = 4;
7031
7032     caps = gst_caps_new_simple ("video/x-pn-realvideo",
7033         "rmversion", G_TYPE_INT, rmversion, NULL);
7034     GST_DEBUG ("data:%p, size:0x%x", data, size);
7035     /* We need to extract the extradata ! */
7036     if (data && (size >= 0x22)) {
7037       GstBuffer *priv;
7038       guint rformat;
7039       guint subformat;
7040
7041       subformat = GST_READ_UINT32_BE (data + 0x1a);
7042       rformat = GST_READ_UINT32_BE (data + 0x1e);
7043
7044       priv = gst_buffer_new_and_alloc (size - 0x1a);
7045
7046       memcpy (GST_BUFFER_DATA (priv), data + 0x1a, size - 0x1a);
7047       gst_caps_set_simple (caps,
7048           "codec_data", GST_TYPE_BUFFER, priv,
7049           "format", G_TYPE_INT, rformat,
7050           "subformat", G_TYPE_INT, subformat, NULL);
7051       gst_buffer_unref (priv);
7052
7053     }
7054     *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
7055   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
7056     caps = gst_caps_new_simple ("video/x-theora", NULL);
7057     context->send_xiph_headers = TRUE;
7058   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
7059     caps = gst_caps_new_simple ("video/x-dirac", NULL);
7060     *codec_name = g_strdup_printf ("Dirac");
7061   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
7062     caps = gst_caps_new_simple ("video/x-vp8", NULL);
7063     *codec_name = g_strdup_printf ("On2 VP8");
7064   } else {
7065     GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
7066     return NULL;
7067   }
7068
7069   if (caps != NULL) {
7070     int i;
7071     GstStructure *structure;
7072
7073     for (i = 0; i < gst_caps_get_size (caps); i++) {
7074       structure = gst_caps_get_structure (caps, i);
7075
7076       /* FIXME: use the real unit here! */
7077       GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
7078           videocontext->pixel_width,
7079           videocontext->pixel_height,
7080           videocontext->display_width, videocontext->display_height);
7081
7082       /* pixel width and height are the w and h of the video in pixels */
7083       if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
7084         gint w = videocontext->pixel_width;
7085
7086         gint h = videocontext->pixel_height;
7087
7088         gst_structure_set (structure,
7089             "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
7090       }
7091
7092       if (videocontext->display_width > 0 && videocontext->display_height > 0) {
7093         int n, d;
7094
7095         /* calculate the pixel aspect ratio using the display and pixel w/h */
7096         n = videocontext->display_width * videocontext->pixel_height;
7097         d = videocontext->display_height * videocontext->pixel_width;
7098         GST_DEBUG ("setting PAR to %d/%d", n, d);
7099         gst_structure_set (structure, "pixel-aspect-ratio",
7100             GST_TYPE_FRACTION,
7101             videocontext->display_width * videocontext->pixel_height,
7102             videocontext->display_height * videocontext->pixel_width, NULL);
7103       }
7104
7105       if (videocontext->default_fps > 0.0) {
7106         GValue fps_double = { 0, };
7107         GValue fps_fraction = { 0, };
7108
7109         g_value_init (&fps_double, G_TYPE_DOUBLE);
7110         g_value_init (&fps_fraction, GST_TYPE_FRACTION);
7111         g_value_set_double (&fps_double, videocontext->default_fps);
7112         g_value_transform (&fps_double, &fps_fraction);
7113
7114         GST_DEBUG ("using default fps %f", videocontext->default_fps);
7115
7116         gst_structure_set_value (structure, "framerate", &fps_fraction);
7117         g_value_unset (&fps_double);
7118         g_value_unset (&fps_fraction);
7119       } else if (context->default_duration > 0) {
7120         int fps_n, fps_d;
7121
7122         gst_duration_to_fraction (context->default_duration, &fps_n, &fps_d);
7123
7124         GST_DEBUG ("using default duration %" G_GUINT64_FORMAT
7125             " framerate %d/%d", context->default_duration, fps_n, fps_d);
7126
7127         gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
7128             fps_n, fps_d, NULL);
7129       } else {
7130         /* sort of a hack to get most codecs to support,
7131          * even if the default_duration is missing */
7132         gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
7133             25, 1, NULL);
7134       }
7135
7136       if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
7137         gst_structure_set (structure, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
7138     }
7139
7140     gst_caps_do_simplify (caps);
7141   }
7142
7143   return caps;
7144 }
7145
7146 /*
7147  * Some AAC specific code... *sigh*
7148  * FIXME: maybe we should use '15' and code the sample rate explicitly
7149  * if the sample rate doesn't match the predefined rates exactly? (tpm)
7150  */
7151
7152 static gint
7153 aac_rate_idx (gint rate)
7154 {
7155   if (92017 <= rate)
7156     return 0;
7157   else if (75132 <= rate)
7158     return 1;
7159   else if (55426 <= rate)
7160     return 2;
7161   else if (46009 <= rate)
7162     return 3;
7163   else if (37566 <= rate)
7164     return 4;
7165   else if (27713 <= rate)
7166     return 5;
7167   else if (23004 <= rate)
7168     return 6;
7169   else if (18783 <= rate)
7170     return 7;
7171   else if (13856 <= rate)
7172     return 8;
7173   else if (11502 <= rate)
7174     return 9;
7175   else if (9391 <= rate)
7176     return 10;
7177   else
7178     return 11;
7179 }
7180
7181 static gint
7182 aac_profile_idx (const gchar * codec_id)
7183 {
7184   gint profile;
7185
7186   if (strlen (codec_id) <= 12)
7187     profile = 3;
7188   else if (!strncmp (&codec_id[12], "MAIN", 4))
7189     profile = 0;
7190   else if (!strncmp (&codec_id[12], "LC", 2))
7191     profile = 1;
7192   else if (!strncmp (&codec_id[12], "SSR", 3))
7193     profile = 2;
7194   else
7195     profile = 3;
7196
7197   return profile;
7198 }
7199
7200 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
7201
7202 static GstCaps *
7203 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
7204     audiocontext, const gchar * codec_id, guint8 * data, guint size,
7205     gchar ** codec_name, guint16 * riff_audio_fmt)
7206 {
7207   GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
7208   GstCaps *caps = NULL;
7209
7210   g_assert (audiocontext != NULL);
7211   g_assert (codec_name != NULL);
7212
7213   if (riff_audio_fmt)
7214     *riff_audio_fmt = 0;
7215
7216   context->send_xiph_headers = FALSE;
7217   context->send_flac_headers = FALSE;
7218   context->send_speex_headers = FALSE;
7219
7220   /* TODO: check if we have all codec types from matroska-ids.h
7221    *       check if we have to do more special things with codec_private
7222    *       check if we need bitdepth in different places too
7223    *       implement channel position magic
7224    * Add support for:
7225    *  GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
7226    *  GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
7227    *  GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
7228    *  GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
7229    */
7230
7231   if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
7232       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
7233       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
7234     gint layer;
7235
7236     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
7237       layer = 1;
7238     else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
7239       layer = 2;
7240     else
7241       layer = 3;
7242
7243     caps = gst_caps_new_simple ("audio/mpeg",
7244         "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
7245     *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
7246   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
7247       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
7248     gint endianness;
7249
7250     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
7251       endianness = G_BIG_ENDIAN;
7252     else
7253       endianness = G_LITTLE_ENDIAN;
7254
7255     caps = gst_caps_new_simple ("audio/x-raw-int",
7256         "width", G_TYPE_INT, audiocontext->bitdepth,
7257         "depth", G_TYPE_INT, audiocontext->bitdepth,
7258         "signed", G_TYPE_BOOLEAN, audiocontext->bitdepth != 8,
7259         "endianness", G_TYPE_INT, endianness, NULL);
7260
7261     *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
7262         audiocontext->bitdepth);
7263   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
7264     caps = gst_caps_new_simple ("audio/x-raw-float",
7265         "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
7266         "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
7267     *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
7268         audiocontext->bitdepth);
7269   } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
7270           strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
7271     caps = gst_caps_new_simple ("audio/x-ac3",
7272         "framed", G_TYPE_BOOLEAN, TRUE, NULL);
7273     *codec_name = g_strdup ("AC-3 audio");
7274   } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
7275           strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
7276     caps = gst_caps_new_simple ("audio/x-eac3",
7277         "framed", G_TYPE_BOOLEAN, TRUE, NULL);
7278     *codec_name = g_strdup ("E-AC-3 audio");
7279   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
7280     caps = gst_caps_new_simple ("audio/x-dts", NULL);
7281     *codec_name = g_strdup ("DTS audio");
7282   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
7283     caps = gst_caps_new_simple ("audio/x-vorbis", NULL);
7284     context->send_xiph_headers = TRUE;
7285     /* vorbis decoder does tags */
7286   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
7287     caps = gst_caps_new_simple ("audio/x-flac", NULL);
7288     context->send_flac_headers = TRUE;
7289   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
7290     caps = gst_caps_new_simple ("audio/x-speex", NULL);
7291     context->send_speex_headers = TRUE;
7292   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
7293     gst_riff_strf_auds auds;
7294
7295     if (data) {
7296       GstBuffer *codec_data = gst_buffer_new ();
7297
7298       /* little-endian -> byte-order */
7299       auds.format = GST_READ_UINT16_LE (data);
7300       auds.channels = GST_READ_UINT16_LE (data + 2);
7301       auds.rate = GST_READ_UINT32_LE (data + 4);
7302       auds.av_bps = GST_READ_UINT32_LE (data + 8);
7303       auds.blockalign = GST_READ_UINT16_LE (data + 12);
7304       auds.size = GST_READ_UINT16_LE (data + 16);
7305
7306       /* 18 is the waveformatex size */
7307       gst_buffer_set_data (codec_data, data + 18, auds.size);
7308
7309       if (riff_audio_fmt)
7310         *riff_audio_fmt = auds.format;
7311
7312       caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
7313           codec_data, codec_name);
7314       gst_buffer_unref (codec_data);
7315
7316       if (caps == NULL) {
7317         GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
7318       }
7319     }
7320   } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
7321     GstBuffer *priv = NULL;
7322     gint mpegversion;
7323     gint rate_idx, profile;
7324     guint8 *data = NULL;
7325
7326     /* unspecified AAC profile with opaque private codec data */
7327     if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
7328       if (context->codec_priv_size >= 2) {
7329         guint obj_type, freq_index, explicit_freq_bytes = 0;
7330
7331         codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
7332         mpegversion = 4;
7333         freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
7334         obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
7335         if (freq_index == 15)
7336           explicit_freq_bytes = 3;
7337         GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
7338         priv = gst_buffer_new_and_alloc (context->codec_priv_size);
7339         memcpy (GST_BUFFER_DATA (priv), context->codec_priv,
7340             context->codec_priv_size);
7341         /* assume SBR if samplerate <= 24kHz */
7342         if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
7343             (context->codec_priv_size == (5 + explicit_freq_bytes))) {
7344           audiocontext->samplerate *= 2;
7345         }
7346       } else {
7347         GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
7348         /* this is pretty broken;
7349          * maybe we need to make up some default private,
7350          * or maybe ADTS data got dumped in.
7351          * Let's set up some private data now, and check actual data later */
7352         /* just try this and see what happens ... */
7353         codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
7354         context->postprocess_frame = gst_matroska_demux_check_aac;
7355       }
7356     }
7357
7358     /* make up decoder-specific data if it is not supplied */
7359     if (priv == NULL) {
7360       priv = gst_buffer_new_and_alloc (5);
7361       data = GST_BUFFER_DATA (priv);
7362       rate_idx = aac_rate_idx (audiocontext->samplerate);
7363       profile = aac_profile_idx (codec_id);
7364
7365       data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
7366       data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
7367       GST_BUFFER_SIZE (priv) = 2;
7368
7369       if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
7370               strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
7371         mpegversion = 2;
7372       } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
7373               strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
7374         mpegversion = 4;
7375
7376         if (g_strrstr (codec_id, "SBR")) {
7377           /* HE-AAC (aka SBR AAC) */
7378           audiocontext->samplerate *= 2;
7379           rate_idx = aac_rate_idx (audiocontext->samplerate);
7380           data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
7381           data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
7382           data[4] = (1 << 7) | (rate_idx << 3);
7383           GST_BUFFER_SIZE (priv) = 5;
7384         }
7385       } else {
7386         gst_buffer_unref (priv);
7387         priv = NULL;
7388         GST_ERROR ("Unknown AAC profile and no codec private data");
7389       }
7390     }
7391
7392     if (priv) {
7393       caps = gst_caps_new_simple ("audio/mpeg",
7394           "mpegversion", G_TYPE_INT, mpegversion,
7395           "framed", G_TYPE_BOOLEAN, TRUE, NULL);
7396       gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
7397       *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
7398     }
7399   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
7400     caps = gst_caps_new_simple ("audio/x-tta",
7401         "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
7402     *codec_name = g_strdup ("TTA audio");
7403   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
7404     caps = gst_caps_new_simple ("audio/x-wavpack",
7405         "width", G_TYPE_INT, audiocontext->bitdepth,
7406         "framed", G_TYPE_BOOLEAN, TRUE, NULL);
7407     *codec_name = g_strdup ("Wavpack audio");
7408     context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
7409     audiocontext->wvpk_block_index = 0;
7410   } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
7411       (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
7412       (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
7413     gint raversion = -1;
7414
7415     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
7416       raversion = 1;
7417     else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
7418       raversion = 8;
7419     else
7420       raversion = 2;
7421
7422     caps = gst_caps_new_simple ("audio/x-pn-realaudio",
7423         "raversion", G_TYPE_INT, raversion, NULL);
7424     /* Extract extra information from caps, mapping varies based on codec */
7425     if (data && (size >= 0x50)) {
7426       GstBuffer *priv;
7427       guint flavor;
7428       guint packet_size;
7429       guint height;
7430       guint leaf_size;
7431       guint sample_width;
7432       guint extra_data_size;
7433
7434       GST_ERROR ("real audio raversion:%d", raversion);
7435       if (raversion == 8) {
7436         /* COOK */
7437         flavor = GST_READ_UINT16_BE (data + 22);
7438         packet_size = GST_READ_UINT32_BE (data + 24);
7439         height = GST_READ_UINT16_BE (data + 40);
7440         leaf_size = GST_READ_UINT16_BE (data + 44);
7441         sample_width = GST_READ_UINT16_BE (data + 58);
7442         extra_data_size = GST_READ_UINT32_BE (data + 74);
7443
7444         GST_ERROR
7445             ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
7446             flavor, packet_size, height, leaf_size, sample_width,
7447             extra_data_size);
7448         gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
7449             G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
7450             G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
7451
7452         if ((size - 78) >= extra_data_size) {
7453           priv = gst_buffer_new_and_alloc (extra_data_size);
7454           memcpy (GST_BUFFER_DATA (priv), data + 78, extra_data_size);
7455           gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
7456           gst_buffer_unref (priv);
7457         }
7458       }
7459     }
7460
7461     *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
7462   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
7463     caps = gst_caps_new_simple ("audio/x-sipro", NULL);
7464     *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
7465   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
7466     caps = gst_caps_new_simple ("audio/x-ralf-mpeg4-generic", NULL);
7467     *codec_name = g_strdup ("Real Audio Lossless");
7468   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
7469     caps = gst_caps_new_simple ("audio/x-vnd.sony.atrac3", NULL);
7470     *codec_name = g_strdup ("Sony ATRAC3");
7471   } else {
7472     GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
7473     return NULL;
7474   }
7475
7476   if (caps != NULL) {
7477     if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
7478       gint i;
7479
7480       for (i = 0; i < gst_caps_get_size (caps); i++) {
7481         gst_structure_set (gst_caps_get_structure (caps, i),
7482             "channels", G_TYPE_INT, audiocontext->channels,
7483             "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
7484       }
7485     }
7486
7487     gst_caps_do_simplify (caps);
7488   }
7489
7490   return caps;
7491 }
7492
7493 static GstCaps *
7494 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
7495     subtitlecontext, const gchar * codec_id, gpointer data, guint size)
7496 {
7497   GstCaps *caps = NULL;
7498   GstMatroskaTrackContext *context =
7499       (GstMatroskaTrackContext *) subtitlecontext;
7500
7501   /* for backwards compatibility */
7502   if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
7503     codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
7504   else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
7505     codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
7506   else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
7507     codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
7508   else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
7509     codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
7510
7511   /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
7512    * Check if we have to do something with codec_private */
7513   if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
7514     caps = gst_caps_new_simple ("text/plain", NULL);
7515     context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
7516   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
7517     caps = gst_caps_new_simple ("application/x-ssa", NULL);
7518     context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
7519   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
7520     caps = gst_caps_new_simple ("application/x-ass", NULL);
7521     context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
7522   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
7523     caps = gst_caps_new_simple ("application/x-usf", NULL);
7524     context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
7525   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
7526     caps = gst_caps_new_simple ("video/x-dvd-subpicture", NULL);
7527     ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
7528   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
7529     caps = gst_caps_new_simple ("subpicture/x-pgs", NULL);
7530   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
7531     caps = gst_caps_new_simple ("subtitle/x-kate", NULL);
7532     context->send_xiph_headers = TRUE;
7533   } else {
7534     GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
7535     caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
7536   }
7537
7538   if (data != NULL && size > 0) {
7539     GstBuffer *buf;
7540
7541     buf = gst_buffer_new_and_alloc (size);
7542     memcpy (GST_BUFFER_DATA (buf), data, size);
7543     gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
7544     gst_buffer_unref (buf);
7545   }
7546
7547   return caps;
7548 }
7549
7550 static void
7551 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
7552 {
7553   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
7554
7555   GST_OBJECT_LOCK (demux);
7556   if (demux->element_index)
7557     gst_object_unref (demux->element_index);
7558   demux->element_index = index ? gst_object_ref (index) : NULL;
7559   GST_OBJECT_UNLOCK (demux);
7560   GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT, demux->element_index);
7561 }
7562
7563 static GstIndex *
7564 gst_matroska_demux_get_index (GstElement * element)
7565 {
7566   GstIndex *result = NULL;
7567   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
7568
7569   GST_OBJECT_LOCK (demux);
7570   if (demux->element_index)
7571     result = gst_object_ref (demux->element_index);
7572   GST_OBJECT_UNLOCK (demux);
7573
7574   GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
7575
7576   return result;
7577 }
7578 #ifdef MKVDEMUX_MODIFICATION
7579 static GstFlowReturn
7580 gst_sec_matroska_demux_find_tracks (GstMatroskaDemux * demux)
7581 {
7582   guint32 id;
7583   guint64 before_pos;
7584   guint64 length;
7585   guint needed;
7586   GstFlowReturn ret = GST_FLOW_OK;
7587
7588   GST_WARNING_OBJECT (demux,
7589       "Found Cluster element before Tracks, searching Tracks");
7590
7591   /* remember */
7592   before_pos = demux->offset;
7593
7594   /* Search Tracks element */
7595   while (TRUE) {
7596     ret = gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
7597     if (ret != GST_FLOW_OK)
7598       break;
7599
7600     if (id != GST_MATROSKA_ID_TRACKS) {
7601       /* we may be skipping large cluster here, so forego size check etc */
7602       /* ... but we can't skip undefined size; force error */
7603       if (length == G_MAXUINT64) {
7604         ret = gst_matroska_demux_check_read_size (demux, length);
7605         break;
7606       } else {
7607         demux->offset += needed;
7608         demux->offset += length;
7609       }
7610       continue;
7611     }
7612
7613     /* will lead to track parsing ... */
7614     ret = gst_sec_matroska_demux_parse_id (demux, id, length, needed);
7615     break;
7616   }
7617
7618   /* seek back */
7619   demux->offset = before_pos;
7620
7621   return ret;
7622 }
7623 static GstFlowReturn
7624 gst_sec_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
7625     guint64 length, guint needed)
7626 {
7627   GstEbmlRead ebml = { 0, };
7628   GstFlowReturn ret = GST_FLOW_OK;
7629   guint64 read;
7630
7631   GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
7632       "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
7633
7634   /* if we plan to read and parse this element, we need prefix (id + length)
7635    * and the contents */
7636   /* mind about overflow wrap-around when dealing with undefined size */
7637   read = length;
7638   if (G_LIKELY (length != G_MAXUINT64))
7639     read += needed;
7640
7641   switch (demux->state) {
7642     case GST_MATROSKA_DEMUX_STATE_START:
7643       switch (id) {
7644         case GST_EBML_ID_HEADER:
7645           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
7646           ret = gst_matroska_demux_parse_header (demux, &ebml);
7647           if (ret != GST_FLOW_OK)
7648             goto parse_failed;
7649           demux->state = GST_MATROSKA_DEMUX_STATE_SEGMENT;
7650           gst_matroska_demux_check_seekability (demux);
7651           break;
7652         default:
7653           goto invalid_header;
7654           break;
7655       }
7656       break;
7657     case GST_MATROSKA_DEMUX_STATE_SEGMENT:
7658       switch (id) {
7659         case GST_MATROSKA_ID_SEGMENT:
7660           /* eat segment prefix */
7661           GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
7662           GST_DEBUG_OBJECT (demux,
7663               "Found Segment start at offset %" G_GUINT64_FORMAT,
7664               demux->offset);
7665           /* seeks are from the beginning of the segment,
7666            * after the segment ID/length */
7667           demux->ebml_segment_start = demux->offset;
7668           demux->state = GST_MATROSKA_DEMUX_STATE_HEADER;
7669           break;
7670         default:
7671           GST_WARNING_OBJECT (demux,
7672               "Expected a Segment ID (0x%x), but received 0x%x!",
7673               GST_MATROSKA_ID_SEGMENT, id);
7674           GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
7675           break;
7676       }
7677       break;
7678     case GST_MATROSKA_DEMUX_STATE_SCANNING:
7679       if (id != GST_MATROSKA_ID_CLUSTER &&
7680           id != GST_MATROSKA_ID_CLUSTERTIMECODE)
7681         goto skip;
7682       /* fall-through */
7683     case GST_MATROSKA_DEMUX_STATE_HEADER:
7684     case GST_MATROSKA_DEMUX_STATE_DATA:
7685     case GST_MATROSKA_DEMUX_STATE_SEEK:
7686       switch (id) {
7687         case GST_MATROSKA_ID_CLUSTER:
7688           if (G_UNLIKELY (!demux->tracks_parsed)) {
7689             if (demux->streaming) {
7690               GST_DEBUG_OBJECT (demux, "Cluster before Track");
7691               goto not_streamable;
7692             } else {
7693               ret = gst_sec_matroska_demux_find_tracks (demux);
7694               if (!demux->tracks_parsed)
7695                 goto no_tracks;
7696             }
7697           }
7698           if (G_UNLIKELY (demux->state == GST_MATROSKA_DEMUX_STATE_HEADER)) {
7699             demux->state = GST_MATROSKA_DEMUX_STATE_DATA;
7700             demux->first_cluster_offset = demux->offset;
7701             GST_DEBUG_OBJECT (demux, "signaling no more pads");
7702             gst_element_no_more_pads (GST_ELEMENT (demux));
7703             /* send initial newsegment */
7704             gst_matroska_demux_send_event (demux,
7705                 gst_event_new_new_segment (FALSE, 1.0,
7706                     GST_FORMAT_TIME, 0,
7707                     (demux->segment.duration >
7708                         0) ? demux->segment.duration : -1, 0));
7709           }
7710           demux->cluster_time = GST_CLOCK_TIME_NONE;
7711           demux->cluster_offset = demux->offset;
7712           if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
7713             GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
7714                 " not found in Cluster, trying next Cluster's first block instead",
7715                 demux->seek_block);
7716             demux->seek_block = 0;
7717           }
7718           demux->seek_first = FALSE;
7719           /* record next cluster for recovery */
7720           if (read != G_MAXUINT64)
7721             demux->next_cluster_offset = demux->cluster_offset + read;
7722           /* eat cluster prefix */
7723           gst_matroska_demux_flush (demux, needed);
7724           break;
7725         case GST_MATROSKA_ID_CLUSTERTIMECODE:
7726         {
7727           guint64 num;
7728
7729           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
7730           if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
7731             goto parse_failed;
7732           GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
7733           demux->cluster_time = num;
7734           if (demux->element_index) {
7735             if (demux->element_index_writer_id == -1)
7736               gst_index_get_writer_id (demux->element_index,
7737                   GST_OBJECT (demux), &demux->element_index_writer_id);
7738             GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
7739                 G_GUINT64_FORMAT " for writer id %d",
7740                 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
7741                 demux->element_index_writer_id);
7742             gst_index_add_association (demux->element_index,
7743                 demux->element_index_writer_id, GST_ASSOCIATION_FLAG_KEY_UNIT,
7744                 GST_FORMAT_TIME, demux->cluster_time,
7745                 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
7746           }
7747           break;
7748         }
7749         case GST_MATROSKA_ID_BLOCKGROUP:
7750           if (!gst_matroska_demux_seek_block (demux))
7751             goto skip;
7752           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
7753           DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
7754           if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
7755             ret = gst_sec_matroska_demux_parse_blockgroup_or_simpleblock (demux,
7756                 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
7757           }
7758           DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
7759           break;
7760         case GST_MATROSKA_ID_SIMPLEBLOCK:
7761           if (!gst_matroska_demux_seek_block (demux))
7762             goto skip;
7763           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
7764           DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
7765           ret = gst_sec_matroska_demux_parse_blockgroup_or_simpleblock (demux,
7766               &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
7767           DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
7768           break;
7769         case GST_MATROSKA_ID_SEGMENTINFO:
7770         case GST_MATROSKA_ID_TRACKS:
7771         case GST_MATROSKA_ID_ATTACHMENTS:
7772         case GST_MATROSKA_ID_TAGS:
7773         case GST_MATROSKA_ID_CHAPTERS:
7774         case GST_MATROSKA_ID_SEEKHEAD:
7775         case GST_MATROSKA_ID_CUES:
7776         case GST_MATROSKA_ID_POSITION:
7777         case GST_MATROSKA_ID_PREVSIZE:
7778         case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
7779         case GST_MATROSKA_ID_SILENTTRACKS:
7780           GST_DEBUG_OBJECT (demux,
7781               "Skipping Cluster subelement 0x%x - ignoring", id);
7782           /* fall-through */
7783         default:
7784         skip:
7785           GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
7786           GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
7787           break;
7788       }
7789       break;
7790   }
7791
7792   if (ret == GST_FLOW_PARSE)
7793     goto parse_failed;
7794
7795 exit:
7796   gst_ebml_read_clear (&ebml);
7797   return ret;
7798
7799   /* ERRORS */
7800 read_error:
7801   {
7802     /* simply exit, maybe not enough data yet */
7803     /* no ebml to clear if read error */
7804     return ret;
7805   }
7806 parse_failed:
7807   {
7808     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
7809         ("Failed to parse Element 0x%x", id));
7810     ret = GST_FLOW_ERROR;
7811     goto exit;
7812   }
7813 not_streamable:
7814   {
7815     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
7816         ("File layout does not permit streaming"));
7817     ret = GST_FLOW_ERROR;
7818     goto exit;
7819   }
7820 no_tracks:
7821   {
7822     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
7823         ("No Tracks element found"));
7824     ret = GST_FLOW_ERROR;
7825     goto exit;
7826   }
7827 invalid_header:
7828   {
7829     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
7830     ret = GST_FLOW_ERROR;
7831     goto exit;
7832   }
7833 }
7834
7835 static GstFlowReturn
7836 gst_sec_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
7837     GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
7838     gboolean is_simpleblock)
7839 {
7840   GstMatroskaTrackContext *stream = NULL;
7841   GstFlowReturn ret = GST_FLOW_OK;
7842   gboolean readblock = FALSE;
7843   guint32 id;
7844   guint64 block_duration = 0;
7845   GstBuffer *buf = NULL;
7846   gint stream_num = -1, n, laces = 0;
7847   guint size = 0;
7848   gint *lace_size = NULL;
7849   gint64 time = 0;
7850   gint flags = 0;
7851   gint64 referenceblock = 0;
7852   gint64 offset;
7853
7854   offset = gst_ebml_read_get_offset (ebml);
7855
7856   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
7857     if (!is_simpleblock) {
7858       if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) {
7859         goto data_error;
7860       }
7861     } else {
7862       id = GST_MATROSKA_ID_SIMPLEBLOCK;
7863     }
7864
7865     switch (id) {
7866         /* one block inside the group. Note, block parsing is one
7867          * of the harder things, so this code is a bit complicated.
7868          * See http://www.matroska.org/ for documentation. */
7869       case GST_MATROSKA_ID_SIMPLEBLOCK:
7870       case GST_MATROSKA_ID_BLOCK:
7871       {
7872         guint64 num;
7873         guint8 *data;
7874
7875         if (buf) {
7876           gst_buffer_unref (buf);
7877           buf = NULL;
7878         }
7879         if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
7880           break;
7881
7882         data = GST_BUFFER_DATA (buf);
7883         size = GST_BUFFER_SIZE (buf);
7884
7885         /* first byte(s): blocknum */
7886         if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
7887           goto data_error;
7888         data += n;
7889         size -= n;
7890
7891         /* fetch stream from num */
7892         stream_num = gst_matroska_demux_stream_from_num (demux, num);
7893         if (G_UNLIKELY (size < 3)) {
7894           GST_WARNING_OBJECT (demux, "Invalid size %u", size);
7895           /* non-fatal, try next block(group) */
7896           ret = GST_FLOW_OK;
7897           goto done;
7898         } else if (G_UNLIKELY (stream_num < 0 ||
7899                 stream_num >= demux->num_streams)) {
7900           /* let's not give up on a stray invalid track number */
7901           GST_WARNING_OBJECT (demux,
7902               "Invalid stream %d for track number %" G_GUINT64_FORMAT
7903               "; ignoring block", stream_num, num);
7904           goto done;
7905         }
7906
7907         stream = g_ptr_array_index (demux->src, stream_num);
7908
7909         /* time (relative to cluster time) */
7910         time = ((gint16) GST_READ_UINT16_BE (data));
7911         data += 2;
7912         size -= 2;
7913         flags = GST_READ_UINT8 (data);
7914         data += 1;
7915         size -= 1;
7916
7917         GST_LOG_OBJECT (demux, "time %" G_GUINT64_FORMAT ", flags %d", time,
7918             flags);
7919
7920          switch ((flags & 0x06) >> 1) {
7921           case 0x0:            /* no lacing */
7922             laces = 1;
7923             break;
7924
7925           case 0x1:            /* xiph lacing */
7926           case 0x2:            /* fixed-size lacing */
7927           case 0x3:            /* EBML lacing */
7928             if (size == 0)
7929               goto invalid_lacing;
7930             laces = GST_READ_UINT8 (data) + 1;
7931             break;
7932         }
7933
7934
7935         if (ret != GST_FLOW_OK)
7936           break;
7937
7938         readblock = TRUE;
7939         break;
7940       }
7941
7942       case GST_MATROSKA_ID_BLOCKDURATION:{
7943         ret = gst_ebml_read_uint (ebml, &id, &block_duration);
7944         GST_DEBUG_OBJECT (demux, "BlockDuration: %" G_GUINT64_FORMAT,
7945             block_duration);
7946         break;
7947       }
7948
7949       case GST_MATROSKA_ID_REFERENCEBLOCK:{
7950         ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
7951         GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
7952             referenceblock);
7953         break;
7954       }
7955
7956       default:
7957         ret = gst_matroska_demux_parse_skip (demux, ebml, "BlockGroup", id);
7958         break;
7959
7960       case GST_MATROSKA_ID_BLOCKVIRTUAL:
7961       case GST_MATROSKA_ID_BLOCKADDITIONS:
7962       case GST_MATROSKA_ID_REFERENCEPRIORITY:
7963       case GST_MATROSKA_ID_REFERENCEVIRTUAL:
7964       case GST_MATROSKA_ID_SLICES:
7965         GST_DEBUG_OBJECT (demux,
7966             "Skipping BlockGroup subelement 0x%x - ignoring", id);
7967         ret = gst_ebml_read_skip (ebml);
7968         break;
7969     }
7970
7971     if (is_simpleblock)
7972       break;
7973   }
7974
7975   /* reading a number or so could have failed */
7976   if (ret != GST_FLOW_OK)
7977     goto data_error;
7978
7979   if (ret == GST_FLOW_OK && readblock) {
7980     guint64 duration = 0;
7981     gint64 lace_time = 0;
7982     gboolean delta_unit;
7983
7984     stream = g_ptr_array_index (demux->src, stream_num);
7985         
7986     if (cluster_time != GST_CLOCK_TIME_NONE) {
7987       /* FIXME: What to do with negative timestamps? Give timestamp 0 or -1?
7988        * Drop unless the lace contains timestamp 0? */
7989       if (time < 0 && (-time) > cluster_time) {
7990         lace_time = 0;
7991       } else {
7992         if (stream->timecodescale == 1.0)
7993           lace_time = (cluster_time + time) * demux->time_scale;
7994         else
7995           lace_time =
7996               gst_util_guint64_to_gdouble ((cluster_time + time) *
7997               demux->time_scale) * stream->timecodescale;
7998       }
7999     } else {
8000       lace_time = GST_CLOCK_TIME_NONE;
8001     }
8002
8003     /* else duration is diff between timecode of this and next block */
8004
8005     /* For SimpleBlock, look at the keyframe bit in flags. Otherwise,
8006        a ReferenceBlock implies that this is not a keyframe. In either
8007        case, it only makes sense for video streams. */
8008     delta_unit = stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
8009         ((is_simpleblock && !(flags & 0x80)) || referenceblock);
8010
8011     if (delta_unit && stream->set_discont) {
8012       /* When doing seeks or such, we need to restart on key frames or
8013        * decoders might choke. */
8014       GST_DEBUG_OBJECT (demux, "skipping delta unit");
8015       goto done;
8016     }
8017
8018     /* last_ts used for EOS in trickplay */
8019     stream->last_ts = lace_time;
8020
8021     if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
8022     {
8023       stream->num_frames_bw_keyframes++;
8024       if (delta_unit ==  FALSE)
8025       {
8026         stream->found_next_kframe = TRUE;
8027         demux->next_key_cluster_time = demux->cluster_time;
8028         stream->next_kframe_timestamp = lace_time;
8029         demux->segment.last_stop = lace_time - 0.5* GST_SECOND;
8030       }
8031     }
8032     else if (stream->type == GST_MATROSKA_TRACK_TYPE_AUDIO)
8033     {
8034       stream->num_frames_bw_keyframes = stream->num_frames_bw_keyframes + laces;
8035     }
8036   }
8037
8038 done:
8039   if (buf)
8040     gst_buffer_unref (buf);
8041
8042   return ret;
8043
8044 invalid_lacing:
8045   {
8046     GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
8047     /* non-fatal, try next block(group) */
8048     ret = GST_FLOW_OK;
8049     goto done;
8050   }
8051 data_error:
8052   {
8053     GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
8054     /* non-fatal, try next block(group) */
8055     ret = GST_FLOW_OK;
8056     goto done;
8057   }
8058 }
8059
8060 static gint32
8061 gst_sec_matroska_nframes2show_bw_keyframes (GstMatroskaDemux* demux, GstMatroskaTrackContext * stream)
8062 {
8063   GstFlowReturn ret = GST_FLOW_OK;
8064   guint32 id;
8065   guint64 length;
8066   guint needed;
8067   gint prev_offset = demux->offset;
8068   gint next_keyframe_offset = 0;
8069   guint64 prev_cluster_time = demux->cluster_time;
8070   guint64 prev_cluster_offset = demux->cluster_offset;
8071   gint nframes_bw_kframes = 0;
8072   int i = 0;
8073   
8074   while (stream->found_next_kframe == FALSE)
8075   {
8076     next_keyframe_offset = demux->offset;
8077         
8078     ret = gst_matroska_demux_peek_id_length_pull (demux, &id, &length, &needed);
8079     if (ret == GST_FLOW_UNEXPECTED)
8080     {
8081       stream->next_kframe_timestamp = stream->last_ts;
8082       stream->found_next_kframe = TRUE;
8083       break;
8084     }
8085     GST_LOG_OBJECT (demux, "trickplay : Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
8086       "size %" G_GUINT64_FORMAT ", needed %d", demux->offset, id,
8087       length, needed); 
8088         
8089     if (ret != GST_FLOW_OK)
8090     {
8091       GST_WARNING_OBJECT (demux, "Error in id_length_pull flow ret...reason : %s\n", gst_flow_get_name (ret));
8092       break;
8093     }
8094         
8095     ret = gst_sec_matroska_demux_parse_id (demux, id, length, needed);
8096     if (ret == GST_FLOW_UNEXPECTED)
8097     {
8098       stream->next_kframe_timestamp = stream->last_ts;
8099       stream->found_next_kframe = TRUE;
8100       break;
8101     }
8102         
8103     if (ret != GST_FLOW_OK)
8104     {
8105       GST_WARNING_OBJECT (demux, "Error in parse_id flow ret...reason : %s\n", gst_flow_get_name (ret));
8106       break;
8107     }
8108   }
8109
8110   if (stream->found_next_kframe == TRUE)
8111   {
8112     demux->next_key_frame_offset = next_keyframe_offset;
8113   }
8114
8115   for (i = 0; i < demux->src->len; i++) 
8116   {
8117     GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
8118     if (context->type <= GST_MATROSKA_TRACK_TYPE_AUDIO);
8119     {
8120       context->frames_to_show_bw_keyframes = context->num_frames_bw_keyframes / demux->segment.rate;
8121     }
8122   }
8123   
8124   /* keeping previous offset values for normal operation */
8125   demux->offset = prev_offset;
8126   demux->cluster_offset = prev_cluster_offset;
8127   demux->cluster_time = prev_cluster_time;
8128   
8129   return stream->num_frames_bw_keyframes;
8130 }
8131
8132
8133 static GstFlowReturn 
8134 gst_sec_matroska_forward_trickplay (GstMatroskaDemux* demux, GstMatroskaTrackContext * stream, GstBuffer *buffer, gboolean *skip) 
8135 {
8136   GstFlowReturn ret = GST_FLOW_OK;
8137   gint i = 0;
8138   
8139   if (stream->type == GST_MATROSKA_TRACK_TYPE_VIDEO)
8140   {
8141     if ((stream->found_next_kframe == FALSE) && (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT)))
8142     {
8143       g_assert (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT));
8144       gst_sec_matroska_nframes2show_bw_keyframes (demux, stream);
8145       stream->prev_kframe_timestamp = GST_BUFFER_TIMESTAMP (buffer);
8146       stream->avg_duration_bw_keyframes = (stream->next_kframe_timestamp - stream->prev_kframe_timestamp) / stream->num_frames_bw_keyframes;
8147       GST_INFO_OBJECT (demux, "Number of frames between key frames = %d and frames to show between key frames = %d", stream->num_frames_bw_keyframes, stream->frames_to_show_bw_keyframes);
8148       GST_DEBUG_OBJECT (demux, "average duration of frames = %d", GST_TIME_ARGS(stream->avg_duration_bw_keyframes));
8149           
8150       for (i = 0; i < demux->src->len; i++) 
8151       {
8152         GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
8153         if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO)
8154         {
8155           context->num_frames_bw_keyframes = 0;
8156         }
8157       }
8158     }
8159     else
8160     {
8161       stream->frames_to_show_bw_keyframes--;
8162       if (stream->frames_to_show_bw_keyframes == 0)
8163       {
8164         stream->found_next_kframe = FALSE;
8165         demux->cluster_time = demux->next_key_cluster_time;
8166         demux->offset = demux->next_key_frame_offset;
8167          stream->num_frames_bw_keyframes = 0;
8168         GST_DEBUG_OBJECT (demux, "next key cluster time = %"GST_TIME_FORMAT" and offset = %u...\n", GST_TIME_ARGS(demux->cluster_time), demux->offset);
8169       }
8170      /* GST_BUFFER_TIMESTAMP(buffer) = stream->prev_kframe_timestamp +
8171                 ((stream->num_frames_bw_keyframes/demux->segment.rate) - stream->frames_to_show_bw_keyframes) * abs (demux->segment.rate) * stream->avg_duration_bw_keyframes;*/
8172     }
8173   }
8174   else if (stream->type == GST_MATROSKA_TRACK_TYPE_AUDIO)
8175   {
8176     if (stream->frames_to_show_bw_keyframes == 0)
8177     {
8178       *skip = TRUE;
8179       stream->num_frames_bw_keyframes = 0;
8180       stream->frames_to_show_bw_keyframes = 0;
8181     }
8182     else
8183     {
8184       stream->frames_to_show_bw_keyframes--;
8185     }
8186
8187
8188 /*   else
8189    {
8190       if (G_LIKELY (demux->src->len)) 
8191       {
8192         guint i;
8193         g_assert (demux->num_streams == demux->src->len);
8194         for (i = 0; i < demux->src->len; i++) 
8195         {
8196           GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
8197           if ((context->type == GST_MATROSKA_TRACK_TYPE_VIDEO) && (context->frames_to_show_bw_keyframes == 0))
8198           {
8199             context->frames_to_show_bw_keyframes = 0;
8200             context->num_frames_bw_keyframes = 0;
8201             *skip = TRUE;
8202           }
8203         }
8204       }
8205     } */
8206   }
8207   return ret;
8208 }
8209
8210 #endif
8211
8212 static GstStateChangeReturn
8213 gst_matroska_demux_change_state (GstElement * element,
8214     GstStateChange transition)
8215 {
8216   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
8217   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
8218
8219   /* handle upwards state changes here */
8220   switch (transition) {
8221     default:
8222       break;
8223   }
8224
8225   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
8226
8227   /* handle downwards state changes */
8228   switch (transition) {
8229     case GST_STATE_CHANGE_PAUSED_TO_READY:
8230       gst_matroska_demux_reset (GST_ELEMENT (demux));
8231       break;
8232     default:
8233       break;
8234   }
8235
8236   return ret;
8237 }
8238
8239 gboolean
8240 gst_matroska_demux_plugin_init (GstPlugin * plugin)
8241 {
8242   gst_riff_init ();
8243
8244   /* create an elementfactory for the matroska_demux element */
8245   if (!gst_element_register (plugin, "matroskademux",
8246           GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))
8247     return FALSE;
8248
8249   return TRUE;
8250 }