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