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