first batch : remove ',' at end of enums as they could confuse older gcc, foreign...
[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  *
4  * matroska-demux.c: matroska file/stream demuxer
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <math.h>
27 #include <string.h>
28
29 /* For AVI compatibility mode... Who did that? */
30 #include <gst/riff/riff-ids.h>
31 #include <gst/riff/riff-media.h>
32
33 #include "matroska-demux.h"
34 #include "matroska-ids.h"
35
36 enum
37 {
38   /* FILL ME */
39   LAST_SIGNAL
40 };
41
42 enum
43 {
44   ARG_0,
45   ARG_METADATA,
46   ARG_STREAMINFO
47       /* FILL ME */
48 };
49
50 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
51     GST_PAD_SINK,
52     GST_PAD_ALWAYS,
53     GST_STATIC_CAPS ("video/x-matroska")
54     );
55
56 /* gobject magic foo */
57 static void gst_matroska_demux_base_init (GstMatroskaDemuxClass * klass);
58 static void gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass);
59 static void gst_matroska_demux_init (GstMatroskaDemux * demux);
60
61 /* element functions */
62 static void gst_matroska_demux_loop (GstElement * element);
63 static gboolean gst_matroska_demux_send_event (GstElement * element,
64     GstEvent * event);
65
66 /* pad functions */
67 static const GstEventMask *gst_matroska_demux_get_event_mask (GstPad * pad);
68 static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
69     GstEvent * event);
70 static const GstFormat *gst_matroska_demux_get_src_formats (GstPad * pad);
71 static const GstQueryType *gst_matroska_demux_get_src_query_types (GstPad *
72     pad);
73 static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
74     GstQueryType type, GstFormat * format, gint64 * value);
75
76 /* gst internal change state handler */
77 static GstElementStateReturn
78 gst_matroska_demux_change_state (GstElement * element);
79 static void gst_matroska_demux_set_clock (GstElement * element,
80     GstClock * clock);
81
82 /* caps functions */
83 static GstCaps *gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext
84     * videocontext,
85     const gchar * codec_id,
86     gpointer data, guint size, GstMatroskaDemux * demux);
87 static GstCaps *gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext
88     * audiocontext,
89     const gchar * codec_id,
90     gpointer data, guint size, GstMatroskaDemux * demux);
91 static GstCaps *gst_matroska_demux_complex_caps (GstMatroskaTrackComplexContext
92     * complexcontext, const gchar * codec_id, gpointer data, guint size);
93 static GstCaps
94     * gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
95     subtitlecontext, const gchar * codec_id, gpointer data, guint size);
96
97 /* stream methods */
98 static void gst_matroska_demux_reset (GstElement * element);
99
100 static GstEbmlReadClass *parent_class = NULL;
101 static GstPadTemplate *videosrctempl, *audiosrctempl, *subtitlesrctempl;
102
103 /*static guint gst_matroska_demux_signals[LAST_SIGNAL] = { 0 };*/
104
105 GType
106 gst_matroska_demux_get_type (void)
107 {
108   static GType gst_matroska_demux_type = 0;
109
110   if (!gst_matroska_demux_type) {
111     static const GTypeInfo gst_matroska_demux_info = {
112       sizeof (GstMatroskaDemuxClass),
113       (GBaseInitFunc) gst_matroska_demux_base_init,
114       NULL,
115       (GClassInitFunc) gst_matroska_demux_class_init,
116       NULL,
117       NULL,
118       sizeof (GstMatroskaDemux),
119       0,
120       (GInstanceInitFunc) gst_matroska_demux_init,
121     };
122
123     gst_matroska_demux_type =
124         g_type_register_static (GST_TYPE_EBML_READ,
125         "GstMatroskaDemux", &gst_matroska_demux_info, 0);
126   }
127
128   return gst_matroska_demux_type;
129 }
130
131 static void
132 gst_matroska_demux_base_init (GstMatroskaDemuxClass * klass)
133 {
134   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
135   static GstElementDetails gst_matroska_demux_details = {
136     "Matroska demuxer",
137     "Codec/Demuxer",
138     "Demuxes a Matroska Stream into video/audio/subtitles",
139     "Ronald Bultje <rbultje@ronald.bitfreak.net>"
140   };
141
142   gst_element_class_add_pad_template (element_class, videosrctempl);
143   gst_element_class_add_pad_template (element_class, audiosrctempl);
144   gst_element_class_add_pad_template (element_class, subtitlesrctempl);
145   gst_element_class_add_pad_template (element_class,
146       gst_static_pad_template_get (&sink_templ));
147   gst_element_class_set_details (element_class, &gst_matroska_demux_details);
148 }
149
150 static void
151 gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
152 {
153   GstElementClass *gstelement_class;
154
155   gstelement_class = (GstElementClass *) klass;
156
157   parent_class = g_type_class_ref (GST_TYPE_EBML_READ);
158
159   gstelement_class->change_state = gst_matroska_demux_change_state;
160   gstelement_class->send_event = gst_matroska_demux_send_event;
161   gstelement_class->set_clock = gst_matroska_demux_set_clock;
162 }
163
164 static void
165 gst_matroska_demux_init (GstMatroskaDemux * demux)
166 {
167   GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
168   gint i;
169
170   GST_FLAG_SET (GST_OBJECT (demux), GST_ELEMENT_EVENT_AWARE);
171
172   demux->sinkpad =
173       gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
174           "sink"), "sink");
175   gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);
176   GST_EBML_READ (demux)->sinkpad = demux->sinkpad;
177
178   gst_element_set_loop_function (GST_ELEMENT (demux), gst_matroska_demux_loop);
179
180   /* initial stream no. */
181   for (i = 0; i < GST_MATROSKA_DEMUX_MAX_STREAMS; i++) {
182     demux->src[i] = NULL;
183   }
184   demux->writing_app = demux->muxing_app = NULL;
185   demux->index = NULL;
186
187   /* finish off */
188   gst_matroska_demux_reset (GST_ELEMENT (demux));
189 }
190
191 static void
192 gst_matroska_demux_reset (GstElement * element)
193 {
194   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
195   guint i;
196
197   /* reset input */
198   demux->state = GST_MATROSKA_DEMUX_STATE_START;
199
200   /* clean up existing streams */
201   for (i = 0; i < GST_MATROSKA_DEMUX_MAX_STREAMS; i++) {
202     if (demux->src[i] != NULL) {
203       if (demux->src[i]->pad != NULL) {
204         gst_element_remove_pad (GST_ELEMENT (demux), demux->src[i]->pad);
205       }
206       g_free (demux->src[i]->codec_id);
207       g_free (demux->src[i]->codec_name);
208       g_free (demux->src[i]->name);
209       g_free (demux->src[i]->language);
210       g_free (demux->src[i]->codec_priv);
211       g_free (demux->src[i]);
212       demux->src[i] = NULL;
213     }
214   }
215   demux->num_streams = 0;
216   demux->num_a_streams = 0;
217   demux->num_t_streams = 0;
218   demux->num_v_streams = 0;
219
220   /* reset media info */
221   g_free (demux->writing_app);
222   demux->writing_app = NULL;
223   g_free (demux->muxing_app);
224   demux->muxing_app = NULL;
225
226   /* reset indexes */
227   demux->num_indexes = 0;
228   g_free (demux->index);
229   demux->index = NULL;
230
231   /* reset timers */
232   demux->clock = NULL;
233   demux->time_scale = 1000000;
234   demux->duration = 0;
235   demux->pos = 0;
236   demux->created = G_MININT64;
237   demux->seek_pending = GST_CLOCK_TIME_NONE;
238
239   demux->metadata_parsed = FALSE;
240   demux->index_parsed = FALSE;
241 }
242
243 static void
244 gst_matroska_demux_set_clock (GstElement * element, GstClock * clock)
245 {
246   GST_MATROSKA_DEMUX (element)->clock = clock;
247 }
248
249 static gint
250 gst_matroska_demux_stream_from_num (GstMatroskaDemux * demux, guint track_num)
251 {
252   guint n;
253
254   for (n = 0; n < demux->num_streams; n++) {
255     if (demux->src[n] != NULL && demux->src[n]->num == track_num) {
256       return n;
257     }
258   }
259
260   if (n == demux->num_streams) {
261     GST_WARNING ("Failed to find corresponding pad for tracknum %d", track_num);
262   }
263
264   return -1;
265 }
266
267 static GstCaps *
268 gst_matroska_demux_src_getcaps (GstPad * pad)
269 {
270   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
271   guint n;
272
273   for (n = 0; n < demux->num_streams; n++) {
274     if (demux->src[n] != NULL && demux->src[n]->pad == pad) {
275       break;
276     }
277   }
278
279   if (n == demux->num_streams)
280     return gst_caps_new_empty ();
281
282   return gst_caps_copy (demux->src[n]->caps);
283 }
284
285 static gboolean
286 gst_matroska_demux_add_stream (GstMatroskaDemux * demux)
287 {
288   GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
289   GstEbmlRead *ebml = GST_EBML_READ (demux);
290   GstMatroskaTrackContext *context;
291   GstPadTemplate *templ = NULL;
292   GstCaps *caps = NULL;
293   gchar *padname = NULL;
294   gboolean res = TRUE;
295   guint32 id;
296
297   if (demux->num_streams >= GST_MATROSKA_DEMUX_MAX_STREAMS) {
298     GST_WARNING ("Maximum number of streams (%d) exceeded, skipping",
299         GST_MATROSKA_DEMUX_MAX_STREAMS);
300     return gst_ebml_read_skip (ebml);   /* skip-and-continue */
301   }
302
303   /* allocate generic... if we know the type, we'll g_renew()
304    * with the precise type */
305   context = g_new0 (GstMatroskaTrackContext, 1);
306   demux->src[demux->num_streams] = context;
307   context->index = demux->num_streams;
308   context->type = 0;            /* no type yet */
309   demux->num_streams++;
310
311   /* start with the master */
312   if (!gst_ebml_read_master (ebml, &id))
313     return FALSE;
314
315   /* try reading the trackentry headers */
316   while (res) {
317     if (!(id = gst_ebml_peek_id (ebml, &demux->level_up))) {
318       res = FALSE;
319       break;
320     } else if (demux->level_up > 0) {
321       demux->level_up--;
322       break;
323     }
324
325     switch (id) {
326         /* track number (unique stream ID) */
327       case GST_MATROSKA_ID_TRACKNUMBER:{
328         guint64 num;
329
330         if (!gst_ebml_read_uint (ebml, &id, &num)) {
331           res = FALSE;
332           break;
333         }
334         context->num = num;
335         break;
336       }
337
338         /* track UID (unique identifier) */
339       case GST_MATROSKA_ID_TRACKUID:{
340         guint64 num;
341
342         if (!gst_ebml_read_uint (ebml, &id, &num)) {
343           res = FALSE;
344           break;
345         }
346         context->uid = num;
347         break;
348       }
349
350         /* track type (video, audio, combined, subtitle, etc.) */
351       case GST_MATROSKA_ID_TRACKTYPE:{
352         guint64 num;
353
354         if (context->type != 0) {
355           GST_WARNING
356               ("More than one tracktype defined in a trackentry - skipping");
357           break;
358         }
359         if (!gst_ebml_read_uint (ebml, &id, &num)) {
360           res = FALSE;
361           break;
362         }
363         context->type = num;
364
365         /* ok, so we're actually going to reallocate this thing */
366         switch (context->type) {
367           case GST_MATROSKA_TRACK_TYPE_VIDEO:
368             context = (GstMatroskaTrackContext *)
369                 g_renew (GstMatroskaTrackVideoContext, context, 1);
370             break;
371           case GST_MATROSKA_TRACK_TYPE_AUDIO:
372             context = (GstMatroskaTrackContext *)
373                 g_renew (GstMatroskaTrackAudioContext, context, 1);
374             /* defaults */
375             ((GstMatroskaTrackAudioContext *) context)->channels = 1;
376             ((GstMatroskaTrackAudioContext *) context)->samplerate = 8000;
377             break;
378           case GST_MATROSKA_TRACK_TYPE_COMPLEX:
379             context = (GstMatroskaTrackContext *)
380                 g_renew (GstMatroskaTrackComplexContext, context, 1);
381             break;
382           case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
383             context = (GstMatroskaTrackContext *)
384                 g_renew (GstMatroskaTrackSubtitleContext, context, 1);
385             break;
386           case GST_MATROSKA_TRACK_TYPE_LOGO:
387           case GST_MATROSKA_TRACK_TYPE_CONTROL:
388           default:
389             GST_WARNING ("Unknown or unsupported track type 0x%x",
390                 context->type);
391             context->type = 0;
392             break;
393         }
394         demux->src[demux->num_streams - 1] = context;
395         break;
396       }
397
398         /* tracktype specific stuff for video */
399       case GST_MATROSKA_ID_TRACKVIDEO:{
400         GstMatroskaTrackVideoContext *videocontext;
401
402         if (context->type != GST_MATROSKA_TRACK_TYPE_VIDEO) {
403           GST_WARNING
404               ("trackvideo EBML entry in non-video track - ignoring track");
405           res = FALSE;
406           break;
407         } else if (!gst_ebml_read_master (ebml, &id)) {
408           res = FALSE;
409           break;
410         }
411         videocontext = (GstMatroskaTrackVideoContext *) context;
412
413         while (res) {
414           if (!(id = gst_ebml_peek_id (ebml, &demux->level_up))) {
415             res = FALSE;
416             break;
417           } else if (demux->level_up > 0) {
418             demux->level_up--;
419             break;
420           }
421
422           switch (id) {
423               /* fixme, this should be one-up, but I get it here (?) */
424             case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
425               guint64 num;
426
427               if (!gst_ebml_read_uint (ebml, &id, &num)) {
428                 res = FALSE;
429                 break;
430               }
431               context->default_duration = num;
432               break;
433             }
434
435               /* video framerate */
436             case GST_MATROSKA_ID_VIDEOFRAMERATE:{
437               gdouble num;
438
439               if (!gst_ebml_read_float (ebml, &id, &num)) {
440                 res = FALSE;
441                 break;
442               }
443               context->default_duration = GST_SECOND * (1. / num);
444               break;
445             }
446
447               /* width of the size to display the video at */
448             case GST_MATROSKA_ID_VIDEODISPLAYWIDTH:{
449               guint64 num;
450
451               if (!gst_ebml_read_uint (ebml, &id, &num)) {
452                 res = FALSE;
453                 break;
454               }
455               videocontext->display_width = num;
456               break;
457             }
458
459               /* height of the size to display the video at */
460             case GST_MATROSKA_ID_VIDEODISPLAYHEIGHT:{
461               guint64 num;
462
463               if (!gst_ebml_read_uint (ebml, &id, &num)) {
464                 res = FALSE;
465                 break;
466               }
467               videocontext->display_height = num;
468               break;
469             }
470
471               /* width of the video in the file */
472             case GST_MATROSKA_ID_VIDEOPIXELWIDTH:{
473               guint64 num;
474
475               if (!gst_ebml_read_uint (ebml, &id, &num)) {
476                 res = FALSE;
477                 break;
478               }
479               videocontext->pixel_width = num;
480               break;
481             }
482
483               /* height of the video in the file */
484             case GST_MATROSKA_ID_VIDEOPIXELHEIGHT:{
485               guint64 num;
486
487               if (!gst_ebml_read_uint (ebml, &id, &num)) {
488                 res = FALSE;
489                 break;
490               }
491               videocontext->pixel_height = num;
492               break;
493             }
494
495               /* whether the video is interlaced */
496             case GST_MATROSKA_ID_VIDEOFLAGINTERLACED:{
497               guint64 num;
498
499               if (!gst_ebml_read_uint (ebml, &id, &num)) {
500                 res = FALSE;
501                 break;
502               }
503               if (num)
504                 context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;
505               else
506                 context->flags &= ~GST_MATROSKA_VIDEOTRACK_INTERLACED;
507               break;
508             }
509
510               /* stereo mode (whether the video has two streams, where
511                * one is for the left eye and the other for the right eye,
512                * which creates a 3D-like effect) */
513             case GST_MATROSKA_ID_VIDEOSTEREOMODE:{
514               guint64 num;
515
516               if (!gst_ebml_read_uint (ebml, &id, &num)) {
517                 res = FALSE;
518                 break;
519               }
520               if (num != GST_MATROSKA_EYE_MODE_MONO &&
521                   num != GST_MATROSKA_EYE_MODE_LEFT &&
522                   num != GST_MATROSKA_EYE_MODE_RIGHT &&
523                   num != GST_MATROSKA_EYE_MODE_BOTH) {
524                 GST_WARNING ("Unknown eye mode 0x%x - ignoring", (guint) num);
525                 break;
526               }
527               videocontext->eye_mode = num;
528               break;
529             }
530
531               /* aspect ratio behaviour */
532             case GST_MATROSKA_ID_VIDEOASPECTRATIO:{
533               guint64 num;
534
535               if (!gst_ebml_read_uint (ebml, &id, &num)) {
536                 res = FALSE;
537                 break;
538               }
539               if (num != GST_MATROSKA_ASPECT_RATIO_MODE_FREE &&
540                   num != GST_MATROSKA_ASPECT_RATIO_MODE_KEEP &&
541                   num != GST_MATROSKA_ASPECT_RATIO_MODE_FIXED) {
542                 GST_WARNING ("Unknown aspect ratio mode 0x%x - ignoring",
543                     (guint) num);
544                 break;
545               }
546               videocontext->asr_mode = num;
547               break;
548             }
549
550               /* colourspace (only matters for raw video) fourcc */
551             case GST_MATROSKA_ID_VIDEOCOLOURSPACE:{
552               guint64 num;
553
554               if (!gst_ebml_read_uint (ebml, &id, &num)) {
555                 res = FALSE;
556                 break;
557               }
558               videocontext->fourcc = num;
559               break;
560             }
561
562             default:
563               GST_WARNING ("Unknown video track header entry 0x%x - ignoring",
564                   id);
565               /* pass-through */
566
567             case GST_EBML_ID_VOID:
568               if (!gst_ebml_read_skip (ebml))
569                 res = FALSE;
570               break;
571           }
572
573           if (demux->level_up) {
574             demux->level_up--;
575             break;
576           }
577         }
578         break;
579       }
580
581         /* tracktype specific stuff for audio */
582       case GST_MATROSKA_ID_TRACKAUDIO:{
583         GstMatroskaTrackAudioContext *audiocontext;
584
585         if (context->type != GST_MATROSKA_TRACK_TYPE_AUDIO) {
586           GST_WARNING
587               ("trackaudio EBML entry in non-audio track - ignoring track");
588           res = FALSE;
589           break;
590         } else if (!gst_ebml_read_master (ebml, &id)) {
591           res = FALSE;
592           break;
593         }
594         audiocontext = (GstMatroskaTrackAudioContext *) context;
595
596         while (res) {
597           if (!(id = gst_ebml_peek_id (ebml, &demux->level_up))) {
598             res = FALSE;
599             break;
600           } else if (demux->level_up > 0) {
601             demux->level_up--;
602             break;
603           }
604
605           switch (id) {
606               /* samplerate */
607             case GST_MATROSKA_ID_AUDIOSAMPLINGFREQ:{
608               gdouble num;
609
610               if (!gst_ebml_read_float (ebml, &id, &num)) {
611                 res = FALSE;
612                 break;
613               }
614               audiocontext->samplerate = num;
615               break;
616             }
617
618               /* bitdepth */
619             case GST_MATROSKA_ID_AUDIOBITDEPTH:{
620               guint64 num;
621
622               if (!gst_ebml_read_uint (ebml, &id, &num)) {
623                 res = FALSE;
624                 break;
625               }
626               audiocontext->bitdepth = num;
627               break;
628             }
629
630               /* channels */
631             case GST_MATROSKA_ID_AUDIOCHANNELS:{
632               guint64 num;
633
634               if (!gst_ebml_read_uint (ebml, &id, &num)) {
635                 res = FALSE;
636                 break;
637               }
638               audiocontext->channels = num;
639               break;
640             }
641
642             default:
643               GST_WARNING ("Unknown audio track header entry 0x%x - ignoring",
644                   id);
645               /* pass-through */
646
647             case GST_EBML_ID_VOID:
648               if (!gst_ebml_read_skip (ebml))
649                 res = FALSE;
650               break;
651           }
652
653           if (demux->level_up) {
654             demux->level_up--;
655             break;
656           }
657         }
658         break;
659       }
660
661         /* codec identifier */
662       case GST_MATROSKA_ID_CODECID:{
663         gchar *text;
664
665         if (!gst_ebml_read_ascii (ebml, &id, &text)) {
666           res = FALSE;
667           break;
668         }
669         context->codec_id = text;
670         break;
671       }
672
673         /* codec private data */
674       case GST_MATROSKA_ID_CODECPRIVATE:{
675         guint8 *data;
676         guint64 size;
677
678         if (!gst_ebml_read_binary (ebml, &id, &data, &size)) {
679           res = FALSE;
680           break;
681         }
682         context->codec_priv = data;
683         context->codec_priv_size = size;
684         break;
685       }
686
687         /* name of the codec */
688       case GST_MATROSKA_ID_CODECNAME:{
689         gchar *text;
690
691         if (!gst_ebml_read_utf8 (ebml, &id, &text)) {
692           res = FALSE;
693           break;
694         }
695         context->codec_name = text;
696         break;
697       }
698
699         /* name of this track */
700       case GST_MATROSKA_ID_TRACKNAME:{
701         gchar *text;
702
703         if (!gst_ebml_read_utf8 (ebml, &id, &text)) {
704           res = FALSE;
705           break;
706         }
707         context->name = text;
708         break;
709       }
710
711         /* language (matters for audio/subtitles, mostly) */
712       case GST_MATROSKA_ID_TRACKLANGUAGE:{
713         gchar *text;
714
715         if (!gst_ebml_read_utf8 (ebml, &id, &text)) {
716           res = FALSE;
717           break;
718         }
719         context->language = text;
720         break;
721       }
722
723         /* whether this is actually used */
724       case GST_MATROSKA_ID_TRACKFLAGENABLED:{
725         guint64 num;
726
727         if (!gst_ebml_read_uint (ebml, &id, &num)) {
728           res = FALSE;
729           break;
730         }
731         if (num)
732           context->flags |= GST_MATROSKA_TRACK_ENABLED;
733         else
734           context->flags &= ~GST_MATROSKA_TRACK_ENABLED;
735         break;
736       }
737
738         /* whether it's the default for this track type */
739       case GST_MATROSKA_ID_TRACKFLAGDEFAULT:{
740         guint64 num;
741
742         if (!gst_ebml_read_uint (ebml, &id, &num)) {
743           res = FALSE;
744           break;
745         }
746         if (num)
747           context->flags |= GST_MATROSKA_TRACK_DEFAULT;
748         else
749           context->flags &= ~GST_MATROSKA_TRACK_DEFAULT;
750         break;
751       }
752
753         /* lacing (like MPEG, where blocks don't end/start on frame
754          * boundaries) */
755       case GST_MATROSKA_ID_TRACKFLAGLACING:{
756         guint64 num;
757
758         if (!gst_ebml_read_uint (ebml, &id, &num)) {
759           res = FALSE;
760           break;
761         }
762         if (num)
763           context->flags |= GST_MATROSKA_TRACK_LACING;
764         else
765           context->flags &= ~GST_MATROSKA_TRACK_LACING;
766         break;
767       }
768
769         /* default length (in time) of one data block in this track */
770       case GST_MATROSKA_ID_TRACKDEFAULTDURATION:{
771         guint64 num;
772
773         if (!gst_ebml_read_uint (ebml, &id, &num)) {
774           res = FALSE;
775           break;
776         }
777         context->default_duration = num;
778         break;
779       }
780
781       default:
782         GST_WARNING ("Unknown track header entry 0x%x - ignoring", id);
783         /* pass-through */
784
785         /* we ignore these because they're nothing useful (i.e. crap). */
786       case GST_MATROSKA_ID_CODECINFOURL:
787       case GST_MATROSKA_ID_CODECDOWNLOADURL:
788       case GST_MATROSKA_ID_TRACKMINCACHE:
789       case GST_MATROSKA_ID_TRACKMAXCACHE:
790       case GST_EBML_ID_VOID:
791         if (!gst_ebml_read_skip (ebml))
792           res = FALSE;
793         break;
794     }
795
796     if (demux->level_up) {
797       demux->level_up--;
798       break;
799     }
800   }
801
802   if (context->type == 0 || context->codec_id == NULL || !res) {
803     if (res)
804       GST_WARNING ("Unknown stream/codec in track entry header");
805
806     demux->num_streams--;
807     demux->src[demux->num_streams] = NULL;
808     if (context) {
809       g_free (context->codec_id);
810       g_free (context->codec_name);
811       g_free (context->name);
812       g_free (context->language);
813       g_free (context->codec_priv);
814       g_free (context);
815     }
816
817     return res;
818   }
819
820   /* now create the GStreamer connectivity */
821   switch (context->type) {
822     case GST_MATROSKA_TRACK_TYPE_VIDEO:{
823       GstMatroskaTrackVideoContext *videocontext =
824           (GstMatroskaTrackVideoContext *) context;
825       padname = g_strdup_printf ("video_%02d", demux->num_v_streams++);
826       templ = gst_element_class_get_pad_template (klass, "video_%02d");
827       caps = gst_matroska_demux_video_caps (videocontext,
828           context->codec_id,
829           context->codec_priv, context->codec_priv_size, demux);
830       break;
831     }
832
833     case GST_MATROSKA_TRACK_TYPE_AUDIO:{
834       GstMatroskaTrackAudioContext *audiocontext =
835           (GstMatroskaTrackAudioContext *) context;
836       padname = g_strdup_printf ("audio_%02d", demux->num_a_streams++);
837       templ = gst_element_class_get_pad_template (klass, "audio_%02d");
838       caps = gst_matroska_demux_audio_caps (audiocontext,
839           context->codec_id,
840           context->codec_priv, context->codec_priv_size, demux);
841       break;
842     }
843
844     case GST_MATROSKA_TRACK_TYPE_COMPLEX:{
845       GstMatroskaTrackComplexContext *complexcontext =
846           (GstMatroskaTrackComplexContext *) context;
847       padname = g_strdup_printf ("video_%02d", demux->num_v_streams++);
848       templ = gst_element_class_get_pad_template (klass, "video_%02d");
849       caps = gst_matroska_demux_complex_caps (complexcontext,
850           context->codec_id, context->codec_priv, context->codec_priv_size);
851       break;
852     }
853
854     case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
855       GstMatroskaTrackSubtitleContext *subtitlecontext =
856           (GstMatroskaTrackSubtitleContext *) context;
857       padname = g_strdup_printf ("subtitle_%02d", demux->num_t_streams++);
858       templ = gst_element_class_get_pad_template (klass, "subtitle_%02d");
859       caps = gst_matroska_demux_subtitle_caps (subtitlecontext,
860           context->codec_id, context->codec_priv, context->codec_priv_size);
861       break;
862     }
863
864     case GST_MATROSKA_TRACK_TYPE_LOGO:
865     case GST_MATROSKA_TRACK_TYPE_CONTROL:
866     default:
867       /* we should already have quit by now */
868       g_assert (0);
869   }
870
871   /* the pad in here */
872   context->pad = gst_pad_new_from_template (templ, padname);
873   context->caps = caps ? caps : gst_caps_new_empty ();
874
875   g_free (padname);
876
877   /* set some functions */
878   gst_pad_set_formats_function (context->pad,
879       gst_matroska_demux_get_src_formats);
880   gst_pad_set_event_mask_function (context->pad,
881       gst_matroska_demux_get_event_mask);
882   gst_pad_set_event_function (context->pad,
883       gst_matroska_demux_handle_src_event);
884   gst_pad_set_query_type_function (context->pad,
885       gst_matroska_demux_get_src_query_types);
886   gst_pad_set_query_function (context->pad,
887       gst_matroska_demux_handle_src_query);
888   gst_pad_set_getcaps_function (context->pad, gst_matroska_demux_src_getcaps);
889
890   gst_element_add_pad (GST_ELEMENT (demux), context->pad);
891
892   /* tadaah! */
893   return TRUE;
894 }
895
896 static const GstFormat *
897 gst_matroska_demux_get_src_formats (GstPad * pad)
898 {
899   /*GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad)); */
900
901   /* we could try to look for units (i.e. samples) in audio streams
902    * or video streams, but both samplerate and framerate are not
903    * always constant, and since we only have a time indication, we
904    * cannot guarantee anything here based purely on index. So, we
905    * only support time for now. */
906   static const GstFormat src_formats[] = {
907     GST_FORMAT_TIME,
908     (GstFormat) 0
909   };
910
911   return src_formats;
912 }
913
914 static const GstQueryType *
915 gst_matroska_demux_get_src_query_types (GstPad * pad)
916 {
917   static const GstQueryType src_types[] = {
918     GST_QUERY_TOTAL,
919     GST_QUERY_POSITION,
920     (GstQueryType) 0
921   };
922
923   return src_types;
924 }
925
926 static gboolean
927 gst_matroska_demux_handle_src_query (GstPad * pad,
928     GstQueryType type, GstFormat * format, gint64 * value)
929 {
930   gboolean res = TRUE;
931   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
932
933   switch (type) {
934     case GST_QUERY_TOTAL:
935       switch (*format) {
936         case GST_FORMAT_DEFAULT:
937           *format = GST_FORMAT_TIME;
938           /* fall through */
939         case GST_FORMAT_TIME:
940           *value = demux->duration;
941           break;
942         default:
943           res = FALSE;
944           break;
945       }
946       break;
947
948     case GST_QUERY_POSITION:
949       switch (*format) {
950         case GST_FORMAT_DEFAULT:
951           *format = GST_FORMAT_TIME;
952           /* fall through */
953         case GST_FORMAT_TIME:
954           *value = demux->pos;
955           break;
956         default:
957           res = FALSE;
958           break;
959       }
960       break;
961
962     default:
963       res = FALSE;
964       break;
965   }
966
967   return res;
968 }
969
970 static GstMatroskaIndex *
971 gst_matroskademux_seek (GstMatroskaDemux * demux)
972 {
973   guint entry = (guint) - 1;
974   guint64 offset = demux->seek_pending;
975   guint n;
976
977   /* make sure we don't seek twice */
978   demux->seek_pending = GST_CLOCK_TIME_NONE;
979
980   for (n = 0; n < demux->num_indexes; n++) {
981     if (entry == (guint) - 1) {
982       entry = n;
983     } else {
984       gfloat diff_old = fabs (1. * (demux->index[entry].time - offset)),
985           diff_new = fabs (1. * (demux->index[n].time - offset));
986
987       if (diff_new < diff_old) {
988         entry = n;
989       }
990     }
991   }
992
993   if (entry != (guint) - 1) {
994     return &demux->index[entry];
995   }
996
997   return NULL;
998 }
999
1000 static gboolean
1001 gst_matroska_demux_send_event (GstElement * element, GstEvent * event)
1002 {
1003   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
1004   gboolean res = TRUE;
1005
1006   switch (GST_EVENT_TYPE (event)) {
1007     case GST_EVENT_SEEK:
1008       switch (GST_EVENT_SEEK_FORMAT (event)) {
1009         case GST_FORMAT_TIME:
1010           demux->seek_pending = GST_EVENT_SEEK_OFFSET (event);
1011           break;
1012
1013         default:
1014           GST_WARNING ("Only time seek is supported");
1015           res = FALSE;
1016           break;
1017       }
1018       break;
1019
1020     default:
1021       GST_WARNING ("Unhandled event of type %d", GST_EVENT_TYPE (event));
1022       res = FALSE;
1023       break;
1024   }
1025
1026   gst_event_unref (event);
1027
1028   return res;
1029 }
1030
1031 static const GstEventMask *
1032 gst_matroska_demux_get_event_mask (GstPad * pad)
1033 {
1034   static const GstEventMask masks[] = {
1035     {GST_EVENT_SEEK, (GstEventFlag) ((gint) GST_SEEK_METHOD_SET |
1036               (gint) GST_SEEK_FLAG_KEY_UNIT)},
1037     {GST_EVENT_SEEK_SEGMENT, (GstEventFlag) ((gint) GST_SEEK_METHOD_SET |
1038               (gint) GST_SEEK_FLAG_KEY_UNIT)},
1039     {(GstEventType) 0, (GstEventFlag) 0}
1040   };
1041
1042   return masks;
1043 }
1044
1045 static gboolean
1046 gst_matroska_demux_handle_src_event (GstPad * pad, GstEvent * event)
1047 {
1048   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
1049   gboolean res = TRUE;
1050
1051   switch (GST_EVENT_TYPE (event)) {
1052     case GST_EVENT_SEEK_SEGMENT:
1053     case GST_EVENT_SEEK:
1054       return gst_matroska_demux_send_event (GST_ELEMENT (demux), event);
1055
1056     default:
1057       GST_WARNING ("Unhandled event of type %d", GST_EVENT_TYPE (event));
1058       res = FALSE;
1059       break;
1060   }
1061
1062   gst_event_unref (event);
1063
1064   return res;
1065 }
1066
1067 static gboolean
1068 gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux)
1069 {
1070   GstEbmlRead *ebml = GST_EBML_READ (demux);
1071   GstMatroskaIndex *entry = gst_matroskademux_seek (demux);
1072   GstEvent *event;
1073   guint i;
1074
1075   if (!entry)
1076     return FALSE;
1077
1078   /* seek (relative to segment) */
1079   if (!(event = gst_ebml_read_seek (ebml, entry->pos + demux->segment_start)))
1080     return FALSE;
1081   gst_event_unref (event);      /* byte - we want time */
1082   event =
1083       gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, entry->time,
1084       GST_FORMAT_UNDEFINED);
1085
1086   /* forward to all src pads */
1087   for (i = 0; i < demux->num_streams; i++) {
1088     if (GST_PAD_IS_USABLE (demux->src[i]->pad)) {
1089       gst_event_ref (event);
1090       gst_pad_push (demux->src[i]->pad, GST_DATA (event));
1091     }
1092   }
1093
1094   gst_event_unref (event);
1095
1096   return TRUE;
1097 }
1098
1099 static gboolean
1100 gst_matroska_demux_init_stream (GstMatroskaDemux * demux)
1101 {
1102   GstEbmlRead *ebml = GST_EBML_READ (demux);
1103   guint32 id;
1104   gchar *doctype;
1105   guint version;
1106
1107   if (!gst_ebml_read_header (ebml, &doctype, &version))
1108     return FALSE;
1109
1110   if (!doctype || strcmp (doctype, "matroska") != 0) {
1111     GST_ELEMENT_ERROR (demux, STREAM, WRONG_TYPE, (NULL),
1112         ("Input is not a matroska stream (doctype=%s)",
1113             doctype ? doctype : "none"));
1114     g_free (doctype);
1115     return FALSE;
1116   }
1117   g_free (doctype);
1118   if (version > 1) {
1119     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
1120         ("Demuxer version (1) is too old to read stream version %d", version));
1121     return FALSE;
1122   }
1123
1124   /* find segment, must be the next element */
1125   while (1) {
1126     guint last_level;
1127
1128     if (!(id = gst_ebml_peek_id (ebml, &last_level)))
1129       return FALSE;
1130
1131     if (id == GST_MATROSKA_ID_SEGMENT)
1132       break;
1133
1134     /* oi! */
1135     GST_WARNING ("Expected a Segment ID (0x%x), but received 0x%x!",
1136         GST_MATROSKA_ID_SEGMENT, id);
1137     if (!gst_ebml_read_skip (ebml))
1138       return FALSE;
1139   }
1140
1141   /* we now have a EBML segment */
1142   if (!gst_ebml_read_master (ebml, &id))
1143     return FALSE;
1144   /* seeks are from the beginning of the segment,
1145    * after the segment ID/length */
1146   demux->segment_start = gst_bytestream_tell (ebml->bs);
1147
1148   return TRUE;
1149 }
1150
1151 static gboolean
1152 gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux)
1153 {
1154   GstEbmlRead *ebml = GST_EBML_READ (demux);
1155   gboolean res = TRUE;
1156   guint32 id;
1157
1158   while (res) {
1159     if (!(id = gst_ebml_peek_id (ebml, &demux->level_up))) {
1160       res = FALSE;
1161       break;
1162     } else if (demux->level_up) {
1163       demux->level_up--;
1164       break;
1165     }
1166
1167     switch (id) {
1168         /* one track within the "all-tracks" header */
1169       case GST_MATROSKA_ID_TRACKENTRY:
1170         if (!gst_matroska_demux_add_stream (demux))
1171           res = FALSE;
1172         break;
1173
1174       default:
1175         GST_WARNING ("Unknown entry 0x%x in track header", id);
1176         /* fall-through */
1177
1178       case GST_EBML_ID_VOID:
1179         if (!gst_ebml_read_skip (ebml))
1180           res = FALSE;
1181         break;
1182     }
1183
1184     if (demux->level_up) {
1185       demux->level_up--;
1186       break;
1187     }
1188   }
1189
1190   return res;
1191 }
1192
1193 static gboolean
1194 gst_matroska_demux_parse_index (GstMatroskaDemux * demux, gboolean prevent_eos)
1195 {
1196   GstEbmlRead *ebml = GST_EBML_READ (demux);
1197   gboolean res = TRUE;
1198   guint32 id;
1199   GstMatroskaIndex idx;
1200   guint64 length = 0;
1201
1202   if (prevent_eos) {
1203     length = gst_bytestream_length (ebml->bs);
1204   }
1205
1206   while (res) {
1207     /* We're an element that can be seeked to. If we are, then
1208      * we want to prevent EOS, since that'll kill us. So we cache
1209      * file size and seek until there, and don't call EOS upon os. */
1210     if (prevent_eos && length == gst_bytestream_tell (ebml->bs)) {
1211       res = FALSE;
1212       break;
1213     } else if (!(id = gst_ebml_peek_id (ebml, &demux->level_up))) {
1214       res = FALSE;
1215       break;
1216     } else if (demux->level_up) {
1217       demux->level_up--;
1218       break;
1219     }
1220
1221     switch (id) {
1222         /* one single index entry ('point') */
1223       case GST_MATROSKA_ID_POINTENTRY:
1224         if (!gst_ebml_read_master (ebml, &id)) {
1225           res = FALSE;
1226           break;
1227         }
1228
1229         /* in the end, we hope to fill one entry with a
1230          * timestamp, a file position and a tracknum */
1231         idx.pos = (guint64) - 1;
1232         idx.time = (guint64) - 1;
1233         idx.track = (guint16) - 1;
1234
1235         while (res) {
1236           if (prevent_eos && length == gst_bytestream_tell (ebml->bs)) {
1237             res = FALSE;
1238             break;
1239           } else if (!(id = gst_ebml_peek_id (ebml, &demux->level_up))) {
1240             res = FALSE;
1241             break;
1242           } else if (demux->level_up) {
1243             demux->level_up--;
1244             break;
1245           }
1246
1247           switch (id) {
1248               /* one single index entry ('point') */
1249             case GST_MATROSKA_ID_CUETIME:{
1250               gint64 time;
1251
1252               if (!gst_ebml_read_uint (ebml, &id, &time)) {
1253                 res = FALSE;
1254                 break;
1255               }
1256               idx.time = time * demux->time_scale;
1257               break;
1258             }
1259
1260               /* position in the file + track to which it belongs */
1261             case GST_MATROSKA_ID_CUETRACKPOSITION:
1262               if (!gst_ebml_read_master (ebml, &id)) {
1263                 res = FALSE;
1264                 break;
1265               }
1266
1267               while (res) {
1268                 if (prevent_eos && length == gst_bytestream_tell (ebml->bs)) {
1269                   res = FALSE;
1270                   break;
1271                 } else if (!(id = gst_ebml_peek_id (ebml, &demux->level_up))) {
1272                   res = FALSE;
1273                   break;
1274                 } else if (demux->level_up) {
1275                   demux->level_up--;
1276                   break;
1277                 }
1278
1279                 switch (id) {
1280                     /* track number */
1281                   case GST_MATROSKA_ID_CUETRACK:{
1282                     guint64 num;
1283
1284                     if (!gst_ebml_read_uint (ebml, &id, &num)) {
1285                       res = FALSE;
1286                       break;
1287                     }
1288                     idx.track = num;
1289                     break;
1290                   }
1291
1292                     /* position in file */
1293                   case GST_MATROSKA_ID_CUECLUSTERPOSITION:{
1294                     guint64 num;
1295
1296                     if (!gst_ebml_read_uint (ebml, &id, &num)) {
1297                       res = FALSE;
1298                       break;
1299                     }
1300                     idx.pos = num;
1301                     break;
1302                   }
1303
1304                   default:
1305                     GST_WARNING ("Unknown entry 0x%x in CuesTrackPositions",
1306                         id);
1307                     /* fall-through */
1308
1309                   case GST_EBML_ID_VOID:
1310                     if (!gst_ebml_read_skip (ebml))
1311                       res = FALSE;
1312                     break;
1313                 }
1314
1315                 if (demux->level_up) {
1316                   demux->level_up--;
1317                   break;
1318                 }
1319               }
1320
1321               break;
1322
1323             default:
1324               GST_WARNING ("Unknown entry 0x%x in cuespoint index", id);
1325               /* fall-through */
1326
1327             case GST_EBML_ID_VOID:
1328               if (!gst_ebml_read_skip (ebml))
1329                 res = FALSE;
1330               break;
1331           }
1332
1333           if (demux->level_up) {
1334             demux->level_up--;
1335             break;
1336           }
1337         }
1338
1339         /* so let's see if we got what we wanted */
1340         if (idx.pos != (guint64) - 1 &&
1341             idx.time != (guint64) - 1 && idx.track != (guint16) - 1) {
1342           if (demux->num_indexes % 32 == 0) {
1343             /* re-allocate bigger index */
1344             demux->index = g_renew (GstMatroskaIndex, demux->index,
1345                 demux->num_indexes + 32);
1346           }
1347           demux->index[demux->num_indexes].pos = idx.pos;
1348           demux->index[demux->num_indexes].time = idx.time;
1349           demux->index[demux->num_indexes].track = idx.track;
1350           demux->num_indexes++;
1351         }
1352
1353         break;
1354
1355       default:
1356         GST_WARNING ("Unknown entry 0x%x in cues header", id);
1357         /* fall-through */
1358
1359       case GST_EBML_ID_VOID:
1360         if (!gst_ebml_read_skip (ebml))
1361           res = FALSE;
1362         break;
1363     }
1364
1365     if (demux->level_up) {
1366       demux->level_up--;
1367       break;
1368     }
1369   }
1370
1371   return res;
1372 }
1373
1374 static gboolean
1375 gst_matroska_demux_parse_info (GstMatroskaDemux * demux)
1376 {
1377   GstEbmlRead *ebml = GST_EBML_READ (demux);
1378   gboolean res = TRUE;
1379   guint32 id;
1380
1381   while (res) {
1382     if (!(id = gst_ebml_peek_id (ebml, &demux->level_up))) {
1383       res = FALSE;
1384       break;
1385     } else if (demux->level_up) {
1386       demux->level_up--;
1387       break;
1388     }
1389
1390     switch (id) {
1391         /* cluster timecode */
1392       case GST_MATROSKA_ID_TIMECODESCALE:{
1393         guint64 num;
1394
1395         if (!gst_ebml_read_uint (ebml, &id, &num)) {
1396           res = FALSE;
1397           break;
1398         }
1399         demux->time_scale = num;
1400         break;
1401       }
1402
1403       case GST_MATROSKA_ID_DURATION:{
1404         gdouble num;
1405
1406         if (!gst_ebml_read_float (ebml, &id, &num)) {
1407           res = FALSE;
1408           break;
1409         }
1410         demux->duration = num * demux->time_scale;
1411         break;
1412       }
1413
1414       case GST_MATROSKA_ID_WRITINGAPP:{
1415         gchar *text;
1416
1417         if (!gst_ebml_read_utf8 (ebml, &id, &text)) {
1418           res = FALSE;
1419           break;
1420         }
1421         demux->writing_app = text;
1422         break;
1423       }
1424
1425       case GST_MATROSKA_ID_MUXINGAPP:{
1426         gchar *text;
1427
1428         if (!gst_ebml_read_utf8 (ebml, &id, &text)) {
1429           res = FALSE;
1430           break;
1431         }
1432         demux->muxing_app = text;
1433         break;
1434       }
1435
1436       case GST_MATROSKA_ID_DATEUTC:{
1437         gint64 time;
1438
1439         if (!gst_ebml_read_date (ebml, &id, &time)) {
1440           res = FALSE;
1441           break;
1442         }
1443         demux->created = time;
1444         break;
1445       }
1446
1447       default:
1448         GST_WARNING ("Unknown entry 0x%x in info header", id);
1449         /* fall-through */
1450
1451       case GST_EBML_ID_VOID:
1452         if (!gst_ebml_read_skip (ebml))
1453           res = FALSE;
1454         break;
1455     }
1456
1457     if (demux->level_up) {
1458       demux->level_up--;
1459       break;
1460     }
1461   }
1462
1463   return res;
1464 }
1465
1466 static gboolean
1467 gst_matroska_demux_parse_metadata (GstMatroskaDemux * demux,
1468     gboolean prevent_eos)
1469 {
1470   GstEbmlRead *ebml = GST_EBML_READ (demux);
1471   gboolean res = TRUE;
1472   guint32 id;
1473   guint64 length = 0;
1474   struct
1475   {
1476     gchar *matroska_tagname;
1477     gchar *gstreamer_tagname;
1478   }
1479   tag_conv[] =
1480   {
1481     {
1482     GST_MATROSKA_TAG_ID_TITLE, GST_TAG_TITLE}
1483     , {
1484     GST_MATROSKA_TAG_ID_AUTHOR, GST_TAG_ARTIST}
1485     , {
1486     GST_MATROSKA_TAG_ID_ALBUM, GST_TAG_ALBUM}
1487     , {
1488     GST_MATROSKA_TAG_ID_COMMENTS, GST_TAG_COMMENT}
1489     , {
1490     GST_MATROSKA_TAG_ID_BITSPS, GST_TAG_BITRATE}
1491     , {
1492     GST_MATROSKA_TAG_ID_ENCODER, GST_TAG_ENCODER}
1493     , {
1494     GST_MATROSKA_TAG_ID_DATE, GST_TAG_DATE}
1495     , {
1496     GST_MATROSKA_TAG_ID_ISRC, GST_TAG_ISRC}
1497     , {
1498     GST_MATROSKA_TAG_ID_COPYRIGHT, GST_TAG_COPYRIGHT}
1499     , {
1500     NULL, NULL}
1501   };
1502   gint i;
1503   gboolean have_tags = FALSE;
1504   GstTagList *taglist = gst_tag_list_new ();
1505
1506   if (prevent_eos) {
1507     length = gst_bytestream_length (ebml->bs);
1508   }
1509
1510   while (res) {
1511     /* We're an element that can be seeked to. If we are, then
1512      * we want to prevent EOS, since that'll kill us. So we cache
1513      * file size and seek until there, and don't call EOS upon os. */
1514     if (prevent_eos && length == gst_bytestream_tell (ebml->bs)) {
1515       res = FALSE;
1516       break;
1517     } else if (!(id = gst_ebml_peek_id (ebml, &demux->level_up))) {
1518       res = FALSE;
1519       break;
1520     } else if (demux->level_up) {
1521       demux->level_up--;
1522       break;
1523     }
1524
1525     switch (id) {
1526       case GST_MATROSKA_ID_TAG:
1527         if (!gst_ebml_read_master (ebml, &id)) {
1528           res = FALSE;
1529           break;
1530         }
1531
1532         while (res) {
1533           /* read all sub-entries */
1534           if (prevent_eos && length == gst_bytestream_tell (ebml->bs)) {
1535             res = FALSE;
1536             break;
1537           } else if (!(id = gst_ebml_peek_id (ebml, &demux->level_up))) {
1538             res = FALSE;
1539             break;
1540           } else if (demux->level_up) {
1541             demux->level_up--;
1542             break;
1543           }
1544
1545           switch (id) {
1546             case GST_MATROSKA_ID_SIMPLETAG:{
1547               gchar *tag = NULL, *value = NULL;
1548
1549               if (!gst_ebml_read_master (ebml, &id)) {
1550                 res = FALSE;
1551                 break;
1552               }
1553
1554               while (res) {
1555                 /* read all sub-entries */
1556                 if (prevent_eos && length == gst_bytestream_tell (ebml->bs)) {
1557                   res = FALSE;
1558                   break;
1559                 } else if (!(id = gst_ebml_peek_id (ebml, &demux->level_up))) {
1560                   res = FALSE;
1561                   break;
1562                 } else if (demux->level_up) {
1563                   demux->level_up--;
1564                   break;
1565                 }
1566
1567                 switch (id) {
1568                   case GST_MATROSKA_ID_TAGNAME:
1569                     g_free (tag);
1570                     res = gst_ebml_read_ascii (ebml, &id, &tag);
1571                     break;
1572
1573                   case GST_MATROSKA_ID_TAGSTRING:
1574                     g_free (value);
1575                     res = gst_ebml_read_utf8 (ebml, &id, &value);
1576                     break;
1577
1578                   default:
1579                     GST_WARNING ("Unknown entry 0x%x in metadata collection",
1580                         id);
1581                     /* fall-through */
1582
1583                   case GST_EBML_ID_VOID:
1584                     if (!gst_ebml_read_skip (ebml))
1585                       res = FALSE;
1586                     break;
1587                 }
1588
1589                 if (demux->level_up) {
1590                   demux->level_up--;
1591                   break;
1592                 }
1593               }
1594
1595               if (tag && value) {
1596                 for (i = 0; tag_conv[i].matroska_tagname != NULL; i++) {
1597                   if (!strcmp (tag_conv[i].matroska_tagname, tag)) {
1598                     GValue src = { 0 }
1599                     , dest =
1600                     {
1601                     0};
1602                     const gchar *type = tag_conv[i].gstreamer_tagname;
1603                     GType dest_type = gst_tag_get_type (type);
1604
1605                     g_value_init (&src, G_TYPE_STRING);
1606                     g_value_set_string (&src, value);
1607                     g_value_init (&dest, dest_type);
1608                     g_value_transform (&src, &dest);
1609                     g_value_unset (&src);
1610                     gst_tag_list_add_values (taglist, GST_TAG_MERGE_APPEND,
1611                         type, &dest, NULL);
1612                     g_value_unset (&dest);
1613                     have_tags = TRUE;
1614                     break;
1615                   }
1616                 }
1617               }
1618               g_free (tag);
1619               g_free (value);
1620               break;
1621             }
1622
1623             default:
1624               GST_WARNING ("Unknown entry 0x%x in metadata collection", id);
1625               /* fall-through */
1626
1627             case GST_EBML_ID_VOID:
1628               if (!gst_ebml_read_skip (ebml))
1629                 res = FALSE;
1630               break;
1631           }
1632
1633           if (demux->level_up) {
1634             demux->level_up--;
1635             break;
1636           }
1637         }
1638         break;
1639
1640       default:
1641         GST_WARNING ("Unknown entry 0x%x in metadata header", id);
1642         /* fall-through */
1643
1644       case GST_EBML_ID_VOID:
1645         if (!gst_ebml_read_skip (ebml))
1646           res = FALSE;
1647         break;
1648     }
1649
1650     if (demux->level_up) {
1651       demux->level_up--;
1652       break;
1653     }
1654   }
1655
1656   if (have_tags) {
1657     const GList *padlist;
1658
1659     /* let the world know about this wonderful thing */
1660     for (padlist = gst_element_get_pad_list (GST_ELEMENT (ebml));
1661         padlist != NULL; padlist = padlist->next) {
1662       if (GST_PAD_IS_SRC (padlist->data) && GST_PAD_IS_USABLE (padlist->data)) {
1663         gst_pad_push (GST_PAD (padlist->data),
1664             GST_DATA (gst_event_new_tag (taglist)));
1665       }
1666     }
1667     gst_element_found_tags (GST_ELEMENT (ebml), taglist);
1668   } else {
1669     gst_tag_list_free (taglist);
1670   }
1671
1672   return res;
1673 }
1674
1675 /*
1676  * Read signed/unsigned "EBML" numbers.
1677  * Return: number of bytes processed.
1678  */
1679
1680 static gint
1681 gst_matroska_ebmlnum_uint (guint8 * data, guint size, guint64 * num)
1682 {
1683   gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
1684   guint64 total;
1685
1686   if (size <= 0) {
1687     return -1;
1688   }
1689
1690   total = data[0];
1691   while (read <= 8 && !(total & len_mask)) {
1692     read++;
1693     len_mask >>= 1;
1694   }
1695   if (read > 8)
1696     return -1;
1697
1698   if ((total &= (len_mask - 1)) == len_mask - 1)
1699     num_ffs++;
1700   if (size < read)
1701     return -1;
1702   while (n < read) {
1703     if (data[n] == 0xff)
1704       num_ffs++;
1705     total = (total << 8) | data[n];
1706     n++;
1707   }
1708
1709   if (!total)
1710     return -1;
1711
1712   if (read == num_ffs)
1713     *num = G_MAXUINT64;
1714   else
1715     *num = total;
1716
1717   return read;
1718 }
1719
1720 static gint
1721 gst_matroska_ebmlnum_sint (guint8 * data, guint size, gint64 * num)
1722 {
1723   guint64 unum;
1724   gint res;
1725
1726   /* read as unsigned number first */
1727   if ((res = gst_matroska_ebmlnum_uint (data, size, &unum)) < 0)
1728     return -1;
1729
1730   /* make signed */
1731   if (unum == G_MAXUINT64)
1732     *num = G_MAXINT64;
1733   else
1734     *num = unum - ((1 << ((7 * res) - 1)) - 1);
1735
1736   return res;
1737 }
1738
1739 static gboolean
1740 gst_matroska_demux_parse_blockgroup (GstMatroskaDemux * demux,
1741     guint64 cluster_time)
1742 {
1743   GstEbmlRead *ebml = GST_EBML_READ (demux);
1744   gboolean res = TRUE;
1745   guint32 id;
1746
1747   while (res) {
1748     if (!(id = gst_ebml_peek_id (ebml, &demux->level_up))) {
1749       res = FALSE;
1750       break;
1751     } else if (demux->level_up) {
1752       demux->level_up--;
1753       break;
1754     }
1755
1756     switch (id) {
1757         /* one block inside the group. Note, block parsing is one
1758          * of the harder things, so this code is a bit complicated.
1759          * See http://www.matroska.org/ for documentation. */
1760       case GST_MATROSKA_ID_BLOCK:{
1761         GstBuffer *buf;
1762         guint8 *data;
1763         gint64 time;
1764         guint size, *lace_size = NULL;
1765         gint n, stream, flags, laces = 0;
1766         guint64 num;
1767
1768         if (!gst_ebml_read_buffer (ebml, &id, &buf)) {
1769           res = FALSE;
1770           break;
1771         }
1772         data = GST_BUFFER_DATA (buf);
1773         size = GST_BUFFER_SIZE (buf);
1774
1775         /* first byte(s): blocknum */
1776         if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0) {
1777           GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Data error"));
1778           gst_buffer_unref (buf);
1779           res = FALSE;
1780           break;
1781         }
1782         data += n;
1783         size -= n;
1784
1785         /* fetch stream from num */
1786         stream = gst_matroska_demux_stream_from_num (demux, num);
1787         if (size <= 3 || stream < 0 || stream >= demux->num_streams) {
1788           gst_buffer_unref (buf);
1789           GST_WARNING ("Invalid stream %d or size %u", stream, size);
1790           break;
1791         }
1792         if (!GST_PAD_IS_USABLE (demux->src[stream]->pad)) {
1793           gst_buffer_unref (buf);
1794           break;
1795         }
1796
1797         /* time (relative to cluster time) */
1798         time = (GINT16_FROM_BE (*(gint16 *) data)) * demux->time_scale;
1799         data += 2;
1800         size -= 2;
1801         flags = *(guint8 *) data;
1802         data += 1;
1803         size -= 1;
1804         switch ((flags & 0x06) >> 1) {
1805           case 0x0:            /* no lacing */
1806             laces = 1;
1807             lace_size = g_new (gint, 1);
1808             lace_size[0] = size;
1809             break;
1810
1811           case 0x1:            /* xiph lacing */
1812           case 0x2:            /* fixed-size lacing */
1813           case 0x3:            /* EBML lacing */
1814             if (size == 0) {
1815               res = FALSE;
1816               break;
1817             }
1818             laces = (*(guint8 *) data) + 1;
1819             data += 1;
1820             size -= 1;
1821             lace_size = g_new0 (gint, laces);
1822
1823             switch ((flags & 0x06) >> 1) {
1824               case 0x1:        /* xiph lacing */  {
1825                 guint temp, total = 0;
1826
1827                 for (n = 0; res && n < laces - 1; n++) {
1828                   while (1) {
1829                     if (size == 0) {
1830                       res = FALSE;
1831                       break;
1832                     }
1833                     temp = *(guint8 *) data;
1834                     lace_size[n] += temp;
1835                     data += 1;
1836                     size -= 1;
1837                     if (temp != 0xff)
1838                       break;
1839                   }
1840                   total += lace_size[n];
1841                 }
1842                 lace_size[n] = size - total;
1843                 break;
1844               }
1845
1846               case 0x2:        /* fixed-size lacing */
1847                 for (n = 0; n < laces; n++)
1848                   lace_size[n] = size / laces;
1849                 break;
1850
1851               case 0x3:        /* EBML lacing */  {
1852                 guint total;
1853
1854                 if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0) {
1855                   GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
1856                       ("Data error"));
1857                   res = FALSE;
1858                   break;
1859                 }
1860                 data += n;
1861                 size -= n;
1862                 total = lace_size[0] = num;
1863                 for (n = 1; res && n < laces - 1; n++) {
1864                   gint64 snum;
1865                   gint r;
1866
1867                   if ((r = gst_matroska_ebmlnum_sint (data, size, &snum)) < 0) {
1868                     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
1869                         ("Data error"));
1870                     res = FALSE;
1871                     break;
1872                   }
1873                   data += r;
1874                   size -= r;
1875                   lace_size[n] = lace_size[n - 1] + snum;
1876                   total += lace_size[n];
1877                 }
1878                 lace_size[n] = size - total;
1879                 break;
1880               }
1881             }
1882             break;
1883         }
1884
1885         if (res) {
1886           for (n = 0; n < laces; n++) {
1887             GstBuffer *sub = gst_buffer_create_sub (buf,
1888                 GST_BUFFER_SIZE (buf) - size,
1889                 lace_size[n]);
1890
1891             if (cluster_time != GST_CLOCK_TIME_NONE) {
1892               if (time < 0 && (-time) > cluster_time)
1893                 GST_BUFFER_TIMESTAMP (sub) = cluster_time;
1894               else
1895                 GST_BUFFER_TIMESTAMP (sub) = cluster_time + time;
1896             }
1897             /* FIXME: duration */
1898
1899             gst_pad_push (demux->src[stream]->pad, GST_DATA (sub));
1900
1901             size -= lace_size[n];
1902           }
1903         }
1904
1905         g_free (lace_size);
1906         gst_buffer_unref (buf);
1907         break;
1908       }
1909
1910       case GST_MATROSKA_ID_BLOCKDURATION:{
1911         guint64 num;
1912
1913         if (!gst_ebml_read_uint (ebml, &id, &num)) {
1914           res = FALSE;
1915           break;
1916         }
1917         GST_WARNING ("FIXME: implement support for BlockDuration");
1918         break;
1919       }
1920
1921       default:
1922         GST_WARNING ("Unknown entry 0x%x in blockgroup data", id);
1923         /* fall-through */
1924
1925       case GST_EBML_ID_VOID:
1926         if (!gst_ebml_read_skip (ebml))
1927           res = FALSE;
1928         break;
1929     }
1930
1931     if (demux->level_up) {
1932       demux->level_up--;
1933       break;
1934     }
1935   }
1936
1937   return res;
1938 }
1939
1940 static gboolean
1941 gst_matroska_demux_parse_cluster (GstMatroskaDemux * demux)
1942 {
1943   GstEbmlRead *ebml = GST_EBML_READ (demux);
1944   gboolean res = TRUE;
1945   guint32 id;
1946   guint64 cluster_time = GST_CLOCK_TIME_NONE;
1947
1948   /* We seek after index/header parsing before doing a new
1949    * buffer. So here. */
1950   if (demux->seek_pending != GST_CLOCK_TIME_NONE) {
1951     if (!gst_matroska_demux_handle_seek_event (demux))
1952       return FALSE;
1953     demux->seek_pending = GST_CLOCK_TIME_NONE;
1954   }
1955
1956   while (res) {
1957     if (!(id = gst_ebml_peek_id (ebml, &demux->level_up))) {
1958       res = FALSE;
1959       break;
1960     } else if (demux->level_up) {
1961       demux->level_up--;
1962       break;
1963     }
1964
1965     switch (id) {
1966         /* cluster timecode */
1967       case GST_MATROSKA_ID_CLUSTERTIMECODE:{
1968         guint64 num;
1969
1970         if (!gst_ebml_read_uint (ebml, &id, &num)) {
1971           res = FALSE;
1972           break;
1973         }
1974         cluster_time = num * demux->time_scale;
1975         break;
1976       }
1977
1978         /* a group of blocks inside a cluster */
1979       case GST_MATROSKA_ID_BLOCKGROUP:
1980         if (!gst_ebml_read_master (ebml, &id)) {
1981           res = FALSE;
1982           break;
1983         }
1984         res = gst_matroska_demux_parse_blockgroup (demux, cluster_time);
1985         break;
1986
1987       default:
1988         GST_WARNING ("Unknown entry 0x%x in cluster data", id);
1989         /* fall-through */
1990
1991       case GST_EBML_ID_VOID:
1992         if (!gst_ebml_read_skip (ebml))
1993           res = FALSE;
1994         break;
1995     }
1996
1997     if (demux->level_up) {
1998       demux->level_up--;
1999       break;
2000     }
2001   }
2002
2003   return res;
2004 }
2005
2006 static gboolean
2007 gst_matroska_demux_parse_contents (GstMatroskaDemux * demux)
2008 {
2009   GstEbmlRead *ebml = GST_EBML_READ (demux);
2010   gboolean res = TRUE;
2011   guint32 id;
2012
2013   while (res) {
2014     if (!(id = gst_ebml_peek_id (ebml, &demux->level_up))) {
2015       res = FALSE;
2016       break;
2017     } else if (demux->level_up) {
2018       demux->level_up--;
2019       break;
2020     }
2021
2022     switch (id) {
2023       case GST_MATROSKA_ID_SEEKENTRY:{
2024         guint32 seek_id = 0;
2025         guint64 seek_pos = (guint64) - 1, t;
2026
2027         if (!gst_ebml_read_master (ebml, &id)) {
2028           res = FALSE;
2029           break;
2030         }
2031
2032         while (res) {
2033           if (!(id = gst_ebml_peek_id (ebml, &demux->level_up))) {
2034             res = FALSE;
2035             break;
2036           } else if (demux->level_up) {
2037             demux->level_up--;
2038             break;
2039           }
2040
2041           switch (id) {
2042             case GST_MATROSKA_ID_SEEKID:
2043               if (!gst_ebml_read_uint (ebml, &id, &t))
2044                 res = FALSE;
2045               seek_id = t;
2046               break;
2047
2048             case GST_MATROSKA_ID_SEEKPOSITION:
2049               if (!gst_ebml_read_uint (ebml, &id, &seek_pos))
2050                 res = FALSE;
2051               break;
2052
2053             default:
2054               GST_WARNING ("Unknown seekhead ID 0x%x", id);
2055               /* fall-through */
2056
2057             case GST_EBML_ID_VOID:
2058               if (!gst_ebml_read_skip (ebml))
2059                 res = FALSE;
2060               break;
2061           }
2062
2063           if (demux->level_up) {
2064             demux->level_up--;
2065             break;
2066           }
2067         }
2068
2069         if (!seek_id || seek_pos == (guint64) - 1) {
2070           GST_WARNING ("Incomplete seekhead entry (0x%x/%"
2071               G_GUINT64_FORMAT ")", seek_id, seek_pos);
2072           break;
2073         }
2074
2075         switch (seek_id) {
2076           case GST_MATROSKA_ID_CUES:
2077           case GST_MATROSKA_ID_TAGS:{
2078             guint level_up = demux->level_up;
2079             guint64 before_pos, length;
2080             GstEbmlLevel *level;
2081             GstEvent *event;
2082
2083             /* remember */
2084             length = gst_bytestream_length (ebml->bs);
2085             before_pos = gst_bytestream_tell (ebml->bs);
2086
2087             /* check for validity */
2088             if (seek_pos + demux->segment_start + 12 >= length) {
2089               g_warning ("Seekhead reference lies outside file!");
2090               break;
2091             }
2092
2093             /* seek */
2094             if (!(event = gst_ebml_read_seek (ebml,
2095                         seek_pos + demux->segment_start)))
2096               return FALSE;
2097             gst_event_unref (event);
2098
2099             /* we don't want to lose our seekhead level, so we add
2100              * a dummy. This is a crude hack. */
2101             level = g_new (GstEbmlLevel, 1);
2102             level->start = 0;
2103             level->length = G_MAXUINT64;
2104             ebml->level = g_list_append (ebml->level, level);
2105
2106             /* check ID */
2107             if (!(id = gst_ebml_peek_id (ebml, &demux->level_up))) {
2108               res = FALSE;
2109               break;
2110             }
2111             if (id != seek_id) {
2112               g_warning ("We looked for ID=0x%x but got ID=0x%x (pos=%llu)",
2113                   seek_id, id, seek_pos + demux->segment_start);
2114               goto finish;
2115             }
2116
2117             /* read master + parse */
2118             switch (id) {
2119               case GST_MATROSKA_ID_CUES:
2120                 if (!gst_ebml_read_master (ebml, &id))
2121                   res = FALSE;
2122                 else if (!gst_matroska_demux_parse_index (demux, TRUE) &&
2123                     gst_bytestream_length (ebml->bs) !=
2124                     gst_bytestream_tell (ebml->bs))
2125                   res = FALSE;
2126                 else
2127                   demux->index_parsed = TRUE;
2128                 break;
2129               case GST_MATROSKA_ID_TAGS:
2130                 if (!gst_ebml_read_master (ebml, &id))
2131                   res = FALSE;
2132                 else if (!gst_matroska_demux_parse_metadata (demux, TRUE) &&
2133                     gst_bytestream_length (ebml->bs) !=
2134                     gst_bytestream_tell (ebml->bs))
2135                   res = FALSE;
2136                 else
2137                   demux->metadata_parsed = TRUE;
2138                 break;
2139             }
2140             if (!res)
2141               break;
2142
2143           finish:
2144             /* remove dummy level */
2145             while (ebml->level) {
2146               guint64 length;
2147
2148               level = g_list_last (ebml->level)->data;
2149               ebml->level = g_list_remove (ebml->level, level);
2150               length = level->length;
2151               g_free (level);
2152               if (length == G_MAXUINT64)
2153                 break;
2154             }
2155
2156             /* seek back */
2157             if (!(event = gst_ebml_read_seek (ebml, before_pos)))
2158               return FALSE;
2159             gst_event_unref (event);
2160             demux->level_up = level_up;
2161             break;
2162           }
2163
2164           default:
2165             GST_INFO ("Ignoring seekhead entry for ID=0x%x", seek_id);
2166             break;
2167         }
2168
2169         break;
2170       }
2171
2172       default:
2173         GST_WARNING ("Unknown seekhead ID 0x%x", id);
2174         /* fall-through */
2175
2176       case GST_EBML_ID_VOID:
2177         if (!gst_ebml_read_skip (ebml))
2178           res = FALSE;
2179         break;
2180     }
2181
2182     if (demux->level_up) {
2183       demux->level_up--;
2184       break;
2185     }
2186   }
2187
2188   return res;
2189 }
2190
2191 static gboolean
2192 gst_matroska_demux_loop_stream (GstMatroskaDemux * demux)
2193 {
2194   GstEbmlRead *ebml = GST_EBML_READ (demux);
2195   gboolean res = TRUE;
2196   guint32 id;
2197
2198   /* we've found our segment, start reading the different contents in here */
2199   while (res) {
2200     if (!(id = gst_ebml_peek_id (ebml, &demux->level_up))) {
2201       res = FALSE;
2202       break;
2203     } else if (demux->level_up) {
2204       demux->level_up--;
2205       break;
2206     }
2207
2208     switch (id) {
2209         /* stream info */
2210       case GST_MATROSKA_ID_INFO:{
2211         if (!gst_ebml_read_master (ebml, &id)) {
2212           res = FALSE;
2213           break;
2214         }
2215         res = gst_matroska_demux_parse_info (demux);
2216         break;
2217       }
2218
2219         /* track info headers */
2220       case GST_MATROSKA_ID_TRACKS:{
2221         if (!gst_ebml_read_master (ebml, &id)) {
2222           res = FALSE;
2223           break;
2224         }
2225         res = gst_matroska_demux_parse_tracks (demux);
2226         break;
2227       }
2228
2229         /* stream index */
2230       case GST_MATROSKA_ID_CUES:{
2231         if (!demux->index_parsed) {
2232           if (!gst_ebml_read_master (ebml, &id)) {
2233             res = FALSE;
2234             break;
2235           }
2236           res = gst_matroska_demux_parse_index (demux, FALSE);
2237         } else
2238           res = gst_ebml_read_skip (ebml);
2239         break;
2240       }
2241
2242         /* metadata */
2243       case GST_MATROSKA_ID_TAGS:{
2244         if (!demux->index_parsed) {
2245           if (!gst_ebml_read_master (ebml, &id)) {
2246             res = FALSE;
2247             break;
2248           }
2249           res = gst_matroska_demux_parse_metadata (demux, FALSE);
2250         } else
2251           res = gst_ebml_read_skip (ebml);
2252         break;
2253       }
2254
2255         /* file index (if seekable, seek to Cues/Tags to parse it) */
2256       case GST_MATROSKA_ID_SEEKHEAD:{
2257         if (!gst_ebml_read_master (ebml, &id)) {
2258           res = FALSE;
2259           break;
2260         }
2261         res = gst_matroska_demux_parse_contents (demux);
2262         break;
2263       }
2264
2265       case GST_MATROSKA_ID_CLUSTER:{
2266         if (!gst_ebml_read_master (ebml, &id)) {
2267           res = FALSE;
2268           break;
2269         }
2270         /* The idea is that we parse one cluster per loop and
2271          * then break out of the loop here. In the next call
2272          * of the loopfunc, we will get back here with the
2273          * next cluster. If an error occurs, we didn't
2274          * actually push a buffer, but we still want to break
2275          * out of the loop to handle a possible error. We'll
2276          * get back here if it's recoverable. */
2277         gst_matroska_demux_parse_cluster (demux);
2278         demux->state = GST_MATROSKA_DEMUX_STATE_DATA;
2279         res = FALSE;
2280         break;
2281       }
2282
2283       default:
2284         GST_WARNING ("Unknown matroska file header ID 0x%x", id);
2285         /* fall-through */
2286
2287       case GST_EBML_ID_VOID:
2288         if (!gst_ebml_read_skip (ebml))
2289           res = FALSE;
2290         break;
2291     }
2292
2293     if (demux->level_up) {
2294       demux->level_up--;
2295       break;
2296     }
2297   }
2298
2299   return res;
2300 }
2301
2302 static void
2303 gst_matroska_demux_loop (GstElement * element)
2304 {
2305   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
2306
2307   /* first, if we're to start, let's actually get starting */
2308   if (demux->state == GST_MATROSKA_DEMUX_STATE_START) {
2309     if (!gst_matroska_demux_init_stream (demux)) {
2310       return;
2311     }
2312     demux->state = GST_MATROSKA_DEMUX_STATE_HEADER;
2313   }
2314
2315   gst_matroska_demux_loop_stream (demux);
2316 }
2317
2318 static GstCaps *
2319 gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext * videocontext,
2320     const gchar * codec_id, gpointer data, guint size, GstMatroskaDemux * demux)
2321 {
2322   GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) videocontext;
2323   GstCaps *caps = NULL;
2324
2325   if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC)) {
2326     gst_riff_strf_vids *vids = NULL;
2327
2328     if (data) {
2329       char *codec_name = NULL;
2330       GstTagList *list = gst_tag_list_new ();
2331
2332       vids = (gst_riff_strf_vids *) data;
2333
2334       /* assure size is big enough */
2335       if (size < 24) {
2336         GST_WARNING ("Too small BITMAPINFOHEADER (%d bytes)", size);
2337         return NULL;
2338       }
2339       if (size < sizeof (gst_riff_strf_vids)) {
2340         vids =
2341             (gst_riff_strf_vids *) g_realloc (vids,
2342             sizeof (gst_riff_strf_vids));
2343       }
2344
2345       /* little-endian -> byte-order */
2346       vids->size = GUINT32_FROM_LE (vids->size);
2347       vids->width = GUINT32_FROM_LE (vids->width);
2348       vids->height = GUINT32_FROM_LE (vids->height);
2349       vids->planes = GUINT16_FROM_LE (vids->planes);
2350       vids->bit_cnt = GUINT16_FROM_LE (vids->bit_cnt);
2351       vids->compression = GUINT32_FROM_LE (vids->compression);
2352       vids->image_size = GUINT32_FROM_LE (vids->image_size);
2353       vids->xpels_meter = GUINT32_FROM_LE (vids->xpels_meter);
2354       vids->ypels_meter = GUINT32_FROM_LE (vids->ypels_meter);
2355       vids->num_colors = GUINT32_FROM_LE (vids->num_colors);
2356       vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
2357
2358       caps = gst_riff_create_video_caps (vids->compression, NULL, vids,
2359           &codec_name);
2360       gst_tag_list_add (list, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC,
2361           codec_name, NULL);
2362       if (GST_IS_ELEMENT (demux))
2363         gst_element_found_tags (GST_ELEMENT (demux), list);
2364       gst_tag_list_free (list);
2365       if (codec_name)
2366         g_free (codec_name);
2367     } else {
2368       caps = gst_riff_create_video_template_caps ();
2369     }
2370   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
2371     /* how nice, this is undocumented... */
2372     if (videocontext != NULL) {
2373       guint32 fourcc = 0;
2374
2375       switch (videocontext->fourcc) {
2376         case GST_MAKE_FOURCC ('I', '4', '2', '0'):
2377         case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
2378           fourcc = videocontext->fourcc;
2379           break;
2380
2381         default:
2382           GST_DEBUG ("Unknown fourcc " GST_FOURCC_FORMAT,
2383               GST_FOURCC_ARGS (videocontext->fourcc));
2384           return NULL;
2385       }
2386
2387       caps = gst_caps_new_simple ("video/x-raw-yuv",
2388           "format", GST_TYPE_FOURCC, fourcc, NULL);
2389     } else {
2390       caps = gst_caps_from_string ("video/x-raw-yuv, "
2391           "format = (fourcc) { I420, YUY2, YV12 }");
2392     }
2393   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
2394     caps = gst_caps_new_simple ("video/x-divx",
2395         "divxversion", G_TYPE_INT, 4, NULL);
2396   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP) ||
2397       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AP)) {
2398     caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
2399             "divxversion", G_TYPE_INT, 5, NULL),
2400         gst_structure_new ("video/x-xvid", NULL),
2401         gst_structure_new ("video/mpeg",
2402             "mpegversion", G_TYPE_INT, 4,
2403             "systemstream", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
2404   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3)) {
2405     caps = gst_caps_new_full (gst_structure_new ("video/x-divx",
2406             "divxversion", G_TYPE_INT, 3, NULL),
2407         gst_structure_new ("video/x-msmpeg",
2408             "msmpegversion", G_TYPE_INT, 43, NULL), NULL);
2409   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1) ||
2410       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2)) {
2411     gint mpegversion = -1;
2412
2413     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG1))
2414       mpegversion = 1;
2415     else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG2))
2416       mpegversion = 2;
2417     else
2418       g_assert (0);
2419
2420     caps = gst_caps_new_simple ("video/mpeg",
2421         "systemstream", G_TYPE_BOOLEAN, FALSE,
2422         "mpegversion", G_TYPE_INT, mpegversion, NULL);
2423   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
2424     caps = gst_caps_new_simple ("video/x-jpeg", NULL);
2425   } else {
2426     GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
2427     return NULL;
2428   }
2429
2430   if (caps != NULL) {
2431     int i;
2432     GstStructure *structure;
2433
2434     for (i = 0; i < gst_caps_get_size (caps); i++) {
2435       structure = gst_caps_get_structure (caps, i);
2436       if (videocontext != NULL) {
2437         if (videocontext->pixel_width > 0 && videocontext->pixel_height > 0) {
2438           gint w = videocontext->pixel_width;
2439           gint h = videocontext->pixel_height;
2440
2441           gst_structure_set (structure,
2442               "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
2443         } else {
2444           gst_structure_set (structure,
2445               "width", GST_TYPE_INT_RANGE, 16, 4096,
2446               "height", GST_TYPE_INT_RANGE, 16, 4096, NULL);
2447         }
2448 #if 0
2449         if (videocontext->display_width > 0 && videocontext->display_height > 0) {
2450           gint w =
2451               100 * videocontext->display_width / videocontext->pixel_width;
2452           gint h =
2453               100 * videocontext->display_height / videocontext->pixel_height;
2454
2455           gst_structure_set (structure,
2456               "pixel_width", G_TYPE_INT, w,
2457               "pixel_height", G_TYPE_INT, h, NULL);
2458         }
2459 #endif
2460         if (context->default_duration > 0) {
2461           gfloat framerate = 1. * GST_SECOND / context->default_duration;
2462
2463           gst_structure_set (structure,
2464               "framerate", G_TYPE_DOUBLE, framerate, NULL);
2465         } else {
2466           /* sort of a hack to get most codecs to support,
2467            * even if the default_duration is missing */
2468           gst_structure_set (structure, "framerate", G_TYPE_DOUBLE, 25.0, NULL);
2469         }
2470       } else {
2471         gst_structure_set (structure,
2472             "width", GST_TYPE_INT_RANGE, 16, 4096,
2473             "height", GST_TYPE_INT_RANGE, 16, 4096,
2474             "pixel_width", GST_TYPE_INT_RANGE, 0, 255,
2475             "pixel_height", GST_TYPE_INT_RANGE, 0, 255,
2476             "framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE, NULL);
2477       }
2478     }
2479   }
2480
2481   return caps;
2482 }
2483
2484 static GstCaps *
2485 gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext * audiocontext,
2486     const gchar * codec_id, gpointer data, guint size, GstMatroskaDemux * demux)
2487 {
2488   GstMatroskaTrackContext *context = (GstMatroskaTrackContext *) audiocontext;
2489   GstCaps *caps = NULL;
2490
2491   if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1) ||
2492       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2) ||
2493       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3)) {
2494     gint layer = -1;
2495
2496     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1))
2497       layer = 1;
2498     else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2))
2499       layer = 2;
2500     else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3))
2501       layer = 3;
2502     else
2503       g_assert (0);
2504
2505     caps = gst_caps_new_simple ("audio/mpeg",
2506         "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
2507   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
2508       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
2509     gint endianness = -1;
2510
2511     if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
2512       endianness = G_BIG_ENDIAN;
2513     else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE))
2514       endianness = G_LITTLE_ENDIAN;
2515     else
2516       g_assert (0);
2517
2518     if (context != NULL) {
2519       caps = gst_caps_new_simple ("audio/x-raw-int",
2520           "width", G_TYPE_INT, audiocontext->bitdepth,
2521           "depth", G_TYPE_INT, audiocontext->bitdepth,
2522           "signed", G_TYPE_BOOLEAN, audiocontext->bitdepth == 8, NULL);
2523     } else {
2524       caps = gst_caps_from_string ("audio/x-raw-int, "
2525           "signed = (boolean) { TRUE, FALSE }, "
2526           "depth = (int) { 8, 16 }, " "width = (int) { 8, 16 }");
2527     }
2528     gst_caps_set_simple (caps, "endianness", G_TYPE_INT, endianness, NULL);
2529   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
2530     caps = gst_caps_new_simple ("audio/x-raw-float",
2531         "endianness", G_TYPE_INT, G_BYTE_ORDER,
2532         "buffer-frames", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
2533     if (audiocontext != NULL) {
2534       gst_caps_set_simple (caps,
2535           "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
2536     } else {
2537       gst_caps_set_simple (caps, "width", GST_TYPE_INT_RANGE, 32, 64, NULL);
2538     }
2539   } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3,
2540           strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3)) ||
2541       !strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
2542     caps = gst_caps_new_simple ("audio/x-ac3", NULL);
2543   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
2544     caps = gst_caps_new_simple ("audio/x-vorbis", NULL);
2545   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
2546     gst_riff_strf_auds *auds = NULL;
2547
2548     if (data) {
2549       char *codec_name = NULL;
2550       GstTagList *list = gst_tag_list_new ();
2551
2552       auds = (gst_riff_strf_auds *) data;
2553
2554       /* little-endian -> byte-order */
2555       auds->format = GUINT16_FROM_LE (auds->format);
2556       auds->channels = GUINT16_FROM_LE (auds->channels);
2557       auds->rate = GUINT32_FROM_LE (auds->rate);
2558       auds->av_bps = GUINT32_FROM_LE (auds->av_bps);
2559       auds->blockalign = GUINT16_FROM_LE (auds->blockalign);
2560       auds->size = GUINT16_FROM_LE (auds->size);
2561
2562       caps = gst_riff_create_audio_caps (auds->format, NULL, auds, &codec_name);
2563       gst_tag_list_add (list, GST_TAG_MERGE_APPEND, GST_TAG_AUDIO_CODEC,
2564           codec_name, NULL);
2565       if (GST_IS_ELEMENT (demux))
2566         gst_element_found_tags (GST_ELEMENT (demux), list);
2567       gst_tag_list_free (list);
2568       if (codec_name)
2569         g_free (codec_name);
2570     } else {
2571       caps = gst_riff_create_audio_template_caps ();
2572     }
2573   } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG2,
2574           strlen (GST_MATROSKA_CODEC_ID_AUDIO_MPEG2)) ||
2575       !strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG4,
2576           strlen (GST_MATROSKA_CODEC_ID_AUDIO_MPEG4))) {
2577     gint mpegversion = -1;
2578
2579     if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG2,
2580             strlen (GST_MATROSKA_CODEC_ID_AUDIO_MPEG2)))
2581       mpegversion = 2;
2582     else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_MPEG4,
2583             strlen (GST_MATROSKA_CODEC_ID_AUDIO_MPEG4)))
2584       mpegversion = 4;
2585     else
2586       g_assert (0);
2587
2588     caps = gst_caps_new_simple ("audio/mpeg",
2589         "mpegversion", G_TYPE_INT, mpegversion, NULL);
2590   } else {
2591     GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
2592     g_print ("Codec=%s\n", codec_id);
2593     return NULL;
2594   }
2595
2596   if (caps != NULL) {
2597     GstStructure *structure;
2598     int i;
2599
2600     for (i = 0; i < gst_caps_get_size (caps); i++) {
2601       structure = gst_caps_get_structure (caps, i);
2602       if (audiocontext != NULL) {
2603         if (audiocontext->samplerate > 0 && audiocontext->channels > 0) {
2604           gst_structure_set (structure,
2605               "channels", G_TYPE_INT, audiocontext->channels,
2606               "rate", G_TYPE_INT, audiocontext->samplerate, NULL);
2607         }
2608       } else {
2609         gst_structure_set (structure,
2610             "channels", GST_TYPE_INT_RANGE, 1, 6,
2611             "rate", GST_TYPE_INT_RANGE, 4000, 96000, NULL);
2612       }
2613     }
2614   }
2615
2616   return caps;
2617 }
2618
2619 static GstCaps *
2620 gst_matroska_demux_complex_caps (GstMatroskaTrackComplexContext *
2621     complexcontext, const gchar * codec_id, gpointer data, guint size)
2622 {
2623   GstCaps *caps = NULL;
2624
2625   //..
2626
2627   return caps;
2628 }
2629
2630 static GstCaps *
2631 gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
2632     subtitlecontext, const gchar * codec_id, gpointer data, guint size)
2633 {
2634   GstCaps *caps = NULL;
2635
2636   //..
2637
2638   return caps;
2639 }
2640
2641 static GstElementStateReturn
2642 gst_matroska_demux_change_state (GstElement * element)
2643 {
2644   GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
2645
2646   switch (GST_STATE_TRANSITION (element)) {
2647     case GST_STATE_PAUSED_TO_READY:
2648       gst_matroska_demux_reset (GST_ELEMENT (demux));
2649       break;
2650     default:
2651       break;
2652   }
2653
2654   if (((GstElementClass *) parent_class)->change_state)
2655     return ((GstElementClass *) parent_class)->change_state (element);
2656
2657   return GST_STATE_SUCCESS;
2658 }
2659
2660 gboolean
2661 gst_matroska_demux_plugin_init (GstPlugin * plugin)
2662 {
2663   gint i;
2664   GstCaps *videosrccaps, *audiosrccaps, *subtitlesrccaps, *temp;
2665   const gchar *video_id[] = {
2666     GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC,
2667     GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED,
2668     GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP,
2669     GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP,
2670     GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3,
2671     GST_MATROSKA_CODEC_ID_VIDEO_MPEG1,
2672     GST_MATROSKA_CODEC_ID_VIDEO_MPEG2,
2673     GST_MATROSKA_CODEC_ID_VIDEO_MJPEG,
2674     /* TODO: Real/Quicktime */
2675     /* FILLME */
2676     NULL,
2677   }, *audio_id[] =
2678   {
2679     GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1,
2680         GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2,
2681         GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3,
2682         GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE,
2683         GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE,
2684         GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT,
2685         GST_MATROSKA_CODEC_ID_AUDIO_AC3,
2686         GST_MATROSKA_CODEC_ID_AUDIO_ACM,
2687         GST_MATROSKA_CODEC_ID_AUDIO_VORBIS,
2688         GST_MATROSKA_CODEC_ID_AUDIO_MPEG2, GST_MATROSKA_CODEC_ID_AUDIO_MPEG4,
2689         /* TODO: AC3-9/10, Real, Musepack, Quicktime */
2690         /* FILLME */
2691   NULL,}
2692   , *complex_id[] = {
2693     /* FILLME */
2694   NULL,}
2695   , *subtitle_id[] = {
2696     /* FILLME */
2697   NULL,};
2698
2699   /* this filter needs the riff parser */
2700   if (!gst_library_load ("gstbytestream") || !gst_library_load ("riff"))        /* for fourcc stuff */
2701     return FALSE;
2702
2703   /* video src template */
2704   videosrccaps = gst_caps_new_empty ();
2705   for (i = 0; video_id[i] != NULL; i++) {
2706     temp = gst_matroska_demux_video_caps (NULL, video_id[i], NULL, 0, NULL);
2707     gst_caps_append (videosrccaps, temp);
2708   }
2709   for (i = 0; complex_id[i] != NULL; i++) {
2710     temp = gst_matroska_demux_complex_caps (NULL, video_id[i], NULL, 0);
2711     gst_caps_append (videosrccaps, temp);
2712   }
2713   videosrctempl = gst_pad_template_new ("video_%02d",
2714       GST_PAD_SRC, GST_PAD_SOMETIMES, videosrccaps);
2715
2716   audiosrccaps = gst_caps_new_empty ();
2717   /* audio src template */
2718   for (i = 0; audio_id[i] != NULL; i++) {
2719     temp = gst_matroska_demux_audio_caps (NULL, audio_id[i], NULL, 0, NULL);
2720     gst_caps_append (audiosrccaps, temp);
2721   }
2722   audiosrctempl = gst_pad_template_new ("audio_%02d",
2723       GST_PAD_SRC, GST_PAD_SOMETIMES, audiosrccaps);
2724
2725   subtitlesrccaps = gst_caps_new_empty ();
2726   /* subtitle src template */
2727   for (i = 0; subtitle_id[i] != NULL; i++) {
2728     temp = gst_matroska_demux_subtitle_caps (NULL, subtitle_id[i], NULL, 0);
2729     gst_caps_append (subtitlesrccaps, temp);
2730   }
2731   subtitlesrctempl = gst_pad_template_new ("subtitle_%02d",
2732       GST_PAD_SRC, GST_PAD_SOMETIMES, subtitlesrccaps);
2733
2734   /* create an elementfactory for the matroska_demux element */
2735   if (!gst_element_register (plugin, "matroskademux",
2736           GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))
2737     return FALSE;
2738
2739   return TRUE;
2740 }