qtmux: Print expected/actual values in debug log on mismatch in prefill mode
[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
4061             /* Opus GstAudioClippingMeta units are scaled by 48000/sample_rate.
4062                That is, if a Opus track has audio encoded at 24000 Hz and 132
4063                samples need to be clipped, GstAudioClippingMeta.start will be
4064                set to 264. (This is also the case for buffer offsets.)
4065                Opus sample rates are always divisors of 48000 Hz, which is the
4066                maximum allowed sample rate. */
4067             start_clip =
4068                 gst_util_uint64_scale_round (stream->codec_delay, 48000,
4069                 GST_SECOND);
4070
4071             if (GST_BUFFER_DURATION_IS_VALID (sub)) {
4072               if (GST_BUFFER_DURATION (sub) > stream->codec_delay)
4073                 GST_BUFFER_DURATION (sub) -= stream->codec_delay;
4074               else
4075                 GST_BUFFER_DURATION (sub) = 0;
4076             }
4077           }
4078         }
4079
4080         if (block_discardpadding) {
4081           end_clip =
4082               gst_util_uint64_scale_round (block_discardpadding, 48000,
4083               GST_SECOND);
4084         }
4085
4086         if (start_clip || end_clip) {
4087           gst_buffer_add_audio_clipping_meta (sub, GST_FORMAT_DEFAULT,
4088               start_clip, end_clip);
4089         }
4090       }
4091
4092       if (GST_BUFFER_PTS_IS_VALID (sub)) {
4093         stream->pos = GST_BUFFER_PTS (sub);
4094         if (GST_BUFFER_DURATION_IS_VALID (sub))
4095           stream->pos += GST_BUFFER_DURATION (sub);
4096       } else if (GST_BUFFER_DTS_IS_VALID (sub)) {
4097         stream->pos = GST_BUFFER_DTS (sub);
4098         if (GST_BUFFER_DURATION_IS_VALID (sub))
4099           stream->pos += GST_BUFFER_DURATION (sub);
4100       }
4101
4102       ret = gst_pad_push (stream->pad, sub);
4103
4104       if (demux->common.segment.rate < 0) {
4105         if (lace_time > demux->common.segment.stop && ret == GST_FLOW_EOS) {
4106           /* In reverse playback we can get a GST_FLOW_EOS when
4107            * we are at the end of the segment, so we just need to jump
4108            * back to the previous section. */
4109           GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
4110           ret = GST_FLOW_OK;
4111         }
4112       }
4113       /* combine flows */
4114       ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner,
4115           stream->pad, ret);
4116
4117     next_lace:
4118       size -= lace_size[n];
4119       if (lace_time != GST_CLOCK_TIME_NONE && duration)
4120         lace_time += duration / laces;
4121       else
4122         lace_time = GST_CLOCK_TIME_NONE;
4123     }
4124   }
4125
4126 done:
4127   if (buf) {
4128     gst_buffer_unmap (buf, &map);
4129     gst_buffer_unref (buf);
4130   }
4131   g_free (lace_size);
4132
4133   return ret;
4134
4135   /* EXITS */
4136 eos:
4137   {
4138     stream->eos = TRUE;
4139     ret = GST_FLOW_OK;
4140     /* combine flows */
4141     ret = gst_flow_combiner_update_pad_flow (demux->flowcombiner, stream->pad,
4142         ret);
4143     goto done;
4144   }
4145 invalid_lacing:
4146   {
4147     GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Invalid lacing size"));
4148     /* non-fatal, try next block(group) */
4149     ret = GST_FLOW_OK;
4150     goto done;
4151   }
4152 data_error:
4153   {
4154     GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL), ("Data error"));
4155     /* non-fatal, try next block(group) */
4156     ret = GST_FLOW_OK;
4157     goto done;
4158   }
4159 }
4160
4161 /* return FALSE if block(group) should be skipped (due to a seek) */
4162 static inline gboolean
4163 gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
4164 {
4165   if (G_UNLIKELY (demux->seek_block)) {
4166     if (!(--demux->seek_block)) {
4167       return TRUE;
4168     } else {
4169       GST_LOG_OBJECT (demux, "should skip block due to seek");
4170       return FALSE;
4171     }
4172   } else {
4173     return TRUE;
4174   }
4175 }
4176
4177 static GstFlowReturn
4178 gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
4179     GstEbmlRead * ebml)
4180 {
4181   GstFlowReturn ret;
4182   guint64 seek_pos = (guint64) - 1;
4183   guint32 seek_id = 0;
4184   guint32 id;
4185
4186   DEBUG_ELEMENT_START (demux, ebml, "Seek");
4187
4188   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4189     DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4190     return ret;
4191   }
4192
4193   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4194     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4195       break;
4196
4197     switch (id) {
4198       case GST_MATROSKA_ID_SEEKID:
4199       {
4200         guint64 t;
4201
4202         if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4203           break;
4204
4205         GST_DEBUG_OBJECT (demux, "SeekID: %" G_GUINT64_FORMAT, t);
4206         seek_id = t;
4207         break;
4208       }
4209
4210       case GST_MATROSKA_ID_SEEKPOSITION:
4211       {
4212         guint64 t;
4213
4214         if ((ret = gst_ebml_read_uint (ebml, &id, &t)) != GST_FLOW_OK)
4215           break;
4216
4217         if (t > G_MAXINT64) {
4218           GST_WARNING_OBJECT (demux,
4219               "Too large SeekPosition %" G_GUINT64_FORMAT, t);
4220           break;
4221         }
4222
4223         GST_DEBUG_OBJECT (demux, "SeekPosition: %" G_GUINT64_FORMAT, t);
4224         seek_pos = t;
4225         break;
4226       }
4227
4228       default:
4229         ret = gst_matroska_read_common_parse_skip (&demux->common, ebml,
4230             "SeekHead", id);
4231         break;
4232     }
4233   }
4234
4235   if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
4236     return ret;
4237
4238   if (!seek_id || seek_pos == (guint64) - 1) {
4239     GST_WARNING_OBJECT (demux, "Incomplete seekhead entry (0x%x/%"
4240         G_GUINT64_FORMAT ")", seek_id, seek_pos);
4241     return GST_FLOW_OK;
4242   }
4243
4244   switch (seek_id) {
4245     case GST_MATROSKA_ID_SEEKHEAD:
4246     {
4247     }
4248     case GST_MATROSKA_ID_CUES:
4249     case GST_MATROSKA_ID_TAGS:
4250     case GST_MATROSKA_ID_TRACKS:
4251     case GST_MATROSKA_ID_SEGMENTINFO:
4252     case GST_MATROSKA_ID_ATTACHMENTS:
4253     case GST_MATROSKA_ID_CHAPTERS:
4254     {
4255       guint64 before_pos, length;
4256       guint needed;
4257
4258       /* remember */
4259       length = gst_matroska_read_common_get_length (&demux->common);
4260       before_pos = demux->common.offset;
4261
4262       if (length == (guint64) - 1) {
4263         GST_DEBUG_OBJECT (demux, "no upstream length, skipping SeakHead entry");
4264         break;
4265       }
4266
4267       /* check for validity */
4268       if (seek_pos + demux->common.ebml_segment_start + 12 >= length) {
4269         GST_WARNING_OBJECT (demux,
4270             "SeekHead reference lies outside file!" " (%"
4271             G_GUINT64_FORMAT "+%" G_GUINT64_FORMAT "+12 >= %"
4272             G_GUINT64_FORMAT ")", seek_pos, demux->common.ebml_segment_start,
4273             length);
4274         break;
4275       }
4276
4277       /* only pick up index location when streaming */
4278       if (demux->streaming) {
4279         if (seek_id == GST_MATROSKA_ID_CUES) {
4280           demux->index_offset = seek_pos + demux->common.ebml_segment_start;
4281           GST_DEBUG_OBJECT (demux, "Cues located at offset %" G_GUINT64_FORMAT,
4282               demux->index_offset);
4283         }
4284         break;
4285       }
4286
4287       /* seek */
4288       demux->common.offset = seek_pos + demux->common.ebml_segment_start;
4289
4290       /* check ID */
4291       if ((ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4292                   GST_ELEMENT_CAST (demux), &id, &length, &needed)) !=
4293           GST_FLOW_OK)
4294         goto finish;
4295
4296       if (id != seek_id) {
4297         GST_WARNING_OBJECT (demux,
4298             "We looked for ID=0x%x but got ID=0x%x (pos=%" G_GUINT64_FORMAT ")",
4299             seek_id, id, seek_pos + demux->common.ebml_segment_start);
4300       } else {
4301         /* now parse */
4302         ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4303       }
4304
4305     finish:
4306       /* seek back */
4307       demux->common.offset = before_pos;
4308       break;
4309     }
4310
4311     case GST_MATROSKA_ID_CLUSTER:
4312     {
4313       guint64 pos = seek_pos + demux->common.ebml_segment_start;
4314
4315       GST_LOG_OBJECT (demux, "Cluster position");
4316       if (G_UNLIKELY (!demux->clusters))
4317         demux->clusters = g_array_sized_new (TRUE, TRUE, sizeof (guint64), 100);
4318       g_array_append_val (demux->clusters, pos);
4319       break;
4320     }
4321
4322     default:
4323       GST_DEBUG_OBJECT (demux, "Ignoring Seek entry for ID=0x%x", seek_id);
4324       break;
4325   }
4326   DEBUG_ELEMENT_STOP (demux, ebml, "Seek", ret);
4327
4328   return ret;
4329 }
4330
4331 static GstFlowReturn
4332 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux, GstEbmlRead * ebml)
4333 {
4334   GstFlowReturn ret = GST_FLOW_OK;
4335   guint32 id;
4336
4337   DEBUG_ELEMENT_START (demux, ebml, "SeekHead");
4338
4339   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
4340     DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4341     return ret;
4342   }
4343
4344   while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
4345     if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
4346       break;
4347
4348     switch (id) {
4349       case GST_MATROSKA_ID_SEEKENTRY:
4350       {
4351         ret = gst_matroska_demux_parse_contents_seekentry (demux, ebml);
4352         /* Ignore EOS and errors here */
4353         if (ret != GST_FLOW_OK) {
4354           GST_DEBUG_OBJECT (demux, "Ignoring %s", gst_flow_get_name (ret));
4355           ret = GST_FLOW_OK;
4356         }
4357         break;
4358       }
4359
4360       default:
4361         ret = gst_matroska_read_common_parse_skip (&demux->common,
4362             ebml, "SeekHead", id);
4363         break;
4364     }
4365   }
4366
4367   DEBUG_ELEMENT_STOP (demux, ebml, "SeekHead", ret);
4368
4369   /* Sort clusters by position for easier searching */
4370   if (demux->clusters)
4371     g_array_sort (demux->clusters, (GCompareFunc) gst_matroska_cluster_compare);
4372
4373   return ret;
4374 }
4375
4376 #define GST_FLOW_OVERFLOW   GST_FLOW_CUSTOM_ERROR
4377
4378 #define MAX_BLOCK_SIZE (15 * 1024 * 1024)
4379
4380 static inline GstFlowReturn
4381 gst_matroska_demux_check_read_size (GstMatroskaDemux * demux, guint64 bytes)
4382 {
4383   if (G_UNLIKELY (bytes > MAX_BLOCK_SIZE)) {
4384     /* only a few blocks are expected/allowed to be large,
4385      * and will be recursed into, whereas others will be read and must fit */
4386     if (demux->streaming) {
4387       /* fatal in streaming case, as we can't step over easily */
4388       GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4389           ("reading large block of size %" G_GUINT64_FORMAT " not supported; "
4390               "file might be corrupt.", bytes));
4391       return GST_FLOW_ERROR;
4392     } else {
4393       /* indicate higher level to quietly give up */
4394       GST_DEBUG_OBJECT (demux,
4395           "too large block of size %" G_GUINT64_FORMAT, bytes);
4396       return GST_FLOW_ERROR;
4397     }
4398   } else {
4399     return GST_FLOW_OK;
4400   }
4401 }
4402
4403 /* returns TRUE if we truely are in error state, and should give up */
4404 static inline GstFlowReturn
4405 gst_matroska_demux_check_parse_error (GstMatroskaDemux * demux)
4406 {
4407   if (!demux->streaming && demux->next_cluster_offset > 0) {
4408     /* just repositioning to where next cluster should be and try from there */
4409     GST_WARNING_OBJECT (demux, "parse error, trying next cluster expected at %"
4410         G_GUINT64_FORMAT, demux->next_cluster_offset);
4411     demux->common.offset = demux->next_cluster_offset;
4412     demux->next_cluster_offset = 0;
4413     return GST_FLOW_OK;
4414   } else {
4415     gint64 pos;
4416     GstFlowReturn ret;
4417
4418     /* sigh, one last attempt above and beyond call of duty ...;
4419      * search for cluster mark following current pos */
4420     pos = demux->common.offset;
4421     GST_WARNING_OBJECT (demux, "parse error, looking for next cluster");
4422     if ((ret = gst_matroska_demux_search_cluster (demux, &pos, TRUE)) !=
4423         GST_FLOW_OK) {
4424       /* did not work, give up */
4425       return ret;
4426     } else {
4427       GST_DEBUG_OBJECT (demux, "... found at  %" G_GUINT64_FORMAT, pos);
4428       /* try that position */
4429       demux->common.offset = pos;
4430       return GST_FLOW_OK;
4431     }
4432   }
4433 }
4434
4435 static inline GstFlowReturn
4436 gst_matroska_demux_flush (GstMatroskaDemux * demux, guint flush)
4437 {
4438   GST_LOG_OBJECT (demux, "skipping %d bytes", flush);
4439   demux->common.offset += flush;
4440   if (demux->streaming) {
4441     GstFlowReturn ret;
4442
4443     /* hard to skip large blocks when streaming */
4444     ret = gst_matroska_demux_check_read_size (demux, flush);
4445     if (ret != GST_FLOW_OK)
4446       return ret;
4447     if (flush <= gst_adapter_available (demux->common.adapter))
4448       gst_adapter_flush (demux->common.adapter, flush);
4449     else
4450       return GST_FLOW_EOS;
4451   }
4452   return GST_FLOW_OK;
4453 }
4454
4455 /* initializes @ebml with @bytes from input stream at current offset.
4456  * Returns EOS if insufficient available,
4457  * ERROR if too much was attempted to read. */
4458 static inline GstFlowReturn
4459 gst_matroska_demux_take (GstMatroskaDemux * demux, guint64 bytes,
4460     GstEbmlRead * ebml)
4461 {
4462   GstBuffer *buffer = NULL;
4463   GstFlowReturn ret = GST_FLOW_OK;
4464
4465   GST_LOG_OBJECT (demux, "taking %" G_GUINT64_FORMAT " bytes for parsing",
4466       bytes);
4467   ret = gst_matroska_demux_check_read_size (demux, bytes);
4468   if (G_UNLIKELY (ret != GST_FLOW_OK)) {
4469     if (!demux->streaming) {
4470       /* in pull mode, we can skip */
4471       if ((ret = gst_matroska_demux_flush (demux, bytes)) == GST_FLOW_OK)
4472         ret = GST_FLOW_OVERFLOW;
4473     } else {
4474       /* otherwise fatal */
4475       ret = GST_FLOW_ERROR;
4476     }
4477     goto exit;
4478   }
4479   if (demux->streaming) {
4480     if (gst_adapter_available (demux->common.adapter) >= bytes)
4481       buffer = gst_adapter_take_buffer (demux->common.adapter, bytes);
4482     else
4483       ret = GST_FLOW_EOS;
4484   } else
4485     ret = gst_matroska_read_common_peek_bytes (&demux->common,
4486         demux->common.offset, bytes, &buffer, NULL);
4487   if (G_LIKELY (buffer)) {
4488     gst_ebml_read_init (ebml, GST_ELEMENT_CAST (demux), buffer,
4489         demux->common.offset);
4490     demux->common.offset += bytes;
4491   }
4492 exit:
4493   return ret;
4494 }
4495
4496 static void
4497 gst_matroska_demux_check_seekability (GstMatroskaDemux * demux)
4498 {
4499   GstQuery *query;
4500   gboolean seekable = FALSE;
4501   gint64 start = -1, stop = -1;
4502
4503   query = gst_query_new_seeking (GST_FORMAT_BYTES);
4504   if (!gst_pad_peer_query (demux->common.sinkpad, query)) {
4505     GST_DEBUG_OBJECT (demux, "seeking query failed");
4506     goto done;
4507   }
4508
4509   gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
4510
4511   /* try harder to query upstream size if we didn't get it the first time */
4512   if (seekable && stop == -1) {
4513     GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
4514     gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
4515         &stop);
4516   }
4517
4518   /* if upstream doesn't know the size, it's likely that it's not seekable in
4519    * practice even if it technically may be seekable */
4520   if (seekable && (start != 0 || stop <= start)) {
4521     GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
4522     seekable = FALSE;
4523   }
4524
4525 done:
4526   GST_INFO_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
4527       G_GUINT64_FORMAT ")", seekable, start, stop);
4528   demux->seekable = seekable;
4529
4530   gst_query_unref (query);
4531 }
4532
4533 static GstFlowReturn
4534 gst_matroska_demux_find_tracks (GstMatroskaDemux * demux)
4535 {
4536   guint32 id;
4537   guint64 before_pos;
4538   guint64 length;
4539   guint needed;
4540   GstFlowReturn ret = GST_FLOW_OK;
4541
4542   GST_WARNING_OBJECT (demux,
4543       "Found Cluster element before Tracks, searching Tracks");
4544
4545   /* remember */
4546   before_pos = demux->common.offset;
4547
4548   /* Search Tracks element */
4549   while (TRUE) {
4550     ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4551         GST_ELEMENT_CAST (demux), &id, &length, &needed);
4552     if (ret != GST_FLOW_OK)
4553       break;
4554
4555     if (id != GST_MATROSKA_ID_TRACKS) {
4556       /* we may be skipping large cluster here, so forego size check etc */
4557       /* ... but we can't skip undefined size; force error */
4558       if (length == G_MAXUINT64) {
4559         ret = gst_matroska_demux_check_read_size (demux, length);
4560         break;
4561       } else {
4562         demux->common.offset += needed;
4563         demux->common.offset += length;
4564       }
4565       continue;
4566     }
4567
4568     /* will lead to track parsing ... */
4569     ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4570     break;
4571   }
4572
4573   /* seek back */
4574   demux->common.offset = before_pos;
4575
4576   return ret;
4577 }
4578
4579 #define GST_READ_CHECK(stmt)  \
4580 G_STMT_START { \
4581   if (G_UNLIKELY ((ret = (stmt)) != GST_FLOW_OK)) { \
4582     if (ret == GST_FLOW_OVERFLOW) { \
4583       ret = GST_FLOW_OK; \
4584     } \
4585     goto read_error; \
4586   } \
4587 } G_STMT_END
4588
4589 static GstFlowReturn
4590 gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
4591     guint64 length, guint needed)
4592 {
4593   GstEbmlRead ebml = { 0, };
4594   GstFlowReturn ret = GST_FLOW_OK;
4595   guint64 read;
4596
4597   GST_LOG_OBJECT (demux, "Parsing Element id 0x%x, "
4598       "size %" G_GUINT64_FORMAT ", prefix %d", id, length, needed);
4599
4600   /* if we plan to read and parse this element, we need prefix (id + length)
4601    * and the contents */
4602   /* mind about overflow wrap-around when dealing with undefined size */
4603   read = length;
4604   if (G_LIKELY (length != G_MAXUINT64))
4605     read += needed;
4606
4607   switch (demux->common.state) {
4608     case GST_MATROSKA_READ_STATE_START:
4609       switch (id) {
4610         case GST_EBML_ID_HEADER:
4611           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4612           ret = gst_matroska_read_common_parse_header (&demux->common, &ebml);
4613           if (ret != GST_FLOW_OK)
4614             goto parse_failed;
4615           demux->common.state = GST_MATROSKA_READ_STATE_SEGMENT;
4616           gst_matroska_demux_check_seekability (demux);
4617           break;
4618         default:
4619           goto invalid_header;
4620           break;
4621       }
4622       break;
4623     case GST_MATROSKA_READ_STATE_SEGMENT:
4624       switch (id) {
4625         case GST_MATROSKA_ID_SEGMENT:
4626           /* eat segment prefix */
4627           GST_READ_CHECK (gst_matroska_demux_flush (demux, needed));
4628           GST_DEBUG_OBJECT (demux,
4629               "Found Segment start at offset %" G_GUINT64_FORMAT " with size %"
4630               G_GUINT64_FORMAT, demux->common.offset, length);
4631           /* seeks are from the beginning of the segment,
4632            * after the segment ID/length */
4633           demux->common.ebml_segment_start = demux->common.offset;
4634           if (length == 0)
4635             length = G_MAXUINT64;
4636           demux->common.ebml_segment_length = length;
4637           demux->common.state = GST_MATROSKA_READ_STATE_HEADER;
4638           break;
4639         default:
4640           GST_WARNING_OBJECT (demux,
4641               "Expected a Segment ID (0x%x), but received 0x%x!",
4642               GST_MATROSKA_ID_SEGMENT, id);
4643           GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4644           break;
4645       }
4646       break;
4647     case GST_MATROSKA_READ_STATE_SCANNING:
4648       if (id != GST_MATROSKA_ID_CLUSTER &&
4649           id != GST_MATROSKA_ID_CLUSTERTIMECODE) {
4650         if (demux->common.start_resync_offset != -1) {
4651           /* we need to skip byte per byte if we are scanning for a new cluster
4652            * after invalid data is found
4653            */
4654           read = 1;
4655         }
4656         goto skip;
4657       } else {
4658         if (demux->common.start_resync_offset != -1) {
4659           GST_LOG_OBJECT (demux, "Resync done, new cluster found!");
4660           demux->common.start_resync_offset = -1;
4661           demux->common.state = demux->common.state_to_restore;
4662         }
4663       }
4664       /* fall-through */
4665     case GST_MATROSKA_READ_STATE_HEADER:
4666     case GST_MATROSKA_READ_STATE_DATA:
4667     case GST_MATROSKA_READ_STATE_SEEK:
4668       switch (id) {
4669         case GST_MATROSKA_ID_SEGMENTINFO:
4670           if (!demux->common.segmentinfo_parsed) {
4671             GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4672             ret = gst_matroska_read_common_parse_info (&demux->common,
4673                 GST_ELEMENT_CAST (demux), &ebml);
4674             if (ret == GST_FLOW_OK)
4675               gst_matroska_demux_send_tags (demux);
4676           } else {
4677             GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4678           }
4679           break;
4680         case GST_MATROSKA_ID_TRACKS:
4681           if (!demux->tracks_parsed) {
4682             GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4683             ret = gst_matroska_demux_parse_tracks (demux, &ebml);
4684           } else {
4685             GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4686           }
4687           break;
4688         case GST_MATROSKA_ID_CLUSTER:
4689           if (G_UNLIKELY (!demux->tracks_parsed)) {
4690             if (demux->streaming) {
4691               GST_DEBUG_OBJECT (demux, "Cluster before Track");
4692               goto not_streamable;
4693             } else {
4694               ret = gst_matroska_demux_find_tracks (demux);
4695               if (!demux->tracks_parsed)
4696                 goto no_tracks;
4697             }
4698           }
4699           if (G_UNLIKELY (demux->common.state
4700                   == GST_MATROSKA_READ_STATE_HEADER)) {
4701             demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4702             demux->first_cluster_offset = demux->common.offset;
4703             if (!demux->streaming &&
4704                 !GST_CLOCK_TIME_IS_VALID (demux->common.segment.duration)) {
4705               GstMatroskaIndex *last = NULL;
4706
4707               GST_DEBUG_OBJECT (demux,
4708                   "estimating duration using last cluster");
4709               if ((last = gst_matroska_demux_search_pos (demux,
4710                           GST_CLOCK_TIME_NONE)) != NULL) {
4711                 demux->last_cluster_offset =
4712                     last->pos + demux->common.ebml_segment_start;
4713                 demux->stream_last_time = last->time;
4714                 demux->common.segment.duration =
4715                     demux->stream_last_time - demux->stream_start_time;
4716                 /* above estimate should not be taken all too strongly */
4717                 demux->invalid_duration = TRUE;
4718                 GST_DEBUG_OBJECT (demux,
4719                     "estimated duration as %" GST_TIME_FORMAT,
4720                     GST_TIME_ARGS (demux->common.segment.duration));
4721               }
4722             }
4723             GST_DEBUG_OBJECT (demux, "signaling no more pads");
4724             gst_element_no_more_pads (GST_ELEMENT (demux));
4725             /* send initial segment - we wait till we know the first
4726                incoming timestamp, so we can properly set the start of
4727                the segment. */
4728             demux->need_segment = TRUE;
4729           }
4730           demux->cluster_time = GST_CLOCK_TIME_NONE;
4731           demux->cluster_offset = demux->common.offset;
4732           if (G_UNLIKELY (!demux->seek_first && demux->seek_block)) {
4733             GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
4734                 " not found in Cluster, trying next Cluster's first block instead",
4735                 demux->seek_block);
4736             demux->seek_block = 0;
4737           }
4738           demux->seek_first = FALSE;
4739           /* record next cluster for recovery */
4740           if (read != G_MAXUINT64)
4741             demux->next_cluster_offset = demux->cluster_offset + read;
4742           /* eat cluster prefix */
4743           gst_matroska_demux_flush (demux, needed);
4744           break;
4745         case GST_MATROSKA_ID_CLUSTERTIMECODE:
4746         {
4747           guint64 num;
4748
4749           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4750           if ((ret = gst_ebml_read_uint (&ebml, &id, &num)) != GST_FLOW_OK)
4751             goto parse_failed;
4752           GST_DEBUG_OBJECT (demux, "ClusterTimeCode: %" G_GUINT64_FORMAT, num);
4753           demux->cluster_time = num;
4754           /* track last cluster */
4755           if (demux->cluster_offset > demux->last_cluster_offset) {
4756             demux->last_cluster_offset = demux->cluster_offset;
4757             demux->stream_last_time =
4758                 demux->cluster_time * demux->common.time_scale;
4759           }
4760 #if 0
4761           if (demux->common.element_index) {
4762             if (demux->common.element_index_writer_id == -1)
4763               gst_index_get_writer_id (demux->common.element_index,
4764                   GST_OBJECT (demux), &demux->common.element_index_writer_id);
4765             GST_LOG_OBJECT (demux, "adding association %" GST_TIME_FORMAT "-> %"
4766                 G_GUINT64_FORMAT " for writer id %d",
4767                 GST_TIME_ARGS (demux->cluster_time), demux->cluster_offset,
4768                 demux->common.element_index_writer_id);
4769             gst_index_add_association (demux->common.element_index,
4770                 demux->common.element_index_writer_id,
4771                 GST_ASSOCIATION_FLAG_KEY_UNIT,
4772                 GST_FORMAT_TIME, demux->cluster_time,
4773                 GST_FORMAT_BYTES, demux->cluster_offset, NULL);
4774           }
4775 #endif
4776           break;
4777         }
4778         case GST_MATROSKA_ID_BLOCKGROUP:
4779           if (!gst_matroska_demux_seek_block (demux))
4780             goto skip;
4781           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4782           DEBUG_ELEMENT_START (demux, &ebml, "BlockGroup");
4783           if ((ret = gst_ebml_read_master (&ebml, &id)) == GST_FLOW_OK) {
4784             ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4785                 &ebml, demux->cluster_time, demux->cluster_offset, FALSE);
4786           }
4787           DEBUG_ELEMENT_STOP (demux, &ebml, "BlockGroup", ret);
4788           break;
4789         case GST_MATROSKA_ID_SIMPLEBLOCK:
4790           if (!gst_matroska_demux_seek_block (demux))
4791             goto skip;
4792           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4793           DEBUG_ELEMENT_START (demux, &ebml, "SimpleBlock");
4794           ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
4795               &ebml, demux->cluster_time, demux->cluster_offset, TRUE);
4796           DEBUG_ELEMENT_STOP (demux, &ebml, "SimpleBlock", ret);
4797           break;
4798         case GST_MATROSKA_ID_ATTACHMENTS:
4799           if (!demux->common.attachments_parsed) {
4800             GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4801             ret = gst_matroska_read_common_parse_attachments (&demux->common,
4802                 GST_ELEMENT_CAST (demux), &ebml);
4803             if (ret == GST_FLOW_OK)
4804               gst_matroska_demux_send_tags (demux);
4805           } else {
4806             GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4807           }
4808           break;
4809         case GST_MATROSKA_ID_TAGS:
4810           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4811           ret = gst_matroska_read_common_parse_metadata (&demux->common,
4812               GST_ELEMENT_CAST (demux), &ebml);
4813           if (ret == GST_FLOW_OK)
4814             gst_matroska_demux_send_tags (demux);
4815           break;
4816         case GST_MATROSKA_ID_CHAPTERS:
4817           if (!demux->common.chapters_parsed) {
4818             GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4819             ret =
4820                 gst_matroska_read_common_parse_chapters (&demux->common, &ebml);
4821
4822             if (demux->common.toc) {
4823               gst_matroska_demux_send_event (demux,
4824                   gst_event_new_toc (demux->common.toc, FALSE));
4825             }
4826           } else
4827             GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4828           break;
4829         case GST_MATROSKA_ID_SEEKHEAD:
4830           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4831           ret = gst_matroska_demux_parse_contents (demux, &ebml);
4832           break;
4833         case GST_MATROSKA_ID_CUES:
4834           if (demux->common.index_parsed) {
4835             GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4836             break;
4837           }
4838           GST_READ_CHECK (gst_matroska_demux_take (demux, read, &ebml));
4839           ret = gst_matroska_read_common_parse_index (&demux->common, &ebml);
4840           /* only push based; delayed index building */
4841           if (ret == GST_FLOW_OK
4842               && demux->common.state == GST_MATROSKA_READ_STATE_SEEK) {
4843             GstEvent *event;
4844
4845             GST_OBJECT_LOCK (demux);
4846             event = demux->seek_event;
4847             demux->seek_event = NULL;
4848             GST_OBJECT_UNLOCK (demux);
4849
4850             g_assert (event);
4851             /* unlikely to fail, since we managed to seek to this point */
4852             if (!gst_matroska_demux_handle_seek_event (demux, NULL, event)) {
4853               gst_event_unref (event);
4854               goto seek_failed;
4855             }
4856             gst_event_unref (event);
4857             /* resume data handling, main thread clear to seek again */
4858             GST_OBJECT_LOCK (demux);
4859             demux->common.state = GST_MATROSKA_READ_STATE_DATA;
4860             GST_OBJECT_UNLOCK (demux);
4861           }
4862           break;
4863         case GST_MATROSKA_ID_POSITION:
4864         case GST_MATROSKA_ID_PREVSIZE:
4865         case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
4866         case GST_MATROSKA_ID_SILENTTRACKS:
4867           GST_DEBUG_OBJECT (demux,
4868               "Skipping Cluster subelement 0x%x - ignoring", id);
4869           /* fall-through */
4870         default:
4871         skip:
4872           GST_DEBUG_OBJECT (demux, "skipping Element 0x%x", id);
4873           GST_READ_CHECK (gst_matroska_demux_flush (demux, read));
4874           break;
4875       }
4876       break;
4877   }
4878
4879   if (ret == GST_FLOW_PARSE)
4880     goto parse_failed;
4881
4882 exit:
4883   gst_ebml_read_clear (&ebml);
4884   return ret;
4885
4886   /* ERRORS */
4887 read_error:
4888   {
4889     /* simply exit, maybe not enough data yet */
4890     /* no ebml to clear if read error */
4891     return ret;
4892   }
4893 parse_failed:
4894   {
4895     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4896         ("Failed to parse Element 0x%x", id));
4897     ret = GST_FLOW_ERROR;
4898     goto exit;
4899   }
4900 not_streamable:
4901   {
4902     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4903         ("File layout does not permit streaming"));
4904     ret = GST_FLOW_ERROR;
4905     goto exit;
4906   }
4907 no_tracks:
4908   {
4909     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
4910         ("No Tracks element found"));
4911     ret = GST_FLOW_ERROR;
4912     goto exit;
4913   }
4914 invalid_header:
4915   {
4916     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Invalid header"));
4917     ret = GST_FLOW_ERROR;
4918     goto exit;
4919   }
4920 seek_failed:
4921   {
4922     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Failed to seek"));
4923     ret = GST_FLOW_ERROR;
4924     goto exit;
4925   }
4926 }
4927
4928 static void
4929 gst_matroska_demux_loop (GstPad * pad)
4930 {
4931   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
4932   GstFlowReturn ret;
4933   guint32 id;
4934   guint64 length;
4935   guint needed;
4936
4937   /* If we have to close a segment, send a new segment to do this now */
4938   if (G_LIKELY (demux->common.state == GST_MATROSKA_READ_STATE_DATA)) {
4939     if (G_UNLIKELY (demux->new_segment)) {
4940       gst_matroska_demux_send_event (demux, demux->new_segment);
4941       demux->new_segment = NULL;
4942     }
4943   }
4944
4945   ret = gst_matroska_read_common_peek_id_length_pull (&demux->common,
4946       GST_ELEMENT_CAST (demux), &id, &length, &needed);
4947   if (ret == GST_FLOW_EOS) {
4948     goto eos;
4949   } else if (ret == GST_FLOW_FLUSHING) {
4950     goto pause;
4951   } else if (ret != GST_FLOW_OK) {
4952     ret = gst_matroska_demux_check_parse_error (demux);
4953
4954     /* Only handle EOS as no error if we're outside the segment already */
4955     if (ret == GST_FLOW_EOS && (demux->common.ebml_segment_length != G_MAXUINT64
4956             && demux->common.offset >=
4957             demux->common.ebml_segment_start +
4958             demux->common.ebml_segment_length))
4959       goto eos;
4960     else if (ret != GST_FLOW_OK)
4961       goto pause;
4962     else
4963       return;
4964   }
4965
4966   GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
4967       "size %" G_GUINT64_FORMAT ", needed %d", demux->common.offset, id,
4968       length, needed);
4969
4970   ret = gst_matroska_demux_parse_id (demux, id, length, needed);
4971   if (ret == GST_FLOW_EOS)
4972     goto eos;
4973   if (ret != GST_FLOW_OK)
4974     goto pause;
4975
4976   /* check if we're at the end of a configured segment */
4977   if (G_LIKELY (demux->common.src->len)) {
4978     guint i;
4979
4980     g_assert (demux->common.num_streams == demux->common.src->len);
4981     for (i = 0; i < demux->common.src->len; i++) {
4982       GstMatroskaTrackContext *context = g_ptr_array_index (demux->common.src,
4983           i);
4984       GST_DEBUG_OBJECT (context->pad, "pos %" GST_TIME_FORMAT,
4985           GST_TIME_ARGS (context->pos));
4986       if (context->eos == FALSE)
4987         goto next;
4988     }
4989
4990     GST_INFO_OBJECT (demux, "All streams are EOS");
4991     ret = GST_FLOW_EOS;
4992     goto eos;
4993   }
4994
4995 next:
4996   if (G_UNLIKELY (demux->cached_length == G_MAXUINT64 ||
4997           demux->common.offset >= demux->cached_length)) {
4998     demux->cached_length = gst_matroska_read_common_get_length (&demux->common);
4999     if (demux->common.offset == demux->cached_length) {
5000       GST_LOG_OBJECT (demux, "Reached end of stream");
5001       ret = GST_FLOW_EOS;
5002       goto eos;
5003     }
5004   }
5005
5006   return;
5007
5008   /* ERRORS */
5009 eos:
5010   {
5011     if (demux->common.segment.rate < 0.0) {
5012       ret = gst_matroska_demux_seek_to_previous_keyframe (demux);
5013       if (ret == GST_FLOW_OK)
5014         return;
5015     }
5016     /* fall-through */
5017   }
5018 pause:
5019   {
5020     const gchar *reason = gst_flow_get_name (ret);
5021     gboolean push_eos = FALSE;
5022
5023     GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
5024     gst_pad_pause_task (demux->common.sinkpad);
5025
5026     if (ret == GST_FLOW_EOS) {
5027       /* perform EOS logic */
5028
5029       /* If we were in the headers, make sure we send no-more-pads.
5030          This will ensure decodebin does not get stuck thinking
5031          the chain is not complete yet, and waiting indefinitely. */
5032       if (G_UNLIKELY (demux->common.state == GST_MATROSKA_READ_STATE_HEADER)) {
5033         if (demux->common.src->len == 0) {
5034           GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
5035               ("No pads created"));
5036         } else {
5037           GST_ELEMENT_WARNING (demux, STREAM, DEMUX, (NULL),
5038               ("Failed to finish reading headers"));
5039         }
5040         gst_element_no_more_pads (GST_ELEMENT (demux));
5041       }
5042
5043       if (demux->common.segment.flags & GST_SEEK_FLAG_SEGMENT) {
5044         GstEvent *event;
5045         GstMessage *msg;
5046         gint64 stop;
5047
5048         /* for segment playback we need to post when (in stream time)
5049          * we stopped, this is either stop (when set) or the duration. */
5050         if ((stop = demux->common.segment.stop) == -1)
5051           stop = demux->last_stop_end;
5052
5053         GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
5054         msg = gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
5055             stop);
5056         if (demux->segment_seqnum)
5057           gst_message_set_seqnum (msg, demux->segment_seqnum);
5058         gst_element_post_message (GST_ELEMENT (demux), msg);
5059
5060         event = gst_event_new_segment_done (GST_FORMAT_TIME, stop);
5061         if (demux->segment_seqnum)
5062           gst_event_set_seqnum (event, demux->segment_seqnum);
5063         gst_matroska_demux_send_event (demux, event);
5064       } else {
5065         push_eos = TRUE;
5066       }
5067     } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
5068       /* for fatal errors we post an error message */
5069       GST_ELEMENT_FLOW_ERROR (demux, ret);
5070       push_eos = TRUE;
5071     }
5072     if (push_eos) {
5073       GstEvent *event;
5074
5075       /* send EOS, and prevent hanging if no streams yet */
5076       GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
5077       event = gst_event_new_eos ();
5078       if (demux->segment_seqnum)
5079         gst_event_set_seqnum (event, demux->segment_seqnum);
5080       if (!gst_matroska_demux_send_event (demux, event) &&
5081           (ret == GST_FLOW_EOS)) {
5082         GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5083             (NULL), ("got eos but no streams (yet)"));
5084       }
5085     }
5086     return;
5087   }
5088 }
5089
5090 /*
5091  * Create and push a flushing seek event upstream
5092  */
5093 static gboolean
5094 perform_seek_to_offset (GstMatroskaDemux * demux, gdouble rate, guint64 offset,
5095     guint32 seqnum, GstSeekFlags flags)
5096 {
5097   GstEvent *event;
5098   gboolean res = 0;
5099
5100   GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);
5101
5102   event =
5103       gst_event_new_seek (rate, GST_FORMAT_BYTES,
5104       flags | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
5105       GST_SEEK_TYPE_SET, offset, GST_SEEK_TYPE_NONE, -1);
5106   gst_event_set_seqnum (event, seqnum);
5107
5108   res = gst_pad_push_event (demux->common.sinkpad, event);
5109
5110   /* segment event will update offset */
5111   return res;
5112 }
5113
5114 static GstFlowReturn
5115 gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
5116 {
5117   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5118   guint available;
5119   GstFlowReturn ret = GST_FLOW_OK;
5120   guint needed = 0;
5121   guint32 id;
5122   guint64 length;
5123
5124   if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buffer))) {
5125     GST_DEBUG_OBJECT (demux, "got DISCONT");
5126     gst_adapter_clear (demux->common.adapter);
5127     GST_OBJECT_LOCK (demux);
5128     gst_matroska_read_common_reset_streams (&demux->common,
5129         GST_CLOCK_TIME_NONE, FALSE);
5130     GST_OBJECT_UNLOCK (demux);
5131   }
5132
5133   gst_adapter_push (demux->common.adapter, buffer);
5134   buffer = NULL;
5135
5136 next:
5137   available = gst_adapter_available (demux->common.adapter);
5138
5139   ret = gst_matroska_read_common_peek_id_length_push (&demux->common,
5140       GST_ELEMENT_CAST (demux), &id, &length, &needed);
5141   if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
5142     if (demux->common.ebml_segment_length != G_MAXUINT64
5143         && demux->common.offset >=
5144         demux->common.ebml_segment_start + demux->common.ebml_segment_length) {
5145       return GST_FLOW_OK;
5146     } else {
5147       gint64 bytes_scanned;
5148       if (demux->common.start_resync_offset == -1) {
5149         demux->common.start_resync_offset = demux->common.offset;
5150         demux->common.state_to_restore = demux->common.state;
5151       }
5152       bytes_scanned = demux->common.offset - demux->common.start_resync_offset;
5153       if (bytes_scanned <= INVALID_DATA_THRESHOLD) {
5154         GST_WARNING_OBJECT (demux,
5155             "parse error, looking for next cluster, actual offset %"
5156             G_GUINT64_FORMAT ", start resync offset %" G_GUINT64_FORMAT,
5157             demux->common.offset, demux->common.start_resync_offset);
5158         demux->common.state = GST_MATROSKA_READ_STATE_SCANNING;
5159         ret = GST_FLOW_OK;
5160       } else {
5161         GST_WARNING_OBJECT (demux,
5162             "unrecoverable parse error, next cluster not found and threshold "
5163             "exceeded, bytes scanned %" G_GINT64_FORMAT, bytes_scanned);
5164         return ret;
5165       }
5166     }
5167   }
5168
5169   GST_LOG_OBJECT (demux, "Offset %" G_GUINT64_FORMAT ", Element id 0x%x, "
5170       "size %" G_GUINT64_FORMAT ", needed %d, available %d",
5171       demux->common.offset, id, length, needed, available);
5172
5173   if (needed > available)
5174     return GST_FLOW_OK;
5175
5176   ret = gst_matroska_demux_parse_id (demux, id, length, needed);
5177   if (ret == GST_FLOW_EOS) {
5178     /* need more data */
5179     return GST_FLOW_OK;
5180   } else if (ret != GST_FLOW_OK) {
5181     return ret;
5182   } else
5183     goto next;
5184 }
5185
5186 static gboolean
5187 gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
5188     GstEvent * event)
5189 {
5190   gboolean res = TRUE;
5191   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5192
5193   GST_DEBUG_OBJECT (demux,
5194       "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
5195
5196   switch (GST_EVENT_TYPE (event)) {
5197     case GST_EVENT_SEGMENT:
5198     {
5199       const GstSegment *segment;
5200
5201       /* some debug output */
5202       gst_event_parse_segment (event, &segment);
5203       /* FIXME: do we need to update segment base here (like accum in 0.10)? */
5204       GST_DEBUG_OBJECT (demux,
5205           "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
5206           segment);
5207
5208       if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
5209         GST_DEBUG_OBJECT (demux, "still starting");
5210         goto exit;
5211       }
5212
5213       /* we only expect a BYTE segment, e.g. following a seek */
5214       if (segment->format != GST_FORMAT_BYTES) {
5215         GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
5216         goto exit;
5217       }
5218
5219       GST_DEBUG_OBJECT (demux, "clearing segment state");
5220       GST_OBJECT_LOCK (demux);
5221       /* clear current segment leftover */
5222       gst_adapter_clear (demux->common.adapter);
5223       /* and some streaming setup */
5224       demux->common.offset = segment->start;
5225       /* accumulate base based on current position */
5226       if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
5227         demux->common.segment.base +=
5228             (MAX (demux->common.segment.position, demux->stream_start_time)
5229             - demux->stream_start_time) / fabs (demux->common.segment.rate);
5230       /* do not know where we are;
5231        * need to come across a cluster and generate segment */
5232       demux->common.segment.position = GST_CLOCK_TIME_NONE;
5233       demux->cluster_time = GST_CLOCK_TIME_NONE;
5234       demux->cluster_offset = 0;
5235       demux->need_segment = TRUE;
5236       demux->segment_seqnum = gst_event_get_seqnum (event);
5237       /* but keep some of the upstream segment */
5238       demux->common.segment.rate = segment->rate;
5239       demux->common.segment.flags = segment->flags;
5240       /* also check if need to keep some of the requested seek position */
5241       if (demux->seek_offset == segment->start) {
5242         GST_DEBUG_OBJECT (demux, "position matches requested seek");
5243         demux->common.segment.position = demux->requested_seek_time;
5244       } else {
5245         GST_DEBUG_OBJECT (demux, "unexpected segment position");
5246       }
5247       demux->requested_seek_time = GST_CLOCK_TIME_NONE;
5248       demux->seek_offset = -1;
5249       GST_OBJECT_UNLOCK (demux);
5250     exit:
5251       /* chain will send initial segment after pads have been added,
5252        * or otherwise come up with one */
5253       GST_DEBUG_OBJECT (demux, "eating event");
5254       gst_event_unref (event);
5255       res = TRUE;
5256       break;
5257     }
5258     case GST_EVENT_EOS:
5259     {
5260       if (demux->common.state != GST_MATROSKA_READ_STATE_DATA
5261           && demux->common.state != GST_MATROSKA_READ_STATE_SCANNING) {
5262         gst_event_unref (event);
5263         GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5264             (NULL), ("got eos and didn't receive a complete header object"));
5265       } else if (demux->common.num_streams == 0) {
5266         GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
5267             (NULL), ("got eos but no streams (yet)"));
5268       } else {
5269         gst_matroska_demux_send_event (demux, event);
5270       }
5271       break;
5272     }
5273     case GST_EVENT_FLUSH_STOP:
5274     {
5275       guint64 dur;
5276
5277       gst_adapter_clear (demux->common.adapter);
5278       GST_OBJECT_LOCK (demux);
5279       gst_matroska_read_common_reset_streams (&demux->common,
5280           GST_CLOCK_TIME_NONE, TRUE);
5281       gst_flow_combiner_reset (demux->flowcombiner);
5282       dur = demux->common.segment.duration;
5283       gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
5284       demux->common.segment.duration = dur;
5285       demux->cluster_time = GST_CLOCK_TIME_NONE;
5286       demux->cluster_offset = 0;
5287       GST_OBJECT_UNLOCK (demux);
5288       /* fall-through */
5289     }
5290     default:
5291       res = gst_pad_event_default (pad, parent, event);
5292       break;
5293   }
5294
5295   return res;
5296 }
5297
5298 static gboolean
5299 gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
5300 {
5301   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
5302   GstQuery *query;
5303   gboolean pull_mode = FALSE;
5304
5305   query = gst_query_new_scheduling ();
5306
5307   if (gst_pad_peer_query (sinkpad, query))
5308     pull_mode = gst_query_has_scheduling_mode_with_flags (query,
5309         GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
5310
5311   gst_query_unref (query);
5312
5313   if (pull_mode) {
5314     GST_DEBUG ("going to pull mode");
5315     demux->streaming = FALSE;
5316     return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
5317   } else {
5318     GST_DEBUG ("going to push (streaming) mode");
5319     demux->streaming = TRUE;
5320     return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
5321   }
5322 }
5323
5324 static gboolean
5325 gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
5326     GstPadMode mode, gboolean active)
5327 {
5328   switch (mode) {
5329     case GST_PAD_MODE_PULL:
5330       if (active) {
5331         /* if we have a scheduler we can start the task */
5332         gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
5333             sinkpad, NULL);
5334       } else {
5335         gst_pad_stop_task (sinkpad);
5336       }
5337       return TRUE;
5338     case GST_PAD_MODE_PUSH:
5339       return TRUE;
5340     default:
5341       return FALSE;
5342   }
5343 }
5344
5345 static GstCaps *
5346 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
5347     videocontext, const gchar * codec_id, guint8 * data, guint size,
5348     gchar ** codec_name, guint32 * riff_fourcc)
5349 {
5350   GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
5351   GstCaps *caps = NULL;
5352
5353   g_assert (videocontext != NULL);
5354   g_assert (codec_name != NULL);
5355
5356   if (riff_fourcc)
5357     *riff_fourcc = 0;
5358
5359   /* TODO: check if we have all codec types from matroska-ids.h
5360    *       check if we have to do more special things with codec_private
5361    *
5362    * Add support for
5363    *  GST_MATROSKA_CODEC_ID_VIDEO_QUICKTIME
5364    *  GST_MATROSKA_CODEC_ID_VIDEO_SNOW
5365    */
5366
5367   if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
5368     gst_riff_strf_vids *vids = NULL;
5369
5370     if (data) {
5371       GstBuffer *buf = NULL;
5372
5373       vids = (gst_riff_strf_vids *) data;
5374
5375       /* assure size is big enough */
5376       if (size < 24) {
5377         GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
5378         return NULL;
5379       }
5380       if (size < sizeof (gst_riff_strf_vids)) {
5381         vids = g_new (gst_riff_strf_vids, 1);
5382         memcpy (vids, data, size);
5383       }
5384
5385       context->dts_only = TRUE; /* VFW files only store DTS */
5386
5387       /* little-endian -> byte-order */
5388       vids->size = GUINT32_FROM_LE (vids->size);
5389       vids->width = GUINT32_FROM_LE (vids->width);
5390       vids->height = GUINT32_FROM_LE (vids->height);
5391       vids->planes = GUINT16_FROM_LE (vids->planes);
5392       vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
5393       vids->compression = GUINT32_FROM_LE (vids->compression);
5394       vids->image_size = GUINT32_FROM_LE (vids->image_size);
5395       vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
5396       vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
5397       vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
5398       vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
5399
5400       if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
5401         gsize offset = sizeof (gst_riff_strf_vids);
5402
5403         buf =
5404             gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
5405                 size - offset), size - offset);
5406       }
5407
5408       if (riff_fourcc)
5409         *riff_fourcc = vids->compression;
5410
5411       caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
5412           buf, NULL, codec_name);
5413
5414       if (caps == NULL) {
5415         GST_WARNING ("Unhandled RIFF fourcc %" GST_FOURCC_FORMAT,
5416             GST_FOURCC_ARGS (vids->compression));
5417       } else {
5418         static GstStaticCaps intra_caps = GST_STATIC_CAPS ("image/jpeg; "
5419             "video/x-raw; image/png; video/x-dv; video/x-huffyuv; video/x-ffv; "
5420             "video/x-compressed-yuv");
5421         context->intra_only =
5422             gst_caps_can_intersect (gst_static_caps_get (&intra_caps), caps);
5423       }
5424
5425       if (buf)
5426         gst_buffer_unref (buf);
5427
5428       if (vids != (gst_riff_strf_vids *) data)
5429         g_free (vids);
5430     }
5431   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
5432     GstVideoInfo info;
5433     GstVideoFormat format;
5434
5435     gst_video_info_init (&info);
5436     switch (videocontext->fourcc) {
5437       case GST_MAKE_FOURCC ('I', '4', '2', '0'):
5438         format = GST_VIDEO_FORMAT_I420;
5439         break;
5440       case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
5441         format = GST_VIDEO_FORMAT_YUY2;
5442         break;
5443       case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
5444         format = GST_VIDEO_FORMAT_YV12;
5445         break;
5446       case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
5447         format = GST_VIDEO_FORMAT_UYVY;
5448         break;
5449       case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
5450         format = GST_VIDEO_FORMAT_AYUV;
5451         break;
5452       case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
5453       case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
5454         format = GST_VIDEO_FORMAT_GRAY8;
5455         break;
5456       case GST_MAKE_FOURCC ('R', 'G', 'B', 24):
5457         format = GST_VIDEO_FORMAT_RGB;
5458         break;
5459       case GST_MAKE_FOURCC ('B', 'G', 'R', 24):
5460         format = GST_VIDEO_FORMAT_BGR;
5461         break;
5462       default:
5463         GST_DEBUG ("Unknown fourcc %" GST_FOURCC_FORMAT,
5464             GST_FOURCC_ARGS (videocontext->fourcc));
5465         return NULL;
5466     }
5467
5468     context->intra_only = TRUE;
5469
5470     gst_video_info_set_format (&info, format, videocontext->pixel_width,
5471         videocontext->pixel_height);
5472     caps = gst_video_info_to_caps (&info);
5473     *codec_name = gst_pb_utils_get_codec_description (caps);
5474     context->alignment = 32;
5475   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
5476     caps = gst_caps_new_simple ("video/x-divx",
5477         "divxversion", G_TYPE_INT, 4, NULL);
5478     *codec_name = g_strdup ("MPEG-4 simple profile");
5479   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
5480       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
5481     caps = gst_caps_new_simple ("video/mpeg",
5482         "mpegversion", G_TYPE_INT, 4,
5483         "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
5484     if (data) {
5485       GstBuffer *priv;
5486
5487       priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5488       gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5489       gst_buffer_unref (priv);
5490
5491       gst_codec_utils_mpeg4video_caps_set_level_and_profile (caps, data, size);
5492     }
5493     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP))
5494       *codec_name = g_strdup ("MPEG-4 advanced simple profile");
5495     else
5496       *codec_name = g_strdup ("MPEG-4 advanced profile");
5497   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
5498 #if 0
5499     caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
5500             "divxversion", G_TYPE_INT, 3, NULL),
5501         gst_structure_new ("video/x-msmpeg",
5502             "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
5503 #endif
5504     caps = gst_caps_new_simple ("video/x-msmpeg",
5505         "msmpegversion", G_TYPE_INT, 43, NULL);
5506     *codec_name = g_strdup ("Microsoft MPEG-4 v.3");
5507   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
5508       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
5509     gint mpegversion;
5510
5511     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
5512       mpegversion = 1;
5513     else
5514       mpegversion = 2;
5515
5516     caps = gst_caps_new_simple ("video/mpeg",
5517         "systemstream", G_TYPE_BOOLEAN, FALSE,
5518         "mpegversion", G_TYPE_INT, mpegversion, NULL);
5519     *codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
5520     context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
5521   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
5522     caps = gst_caps_new_empty_simple ("image/jpeg");
5523     *codec_name = g_strdup ("Motion-JPEG");
5524     context->intra_only = TRUE;
5525   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
5526     caps = gst_caps_new_empty_simple ("video/x-h264");
5527     if (data) {
5528       GstBuffer *priv;
5529
5530       /* First byte is the version, second is the profile indication, and third
5531        * is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
5532        * level indication. */
5533       gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
5534           size - 1);
5535
5536       priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5537       gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5538       gst_buffer_unref (priv);
5539
5540       gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
5541           "alignment", G_TYPE_STRING, "au", NULL);
5542     } else {
5543       GST_WARNING ("No codec data found, assuming output is byte-stream");
5544       gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5545           NULL);
5546     }
5547     *codec_name = g_strdup ("H264");
5548   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC)) {
5549     caps = gst_caps_new_empty_simple ("video/x-h265");
5550     if (data) {
5551       GstBuffer *priv;
5552
5553       gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, data + 1,
5554           size - 1);
5555
5556       priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
5557       gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
5558       gst_buffer_unref (priv);
5559
5560       gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
5561           "alignment", G_TYPE_STRING, "au", NULL);
5562     } else {
5563       GST_WARNING ("No codec data found, assuming output is byte-stream");
5564       gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "byte-stream",
5565           NULL);
5566     }
5567     *codec_name = g_strdup ("HEVC");
5568   } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1)) ||
5569       (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2)) ||
5570       (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3)) ||
5571       (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))) {
5572     gint rmversion = -1;
5573
5574     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1))
5575       rmversion = 1;
5576     else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2))
5577       rmversion = 2;
5578     else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3))
5579       rmversion = 3;
5580     else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4))
5581       rmversion = 4;
5582
5583     caps = gst_caps_new_simple ("video/x-pn-realvideo",
5584         "rmversion", G_TYPE_INT, rmversion, NULL);
5585     GST_DEBUG ("data:%p, size:0x%x", data, size);
5586     /* We need to extract the extradata ! */
5587     if (data && (size >= 0x22)) {
5588       GstBuffer *priv;
5589       guint rformat;
5590       guint subformat;
5591
5592       subformat = GST_READ_UINT32_BE (data + 0x1a);
5593       rformat = GST_READ_UINT32_BE (data + 0x1e);
5594
5595       priv =
5596           gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
5597           size - 0x1a);
5598       gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
5599           G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
5600       gst_buffer_unref (priv);
5601
5602     }
5603     *codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
5604   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
5605     caps = gst_caps_new_empty_simple ("video/x-theora");
5606     context->stream_headers =
5607         gst_matroska_parse_xiph_stream_headers (context->codec_priv,
5608         context->codec_priv_size);
5609     /* FIXME: mark stream as broken and skip if there are no stream headers */
5610     context->send_stream_headers = TRUE;
5611   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
5612     caps = gst_caps_new_empty_simple ("video/x-dirac");
5613     *codec_name = g_strdup_printf ("Dirac");
5614   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
5615     caps = gst_caps_new_empty_simple ("video/x-vp8");
5616     *codec_name = g_strdup_printf ("On2 VP8");
5617   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
5618     caps = gst_caps_new_empty_simple ("video/x-vp9");
5619     *codec_name = g_strdup_printf ("On2 VP9");
5620   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_AV1)) {
5621     caps = gst_caps_new_empty_simple ("video/x-av1");
5622     *codec_name = g_strdup_printf ("AOM AV1");
5623   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
5624     guint32 fourcc;
5625     const gchar *variant, *variant_descr = "";
5626
5627     /* Expect a fourcc in the codec private data */
5628     if (!data || size < 4) {
5629       GST_WARNING ("No or too small PRORESS fourcc (%d bytes)", size);
5630       return NULL;
5631     }
5632
5633     fourcc = GST_STR_FOURCC (data);
5634     switch (fourcc) {
5635       case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
5636         variant_descr = " 4:2:2 LT";
5637         variant = "lt";
5638         break;
5639       case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
5640         variant = "hq";
5641         variant_descr = " 4:2:2 HQ";
5642         break;
5643       case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
5644         variant = "4444";
5645         variant_descr = " 4:4:4:4";
5646         break;
5647       case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
5648         variant = "proxy";
5649         variant_descr = " 4:2:2 Proxy";
5650         break;
5651       case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
5652       default:
5653         variant = "standard";
5654         variant_descr = " 4:2:2 SD";
5655         break;
5656     }
5657
5658     GST_LOG ("Prores video, codec fourcc %" GST_FOURCC_FORMAT,
5659         GST_FOURCC_ARGS (fourcc));
5660
5661     caps = gst_caps_new_simple ("video/x-prores",
5662         "format", G_TYPE_STRING, variant, NULL);
5663     *codec_name = g_strdup_printf ("Apple ProRes%s", variant_descr);
5664     context->postprocess_frame = gst_matroska_demux_add_prores_header;
5665   } else {
5666     GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
5667     return NULL;
5668   }
5669
5670   if (caps != NULL) {
5671     int i;
5672     GstStructure *structure;
5673
5674     for (i = 0; i < gst_caps_get_size (caps); i++) {
5675       structure = gst_caps_get_structure (caps, i);
5676
5677       /* FIXME: use the real unit here! */
5678       GST_DEBUG ("video size %dx%d, target display size %dx%d (any unit)",
5679           videocontext->pixel_width,
5680           videocontext->pixel_height,
5681           videocontext->display_width, videocontext->display_height);
5682
5683       /* pixel width and height are the w and h of the video in pixels */
5684       if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
5685         gint w = videocontext->pixel_width;
5686         gint h = videocontext->pixel_height;
5687
5688         gst_structure_set (structure,
5689             "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
5690       }
5691
5692       if (videocontext->display_width > 0 || videocontext->display_height > 0) {
5693         int n, d;
5694
5695         if (videocontext->display_width <= 0)
5696           videocontext->display_width = videocontext->pixel_width;
5697         if (videocontext->display_height <= 0)
5698           videocontext->display_height = videocontext->pixel_height;
5699
5700         /* calculate the pixel aspect ratio using the display and pixel w/h */
5701         n = videocontext->display_width * videocontext->pixel_height;
5702         d = videocontext->display_height * videocontext->pixel_width;
5703         GST_DEBUG ("setting PAR to %d/%d", n, d);
5704         gst_structure_set (structure, "pixel-aspect-ratio",
5705             GST_TYPE_FRACTION,
5706             videocontext->display_width * videocontext->pixel_height,
5707             videocontext->display_height * videocontext->pixel_width, NULL);
5708       }
5709
5710       if (videocontext->default_fps > 0.0) {
5711         gint fps_n, fps_d;
5712
5713         gst_util_double_to_fraction (videocontext->default_fps, &fps_n, &fps_d);
5714
5715         GST_DEBUG ("using default fps %d/%d", fps_n, fps_d);
5716
5717         gst_structure_set (structure, "framerate", GST_TYPE_FRACTION, fps_n,
5718             fps_d, NULL);
5719       } else if (context->default_duration > 0) {
5720         int fps_n, fps_d;
5721
5722         gst_video_guess_framerate (context->default_duration, &fps_n, &fps_d);
5723
5724         GST_INFO ("using default duration %" G_GUINT64_FORMAT
5725             " framerate %d/%d", context->default_duration, fps_n, fps_d);
5726
5727         gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5728             fps_n, fps_d, NULL);
5729       } else {
5730         gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
5731             0, 1, NULL);
5732       }
5733
5734       if (videocontext->parent.flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
5735         gst_structure_set (structure, "interlace-mode", G_TYPE_STRING,
5736             "mixed", NULL);
5737     }
5738     if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
5739       if (gst_video_multiview_guess_half_aspect (videocontext->multiview_mode,
5740               videocontext->pixel_width, videocontext->pixel_height,
5741               videocontext->display_width * videocontext->pixel_height,
5742               videocontext->display_height * videocontext->pixel_width)) {
5743         videocontext->multiview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
5744       }
5745       gst_caps_set_simple (caps,
5746           "multiview-mode", G_TYPE_STRING,
5747           gst_video_multiview_mode_to_caps_string
5748           (videocontext->multiview_mode), "multiview-flags",
5749           GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, videocontext->multiview_flags,
5750           GST_FLAG_SET_MASK_EXACT, NULL);
5751     }
5752
5753     if (videocontext->colorimetry.range != GST_VIDEO_COLOR_RANGE_UNKNOWN ||
5754         videocontext->colorimetry.matrix != GST_VIDEO_COLOR_MATRIX_UNKNOWN ||
5755         videocontext->colorimetry.transfer != GST_VIDEO_TRANSFER_UNKNOWN ||
5756         videocontext->colorimetry.primaries !=
5757         GST_VIDEO_COLOR_PRIMARIES_UNKNOWN) {
5758       gchar *colorimetry =
5759           gst_video_colorimetry_to_string (&videocontext->colorimetry);
5760       gst_caps_set_simple (caps, "colorimetry", G_TYPE_STRING, colorimetry,
5761           NULL);
5762       GST_DEBUG ("setting colorimetry to %s", colorimetry);
5763       g_free (colorimetry);
5764     }
5765
5766     caps = gst_caps_simplify (caps);
5767   }
5768
5769   return caps;
5770 }
5771
5772 /*
5773  * Some AAC specific code... *sigh*
5774  * FIXME: maybe we should use '15' and code the sample rate explicitly
5775  * if the sample rate doesn't match the predefined rates exactly? (tpm)
5776  */
5777
5778 static gint
5779 aac_rate_idx (gint rate)
5780 {
5781   if (92017 <= rate)
5782     return 0;
5783   else if (75132 <= rate)
5784     return 1;
5785   else if (55426 <= rate)
5786     return 2;
5787   else if (46009 <= rate)
5788     return 3;
5789   else if (37566 <= rate)
5790     return 4;
5791   else if (27713 <= rate)
5792     return 5;
5793   else if (23004 <= rate)
5794     return 6;
5795   else if (18783 <= rate)
5796     return 7;
5797   else if (13856 <= rate)
5798     return 8;
5799   else if (11502 <= rate)
5800     return 9;
5801   else if (9391 <= rate)
5802     return 10;
5803   else
5804     return 11;
5805 }
5806
5807 static gint
5808 aac_profile_idx (const gchar * codec_id)
5809 {
5810   gint profile;
5811
5812   if (strlen (codec_id) <= 12)
5813     profile = 3;
5814   else if (!strncmp (&codec_id[12], "MAIN", 4))
5815     profile = 0;
5816   else if (!strncmp (&codec_id[12], "LC", 2))
5817     profile = 1;
5818   else if (!strncmp (&codec_id[12], "SSR", 3))
5819     profile = 2;
5820   else
5821     profile = 3;
5822
5823   return profile;
5824 }
5825
5826 static guint
5827 round_up_pow2 (guint n)
5828 {
5829   n = n - 1;
5830   n = n | (n >> 1);
5831   n = n | (n >> 2);
5832   n = n | (n >> 4);
5833   n = n | (n >> 8);
5834   n = n | (n >> 16);
5835   return n + 1;
5836 }
5837
5838 #define AAC_SYNC_EXTENSION_TYPE 0x02b7
5839
5840 static GstCaps *
5841 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
5842     audiocontext, const gchar * codec_id, guint8 * data, guint size,
5843     gchar ** codec_name, guint16 * riff_audio_fmt)
5844 {
5845   GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
5846   GstCaps *caps = NULL;
5847
5848   g_assert (audiocontext != NULL);
5849   g_assert (codec_name != NULL);
5850
5851   if (riff_audio_fmt)
5852     *riff_audio_fmt = 0;
5853
5854   /* TODO: check if we have all codec types from matroska-ids.h
5855    *       check if we have to do more special things with codec_private
5856    *       check if we need bitdepth in different places too
5857    *       implement channel position magic
5858    * Add support for:
5859    *  GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID9
5860    *  GST_MATROSKA_CODEC_ID_AUDIO_AC3_BSID10
5861    *  GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDMC
5862    *  GST_MATROSKA_CODEC_ID_AUDIO_QUICKTIME_QDM2
5863    */
5864
5865   if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
5866       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
5867       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
5868     gint layer;
5869
5870     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
5871       layer = 1;
5872     else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
5873       layer = 2;
5874     else
5875       layer = 3;
5876
5877     caps = gst_caps_new_simple ("audio/mpeg",
5878         "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
5879     *codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
5880   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
5881       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
5882     gboolean sign;
5883     gint endianness;
5884     GstAudioFormat format;
5885
5886     sign = (audiocontext->bitdepth != 8);
5887     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
5888       endianness = G_BIG_ENDIAN;
5889     else
5890       endianness = G_LITTLE_ENDIAN;
5891
5892     format = gst_audio_format_build_integer (sign, endianness,
5893         audiocontext->bitdepth, audiocontext->bitdepth);
5894
5895     /* FIXME: Channel mask and reordering */
5896     caps = gst_caps_new_simple ("audio/x-raw",
5897         "format", G_TYPE_STRING, gst_audio_format_to_string (format),
5898         "layout", G_TYPE_STRING, "interleaved",
5899         "channel-mask", GST_TYPE_BITMASK,
5900         gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5901
5902     *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
5903         audiocontext->bitdepth);
5904     context->alignment = GST_ROUND_UP_8 (audiocontext->bitdepth) / 8;
5905     context->alignment = round_up_pow2 (context->alignment);
5906   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
5907     const gchar *format;
5908     if (audiocontext->bitdepth == 32)
5909       format = "F32LE";
5910     else
5911       format = "F64LE";
5912     /* FIXME: Channel mask and reordering */
5913     caps = gst_caps_new_simple ("audio/x-raw",
5914         "format", G_TYPE_STRING, format,
5915         "layout", G_TYPE_STRING, "interleaved",
5916         "channel-mask", GST_TYPE_BITMASK,
5917         gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
5918     *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
5919         audiocontext->bitdepth);
5920     context->alignment = audiocontext->bitdepth / 8;
5921     context->alignment = round_up_pow2 (context->alignment);
5922   } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
5923           strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) {
5924     caps = gst_caps_new_simple ("audio/x-ac3",
5925         "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5926     *codec_name = g_strdup ("AC-3 audio");
5927   } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_EAC3,
5928           strlen (GST_MATROSKA_CODEC_ID_AUDIO_EAC3))) {
5929     caps = gst_caps_new_simple ("audio/x-eac3",
5930         "framed", G_TYPE_BOOLEAN, TRUE, NULL);
5931     *codec_name = g_strdup ("E-AC-3 audio");
5932   } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD,
5933           strlen (GST_MATROSKA_CODEC_ID_AUDIO_TRUEHD))) {
5934     caps = gst_caps_new_empty_simple ("audio/x-true-hd");
5935     *codec_name = g_strdup ("Dolby TrueHD");
5936   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
5937     caps = gst_caps_new_empty_simple ("audio/x-dts");
5938     *codec_name = g_strdup ("DTS audio");
5939   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
5940     caps = gst_caps_new_empty_simple ("audio/x-vorbis");
5941     context->stream_headers =
5942         gst_matroska_parse_xiph_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_FLAC)) {
5947     caps = gst_caps_new_empty_simple ("audio/x-flac");
5948     context->stream_headers =
5949         gst_matroska_parse_flac_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_SPEEX)) {
5954     caps = gst_caps_new_empty_simple ("audio/x-speex");
5955     context->stream_headers =
5956         gst_matroska_parse_speex_stream_headers (context->codec_priv,
5957         context->codec_priv_size);
5958     /* FIXME: mark stream as broken and skip if there are no stream headers */
5959     context->send_stream_headers = TRUE;
5960   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
5961     GstBuffer *tmp;
5962
5963     if (context->codec_priv_size >= 19) {
5964       if (audiocontext->samplerate)
5965         GST_WRITE_UINT32_LE ((guint8 *) context->codec_priv + 12,
5966             audiocontext->samplerate);
5967       if (context->codec_delay) {
5968         guint64 delay =
5969             gst_util_uint64_scale_round (context->codec_delay, 48000,
5970             GST_SECOND);
5971         GST_WRITE_UINT16_LE ((guint8 *) context->codec_priv + 10, delay);
5972       }
5973
5974       tmp =
5975           gst_buffer_new_wrapped (g_memdup (context->codec_priv,
5976               context->codec_priv_size), context->codec_priv_size);
5977       caps = gst_codec_utils_opus_create_caps_from_header (tmp, NULL);
5978       gst_buffer_unref (tmp);
5979       *codec_name = g_strdup ("Opus");
5980     } else if (context->codec_priv_size == 0) {
5981       GST_WARNING ("No Opus codec data found, trying to create one");
5982       if (audiocontext->channels <= 2) {
5983         guint8 streams, coupled, channels;
5984         guint32 samplerate;
5985
5986         samplerate =
5987             audiocontext->samplerate == 0 ? 48000 : audiocontext->samplerate;
5988         channels = audiocontext->channels == 0 ? 2 : audiocontext->channels;
5989         if (channels == 1) {
5990           streams = 1;
5991           coupled = 0;
5992         } else {
5993           streams = 1;
5994           coupled = 1;
5995         }
5996
5997         caps =
5998             gst_codec_utils_opus_create_caps (samplerate, channels, 0, streams,
5999             coupled, NULL);
6000         if (caps) {
6001           *codec_name = g_strdup ("Opus");
6002         } else {
6003           GST_WARNING ("Failed to create Opus caps from audio context");
6004         }
6005       } else {
6006         GST_WARNING ("No Opus codec data, and not enough info to create one");
6007       }
6008     } else {
6009       GST_WARNING ("Invalid Opus codec data size (got %" G_GSIZE_FORMAT
6010           ", expected 19)", context->codec_priv_size);
6011     }
6012   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
6013     gst_riff_strf_auds auds;
6014
6015     if (data && size >= 18) {
6016       GstBuffer *codec_data = NULL;
6017
6018       /* little-endian -> byte-order */
6019       auds.format = GST_READ_UINT16_LE (data);
6020       auds.channels = GST_READ_UINT16_LE (data + 2);
6021       auds.rate = GST_READ_UINT32_LE (data + 4);
6022       auds.av_bps = GST_READ_UINT32_LE (data + 8);
6023       auds.blockalign = GST_READ_UINT16_LE (data + 12);
6024       auds.bits_per_sample = GST_READ_UINT16_LE (data + 16);
6025
6026       /* 18 is the waveformatex size */
6027       if (size > 18) {
6028         codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
6029             data + 18, size - 18, 0, size - 18, NULL, NULL);
6030       }
6031
6032       if (riff_audio_fmt)
6033         *riff_audio_fmt = auds.format;
6034
6035       /* FIXME: Handle reorder map */
6036       caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
6037           codec_data, codec_name, NULL);
6038       if (codec_data)
6039         gst_buffer_unref (codec_data);
6040
6041       if (caps == NULL) {
6042         GST_WARNING ("Unhandled RIFF audio format 0x%02x", auds.format);
6043       }
6044     } else {
6045       GST_WARNING ("Invalid codec data size (%d expected, got %d)", 18, size);
6046     }
6047   } else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
6048     GstBuffer *priv = NULL;
6049     gint mpegversion;
6050     gint rate_idx, profile;
6051     guint8 *data = NULL;
6052
6053     /* unspecified AAC profile with opaque private codec data */
6054     if (strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC) == 0) {
6055       if (context->codec_priv_size >= 2) {
6056         guint obj_type, freq_index, explicit_freq_bytes = 0;
6057
6058         codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6059         mpegversion = 4;
6060         freq_index = (GST_READ_UINT16_BE (context->codec_priv) & 0x780) >> 7;
6061         obj_type = (GST_READ_UINT16_BE (context->codec_priv) & 0xF800) >> 11;
6062         if (freq_index == 15)
6063           explicit_freq_bytes = 3;
6064         GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
6065         priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
6066                 context->codec_priv_size), context->codec_priv_size);
6067         /* assume SBR if samplerate <= 24kHz */
6068         if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
6069             (context->codec_priv_size == (5 + explicit_freq_bytes))) {
6070           audiocontext->samplerate *= 2;
6071         }
6072       } else {
6073         GST_WARNING ("Opaque A_AAC codec ID, but no codec private data");
6074         /* this is pretty broken;
6075          * maybe we need to make up some default private,
6076          * or maybe ADTS data got dumped in.
6077          * Let's set up some private data now, and check actual data later */
6078         /* just try this and see what happens ... */
6079         codec_id = GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4;
6080         context->postprocess_frame = gst_matroska_demux_check_aac;
6081       }
6082     }
6083
6084     /* make up decoder-specific data if it is not supplied */
6085     if (priv == NULL) {
6086       GstMapInfo map;
6087
6088       priv = gst_buffer_new_allocate (NULL, 5, NULL);
6089       gst_buffer_map (priv, &map, GST_MAP_WRITE);
6090       data = map.data;
6091       rate_idx = aac_rate_idx (audiocontext->samplerate);
6092       profile = aac_profile_idx (codec_id);
6093
6094       data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
6095       data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
6096
6097       if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
6098               strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
6099         mpegversion = 2;
6100         gst_buffer_unmap (priv, &map);
6101         gst_buffer_set_size (priv, 2);
6102       } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
6103               strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
6104         mpegversion = 4;
6105
6106         if (g_strrstr (codec_id, "SBR")) {
6107           /* HE-AAC (aka SBR AAC) */
6108           audiocontext->samplerate *= 2;
6109           rate_idx = aac_rate_idx (audiocontext->samplerate);
6110           data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
6111           data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
6112           data[4] = (1 << 7) | (rate_idx << 3);
6113           gst_buffer_unmap (priv, &map);
6114         } else {
6115           gst_buffer_unmap (priv, &map);
6116           gst_buffer_set_size (priv, 2);
6117         }
6118       } else {
6119         gst_buffer_unmap (priv, &map);
6120         gst_buffer_unref (priv);
6121         priv = NULL;
6122         GST_ERROR ("Unknown AAC profile and no codec private data");
6123       }
6124     }
6125
6126     if (priv) {
6127       caps = gst_caps_new_simple ("audio/mpeg",
6128           "mpegversion", G_TYPE_INT, mpegversion,
6129           "framed", G_TYPE_BOOLEAN, TRUE,
6130           "stream-format", G_TYPE_STRING, "raw", NULL);
6131       gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6132       if (context->codec_priv && context->codec_priv_size > 0)
6133         gst_codec_utils_aac_caps_set_level_and_profile (caps,
6134             context->codec_priv, context->codec_priv_size);
6135       *codec_name = g_strdup_printf ("MPEG-%d AAC audio", mpegversion);
6136       gst_buffer_unref (priv);
6137     }
6138   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_TTA)) {
6139     caps = gst_caps_new_simple ("audio/x-tta",
6140         "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
6141     *codec_name = g_strdup ("TTA audio");
6142   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_WAVPACK4)) {
6143     caps = gst_caps_new_simple ("audio/x-wavpack",
6144         "width", G_TYPE_INT, audiocontext->bitdepth,
6145         "framed", G_TYPE_BOOLEAN, TRUE, NULL);
6146     *codec_name = g_strdup ("Wavpack audio");
6147     context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
6148     audiocontext->wvpk_block_index = 0;
6149   } else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
6150       (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8)) ||
6151       (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
6152     gint raversion = -1;
6153
6154     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4))
6155       raversion = 1;
6156     else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))
6157       raversion = 8;
6158     else
6159       raversion = 2;
6160
6161     caps = gst_caps_new_simple ("audio/x-pn-realaudio",
6162         "raversion", G_TYPE_INT, raversion, NULL);
6163     /* Extract extra information from caps, mapping varies based on codec */
6164     if (data && (size >= 0x50)) {
6165       GstBuffer *priv;
6166       guint flavor;
6167       guint packet_size;
6168       guint height;
6169       guint leaf_size;
6170       guint sample_width;
6171       guint extra_data_size;
6172
6173       GST_DEBUG ("real audio raversion:%d", raversion);
6174       if (raversion == 8) {
6175         /* COOK */
6176         flavor = GST_READ_UINT16_BE (data + 22);
6177         packet_size = GST_READ_UINT32_BE (data + 24);
6178         height = GST_READ_UINT16_BE (data + 40);
6179         leaf_size = GST_READ_UINT16_BE (data + 44);
6180         sample_width = GST_READ_UINT16_BE (data + 58);
6181         extra_data_size = GST_READ_UINT32_BE (data + 74);
6182
6183         GST_DEBUG
6184             ("flavor:%d, packet_size:%d, height:%d, leaf_size:%d, sample_width:%d, extra_data_size:%d",
6185             flavor, packet_size, height, leaf_size, sample_width,
6186             extra_data_size);
6187         gst_caps_set_simple (caps, "flavor", G_TYPE_INT, flavor, "packet_size",
6188             G_TYPE_INT, packet_size, "height", G_TYPE_INT, height, "leaf_size",
6189             G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
6190
6191         if ((size - 78) >= extra_data_size) {
6192           priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
6193               extra_data_size);
6194           gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
6195           gst_buffer_unref (priv);
6196         }
6197       }
6198     }
6199
6200     *codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
6201   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
6202     caps = gst_caps_new_empty_simple ("audio/x-sipro");
6203     *codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
6204   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
6205     caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
6206     *codec_name = g_strdup ("Real Audio Lossless");
6207   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
6208     caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
6209     *codec_name = g_strdup ("Sony ATRAC3");
6210   } else {
6211     GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
6212     return NULL;
6213   }
6214
6215   if (caps != NULL) {
6216     if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
6217       gint i;
6218
6219       for (i = 0; i < gst_caps_get_size (caps); i++) {
6220         gst_structure_set (gst_caps_get_structure (caps, i),
6221             "channels", G_TYPE_INT, audiocontext->channels,
6222             "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
6223       }
6224     }
6225
6226     caps = gst_caps_simplify (caps);
6227   }
6228
6229   return caps;
6230 }
6231
6232 static GstCaps *
6233 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
6234     subtitlecontext, const gchar * codec_id, gpointer data, guint size)
6235 {
6236   GstCaps *caps = NULL;
6237   GstMatroskaTrackContext *context =
6238       (GstMatroskaTrackContext *) subtitlecontext;
6239
6240   /* for backwards compatibility */
6241   if (!g_ascii_strcasecmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASCII))
6242     codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8;
6243   else if (!g_ascii_strcasecmp (codec_id, "S_SSA"))
6244     codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_SSA;
6245   else if (!g_ascii_strcasecmp (codec_id, "S_ASS"))
6246     codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_ASS;
6247   else if (!g_ascii_strcasecmp (codec_id, "S_USF"))
6248     codec_id = GST_MATROSKA_CODEC_ID_SUBTITLE_USF;
6249
6250   /* TODO: Add GST_MATROSKA_CODEC_ID_SUBTITLE_BMP support
6251    * Check if we have to do something with codec_private */
6252   if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
6253     /* well, plain text simply does not have a lot of markup ... */
6254     caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
6255         "pango-markup", NULL);
6256     context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6257     subtitlecontext->check_markup = TRUE;
6258   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
6259     caps = gst_caps_new_empty_simple ("application/x-ssa");
6260     context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6261     subtitlecontext->check_markup = FALSE;
6262   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
6263     caps = gst_caps_new_empty_simple ("application/x-ass");
6264     context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6265     subtitlecontext->check_markup = FALSE;
6266   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
6267     caps = gst_caps_new_empty_simple ("application/x-usf");
6268     context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
6269     subtitlecontext->check_markup = FALSE;
6270   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
6271     caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
6272     ((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
6273   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
6274     caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
6275   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
6276     caps = gst_caps_new_empty_simple ("subtitle/x-kate");
6277     context->stream_headers =
6278         gst_matroska_parse_xiph_stream_headers (context->codec_priv,
6279         context->codec_priv_size);
6280     /* FIXME: mark stream as broken and skip if there are no stream headers */
6281     context->send_stream_headers = TRUE;
6282   } else {
6283     GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
6284     caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
6285   }
6286
6287   if (data != NULL && size > 0) {
6288     GstBuffer *buf;
6289
6290     buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
6291     gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
6292     gst_buffer_unref (buf);
6293   }
6294
6295   return caps;
6296 }
6297
6298 #if 0
6299 static void
6300 gst_matroska_demux_set_index (GstElement * element, GstIndex * index)
6301 {
6302   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6303
6304   GST_OBJECT_LOCK (demux);
6305   if (demux->common.element_index)
6306     gst_object_unref (demux->common.element_index);
6307   demux->common.element_index = index ? gst_object_ref (index) : NULL;
6308   GST_OBJECT_UNLOCK (demux);
6309   GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT,
6310       demux->common.element_index);
6311 }
6312
6313 static GstIndex *
6314 gst_matroska_demux_get_index (GstElement * element)
6315 {
6316   GstIndex *result = NULL;
6317   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6318
6319   GST_OBJECT_LOCK (demux);
6320   if (demux->common.element_index)
6321     result = gst_object_ref (demux->common.element_index);
6322   GST_OBJECT_UNLOCK (demux);
6323
6324   GST_DEBUG_OBJECT (demux, "Returning index %" GST_PTR_FORMAT, result);
6325
6326   return result;
6327 }
6328 #endif
6329
6330 static GstStateChangeReturn
6331 gst_matroska_demux_change_state (GstElement * element,
6332     GstStateChange transition)
6333 {
6334   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
6335   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
6336
6337   /* handle upwards state changes here */
6338   switch (transition) {
6339     default:
6340       break;
6341   }
6342
6343   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
6344
6345   /* handle downwards state changes */
6346   switch (transition) {
6347     case GST_STATE_CHANGE_PAUSED_TO_READY:
6348       gst_matroska_demux_reset (GST_ELEMENT (demux));
6349       break;
6350     default:
6351       break;
6352   }
6353
6354   return ret;
6355 }
6356
6357 static void
6358 gst_matroska_demux_set_property (GObject * object,
6359     guint prop_id, const GValue * value, GParamSpec * pspec)
6360 {
6361   GstMatroskaDemux *demux;
6362
6363   g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6364   demux = GST_MATROSKA_DEMUX (object);
6365
6366   switch (prop_id) {
6367     case PROP_MAX_GAP_TIME:
6368       GST_OBJECT_LOCK (demux);
6369       demux->max_gap_time = g_value_get_uint64 (value);
6370       GST_OBJECT_UNLOCK (demux);
6371       break;
6372     default:
6373       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6374       break;
6375   }
6376 }
6377
6378 static void
6379 gst_matroska_demux_get_property (GObject * object,
6380     guint prop_id, GValue * value, GParamSpec * pspec)
6381 {
6382   GstMatroskaDemux *demux;
6383
6384   g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
6385   demux = GST_MATROSKA_DEMUX (object);
6386
6387   switch (prop_id) {
6388     case PROP_MAX_GAP_TIME:
6389       GST_OBJECT_LOCK (demux);
6390       g_value_set_uint64 (value, demux->max_gap_time);
6391       GST_OBJECT_UNLOCK (demux);
6392       break;
6393     default:
6394       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6395       break;
6396   }
6397 }
6398
6399 gboolean
6400 gst_matroska_demux_plugin_init (GstPlugin * plugin)
6401 {
6402   gst_riff_init ();
6403
6404   /* parser helper separate debug */
6405   GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
6406       0, "EBML stream helper class");
6407
6408   /* create an elementfactory for the matroska_demux element */
6409   if (!gst_element_register (plugin, "matroskademux",
6410           GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))
6411     return FALSE;
6412
6413   return TRUE;
6414 }