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