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