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