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