]> git.sesse.net Git - vlc/blob - modules/demux/mkv.cpp
Fixes malloc's parameter
[vlc] / modules / demux / mkv.cpp
1 /*****************************************************************************
2  * mkv.cpp : matroska demuxer
3  *****************************************************************************
4  * Copyright (C) 2003-2004 VideoLAN
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>                                      /* malloc(), free() */
28
29 #include <vlc/vlc.h>
30
31 #ifdef HAVE_TIME_H
32 #   include <time.h>                                               /* time() */
33 #endif
34
35 #include <vlc/input.h>
36
37 #include <codecs.h>                        /* BITMAPINFOHEADER, WAVEFORMATEX */
38 #include "iso_lang.h"
39 #include "vlc_meta.h"
40
41 #include <iostream>
42 #include <cassert>
43 #include <typeinfo>
44
45 /* libebml and matroska */
46 #include "ebml/EbmlHead.h"
47 #include "ebml/EbmlSubHead.h"
48 #include "ebml/EbmlStream.h"
49 #include "ebml/EbmlContexts.h"
50 #include "ebml/EbmlVersion.h"
51 #include "ebml/EbmlVoid.h"
52
53 #include "matroska/FileKax.h"
54 #include "matroska/KaxAttachments.h"
55 #include "matroska/KaxBlock.h"
56 #include "matroska/KaxBlockData.h"
57 #include "matroska/KaxChapters.h"
58 #include "matroska/KaxCluster.h"
59 #include "matroska/KaxClusterData.h"
60 #include "matroska/KaxContexts.h"
61 #include "matroska/KaxCues.h"
62 #include "matroska/KaxCuesData.h"
63 #include "matroska/KaxInfo.h"
64 #include "matroska/KaxInfoData.h"
65 #include "matroska/KaxSeekHead.h"
66 #include "matroska/KaxSegment.h"
67 #include "matroska/KaxTag.h"
68 #include "matroska/KaxTags.h"
69 #include "matroska/KaxTagMulti.h"
70 #include "matroska/KaxTracks.h"
71 #include "matroska/KaxTrackAudio.h"
72 #include "matroska/KaxTrackVideo.h"
73 #include "matroska/KaxTrackEntryData.h"
74 #include "matroska/KaxContentEncoding.h"
75
76 #include "ebml/StdIOCallback.h"
77
78 extern "C" {
79    #include "mp4/libmp4.h"
80 }
81 #ifdef HAVE_ZLIB_H
82 #   include <zlib.h>
83 #endif
84
85 #define MATROSKA_COMPRESSION_NONE 0
86 #define MATROSKA_COMPRESSION_ZLIB 1
87
88 using namespace LIBMATROSKA_NAMESPACE;
89 using namespace std;
90
91 /*****************************************************************************
92  * Module descriptor
93  *****************************************************************************/
94 static int  Open ( vlc_object_t * );
95 static void Close( vlc_object_t * );
96
97 vlc_module_begin();
98     set_description( _("Matroska stream demuxer" ) );
99     set_capability( "demux2", 50 );
100     set_callbacks( Open, Close );
101
102     add_bool( "mkv-seek-percent", 1, NULL,
103             N_("Seek based on percent not time"),
104             N_("Seek based on percent not time"), VLC_TRUE );
105
106     add_shortcut( "mka" );
107     add_shortcut( "mkv" );
108 vlc_module_end();
109
110 /*****************************************************************************
111  * Local prototypes
112  *****************************************************************************/
113 static int  Demux  ( demux_t * );
114 static int  Control( demux_t *, int, va_list );
115 static void Seek   ( demux_t *, mtime_t i_date, int i_percent );
116
117 #ifdef HAVE_ZLIB_H
118 block_t *block_zlib_decompress( vlc_object_t *p_this, block_t *p_in_block ) {
119     int result, dstsize, n;
120     unsigned char *dst;
121     block_t *p_block;
122     z_stream d_stream;
123
124     d_stream.zalloc = (alloc_func)0;
125     d_stream.zfree = (free_func)0;
126     d_stream.opaque = (voidpf)0;
127     result = inflateInit(&d_stream);
128     if( result != Z_OK )
129     {
130         msg_Dbg( p_this, "inflateInit() failed. Result: %d", result );
131         return NULL;
132     }
133
134     d_stream.next_in = (Bytef *)p_in_block->p_buffer;
135     d_stream.avail_in = p_in_block->i_buffer;
136     n = 0;
137     p_block = block_New( p_this, 0 );
138     dst = NULL;
139     do
140     {
141         n++;
142         p_block = block_Realloc( p_block, 0, n * 1000 );
143         dst = (unsigned char *)p_block->p_buffer;
144         d_stream.next_out = (Bytef *)&dst[(n - 1) * 1000];
145         d_stream.avail_out = 1000;
146         result = inflate(&d_stream, Z_NO_FLUSH);
147         if( ( result != Z_OK ) && ( result != Z_STREAM_END ) )
148         {
149             msg_Dbg( p_this, "Zlib decompression failed. Result: %d", result );
150             return NULL;
151         }
152     }
153     while( ( d_stream.avail_out == 0 ) && ( d_stream.avail_in != 0 ) &&
154            ( result != Z_STREAM_END ) );
155
156     dstsize = d_stream.total_out;
157     inflateEnd( &d_stream );
158
159     p_block = block_Realloc( p_block, 0, dstsize );
160     p_block->i_buffer = dstsize;
161     block_Release( p_in_block );
162
163     return p_block;
164 }
165 #endif
166
167 /**
168  * Helper function to print the mkv parse tree
169  */
170 static void MkvTree( demux_t *p_this, int i_level, char *psz_format, ... )
171 {
172     va_list args;
173     if( i_level > 9 )
174     {
175         msg_Err( p_this, "too deep tree" );
176         return;
177     }
178     va_start( args, psz_format );
179     static char *psz_foo = "|   |   |   |   |   |   |   |   |   |";
180     char *psz_foo2 = (char*)malloc( ( i_level * 4 + 3 + strlen( psz_format ) ) * sizeof(char) );
181     strncpy( psz_foo2, psz_foo, 4 * i_level );
182     psz_foo2[ 4 * i_level ] = '+';
183     psz_foo2[ 4 * i_level + 1 ] = ' ';
184     strcpy( &psz_foo2[ 4 * i_level + 2 ], psz_format );
185     __msg_GenericVa( VLC_OBJECT(p_this), VLC_MSG_DBG, "mkv", psz_foo2, args );
186     free( psz_foo2 );
187     va_end( args );
188 }
189     
190 /*****************************************************************************
191  * Stream managment
192  *****************************************************************************/
193 class vlc_stream_io_callback: public IOCallback
194 {
195   private:
196     stream_t       *s;
197     vlc_bool_t     mb_eof;
198
199   public:
200     vlc_stream_io_callback( stream_t * );
201
202     virtual uint32   read            ( void *p_buffer, size_t i_size);
203     virtual void     setFilePointer  ( int64_t i_offset, seek_mode mode = seek_beginning );
204     virtual size_t   write           ( const void *p_buffer, size_t i_size);
205     virtual uint64   getFilePointer  ( void );
206     virtual void     close           ( void );
207 };
208
209 /*****************************************************************************
210  * Ebml Stream parser
211  *****************************************************************************/
212 class EbmlParser
213 {
214   public:
215     EbmlParser( EbmlStream *es, EbmlElement *el_start );
216     ~EbmlParser( void );
217
218     void Up( void );
219     void Down( void );
220     EbmlElement *Get( void );
221     void        Keep( void );
222
223     int GetLevel( void );
224
225   private:
226     EbmlStream  *m_es;
227     int         mi_level;
228     EbmlElement *m_el[10];
229
230     EbmlElement *m_got;
231
232     int         mi_user_level;
233     vlc_bool_t  mb_keep;
234 };
235
236
237 /*****************************************************************************
238  * Some functions to manipulate memory
239  *****************************************************************************/
240 #define GetFOURCC( p )  __GetFOURCC( (uint8_t*)p )
241 static vlc_fourcc_t __GetFOURCC( uint8_t *p )
242 {
243     return VLC_FOURCC( p[0], p[1], p[2], p[3] );
244 }
245
246 /*****************************************************************************
247  * definitions of structures and functions used by this plugins
248  *****************************************************************************/
249 typedef struct
250 {
251     vlc_bool_t  b_default;
252     vlc_bool_t  b_enabled;
253     int         i_number;
254
255     int         i_extra_data;
256     uint8_t     *p_extra_data;
257
258     char         *psz_codec;
259
260     uint64_t     i_default_duration;
261     float        f_timecodescale;
262
263     /* video */
264     es_format_t fmt;
265     float       f_fps;
266     es_out_id_t *p_es;
267
268     vlc_bool_t      b_inited;
269     /* data to be send first */
270     int             i_data_init;
271     uint8_t         *p_data_init;
272
273     /* hack : it's for seek */
274     vlc_bool_t      b_search_keyframe;
275
276     /* informative */
277     char         *psz_codec_name;
278     char         *psz_codec_settings;
279     char         *psz_codec_info_url;
280     char         *psz_codec_download_url;
281     
282     /* encryption/compression */
283     int           i_compression_type;
284
285 } mkv_track_t;
286
287 typedef struct
288 {
289     int     i_track;
290     int     i_block_number;
291
292     int64_t i_position;
293     int64_t i_time;
294
295     vlc_bool_t b_key;
296 } mkv_index_t;
297
298 struct demux_sys_t
299 {
300     vlc_stream_io_callback  *in;
301     EbmlStream              *es;
302     EbmlParser              *ep;
303
304     /* time scale */
305     uint64_t                i_timescale;
306
307     /* duration of the segment */
308     float                   f_duration;
309
310     /* all tracks */
311     int                     i_track;
312     mkv_track_t             *track;
313
314     /* from seekhead */
315     int64_t                 i_cues_position;
316     int64_t                 i_chapters_position;
317     int64_t                 i_tags_position;
318
319     /* current data */
320     KaxSegment              *segment;
321     KaxCluster              *cluster;
322
323     mtime_t                 i_pts;
324
325     vlc_bool_t              b_cues;
326     int                     i_index;
327     int                     i_index_max;
328     mkv_index_t             *index;
329
330     /* info */
331     char                    *psz_muxing_application;
332     char                    *psz_writing_application;
333     char                    *psz_segment_filename;
334     char                    *psz_title;
335     char                    *psz_date_utc;
336
337     vlc_meta_t              *meta;
338
339     input_title_t           *title;
340 };
341
342 #define MKVD_TIMECODESCALE 1000000
343
344 #define MKV_IS_ID( el, C ) ( EbmlId( (*el) ) == C::ClassInfos.GlobalId )
345
346 static void IndexAppendCluster  ( demux_t *p_demux, KaxCluster *cluster );
347 static char *UTF8ToStr          ( const UTFstring &u );
348 static void LoadCues            ( demux_t * );
349 static void InformationCreate  ( demux_t * );
350
351 static void ParseInfo( demux_t *, EbmlElement *info );
352 static void ParseTracks( demux_t *, EbmlElement *tracks );
353 static void ParseSeekHead( demux_t *, EbmlElement *seekhead );
354 static void ParseChapters( demux_t *, EbmlElement *chapters );
355
356 /*****************************************************************************
357  * Open: initializes matroska demux structures
358  *****************************************************************************/
359 static int Open( vlc_object_t * p_this )
360 {
361     demux_t     *p_demux = (demux_t*)p_this;
362     demux_sys_t *p_sys;
363     uint8_t     *p_peek;
364
365     int          i_track;
366
367     EbmlElement *el = NULL, *el1 = NULL;
368
369     /* peek the begining */
370     if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 )
371     {
372         msg_Warn( p_demux, "cannot peek" );
373         return VLC_EGENERIC;
374     }
375
376     /* is a valid file */
377     if( p_peek[0] != 0x1a || p_peek[1] != 0x45 ||
378         p_peek[2] != 0xdf || p_peek[3] != 0xa3 )
379     {
380         msg_Warn( p_demux, "matroska module discarded "
381                            "(invalid header 0x%.2x%.2x%.2x%.2x)",
382                            p_peek[0], p_peek[1], p_peek[2], p_peek[3] );
383         return VLC_EGENERIC;
384     }
385
386     /* Set the demux function */
387     p_demux->pf_demux   = Demux;
388     p_demux->pf_control = Control;
389     p_demux->p_sys      = p_sys = (demux_sys_t*)malloc(sizeof( demux_sys_t ));
390
391     memset( p_sys, 0, sizeof( demux_sys_t ) );
392     p_sys->in = new vlc_stream_io_callback( p_demux->s );
393     p_sys->es = new EbmlStream( *p_sys->in );
394     p_sys->f_duration   = -1;
395     p_sys->i_timescale     = MKVD_TIMECODESCALE;
396     p_sys->i_track      = 0;
397     p_sys->track        = (mkv_track_t*)malloc( sizeof( mkv_track_t ) );
398     p_sys->i_pts   = 0;
399     p_sys->i_cues_position = -1;
400     p_sys->i_chapters_position = -1;
401     p_sys->i_tags_position = -1;
402
403     p_sys->b_cues       = VLC_FALSE;
404     p_sys->i_index      = 0;
405     p_sys->i_index_max  = 1024;
406     p_sys->index        = (mkv_index_t*)malloc( sizeof( mkv_index_t ) *
407                                                 p_sys->i_index_max );
408
409     p_sys->psz_muxing_application = NULL;
410     p_sys->psz_writing_application = NULL;
411     p_sys->psz_segment_filename = NULL;
412     p_sys->psz_title = NULL;
413     p_sys->psz_date_utc = NULL;;
414     p_sys->meta = NULL;
415     p_sys->title = NULL;
416
417     if( p_sys->es == NULL )
418     {
419         msg_Err( p_demux, "failed to create EbmlStream" );
420         delete p_sys->in;
421         free( p_sys );
422         return VLC_EGENERIC;
423     }
424     /* Find the EbmlHead element */
425     el = p_sys->es->FindNextID(EbmlHead::ClassInfos, 0xFFFFFFFFL);
426     if( el == NULL )
427     {
428         msg_Err( p_demux, "cannot find EbmlHead" );
429         goto error;
430     }
431     msg_Dbg( p_demux, "EbmlHead" );
432     /* skip it */
433     el->SkipData( *p_sys->es, el->Generic().Context );
434     delete el;
435
436     /* Find a segment */
437     el = p_sys->es->FindNextID( KaxSegment::ClassInfos, 0xFFFFFFFFL);
438     if( el == NULL )
439     {
440         msg_Err( p_demux, "cannot find KaxSegment" );
441         goto error;
442     }
443     MkvTree( p_demux, 0, "Segment" );
444     p_sys->segment = (KaxSegment*)el;
445     p_sys->cluster = NULL;
446
447     p_sys->ep = new EbmlParser( p_sys->es, el );
448
449     while( ( el1 = p_sys->ep->Get() ) != NULL )
450     {
451         if( MKV_IS_ID( el1, KaxInfo ) )
452         {
453             ParseInfo( p_demux, el1 );
454         }
455         else if( MKV_IS_ID( el1, KaxTracks ) )
456         {
457             ParseTracks( p_demux, el1 );
458         }
459         else if( MKV_IS_ID( el1, KaxSeekHead ) )
460         {
461             ParseSeekHead( p_demux, el1 );
462         }
463         else if( MKV_IS_ID( el1, KaxCues ) )
464         {
465             msg_Dbg( p_demux, "|   + Cues" );
466         }
467         else if( MKV_IS_ID( el1, KaxCluster ) )
468         {
469             msg_Dbg( p_demux, "|   + Cluster" );
470
471             p_sys->cluster = (KaxCluster*)el1;
472
473             p_sys->ep->Down();
474             /* stop parsing the stream */
475             break;
476         }
477         else if( MKV_IS_ID( el1, KaxAttachments ) )
478         {
479             msg_Dbg( p_demux, "|   + Attachments FIXME TODO (but probably never supported)" );
480         }
481         else if( MKV_IS_ID( el1, KaxChapters ) )
482         {
483             msg_Dbg( p_demux, "|   + Chapters" );
484             ParseChapters( p_demux, el1 );
485         }
486         else if( MKV_IS_ID( el1, KaxTag ) )
487         {
488             msg_Dbg( p_demux, "|   + Tags FIXME TODO" );
489         }
490         else
491         {
492             msg_Dbg( p_demux, "|   + Unknown (%s)", typeid(*el1).name() );
493         }
494     }
495
496     if( p_sys->cluster == NULL )
497     {
498         msg_Err( p_demux, "cannot find any cluster, damaged file ?" );
499         goto error;
500     }
501
502     /* *** Load the cue if found *** */
503     if( p_sys->i_cues_position >= 0 )
504     {
505         vlc_bool_t b_seekable;
506
507         stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b_seekable );
508         if( b_seekable )
509         {
510             LoadCues( p_demux );
511         }
512     }
513
514     if( !p_sys->b_cues || p_sys->i_index <= 0 )
515     {
516         msg_Warn( p_demux, "no cues/empty cues found->seek won't be precise" );
517
518         IndexAppendCluster( p_demux, p_sys->cluster );
519
520         p_sys->b_cues = VLC_FALSE;
521     }
522
523     /* add all es */
524     msg_Dbg( p_demux, "found %d es", p_sys->i_track );
525     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
526     {
527 #define tk  p_sys->track[i_track]
528         if( tk.fmt.i_cat == UNKNOWN_ES )
529         {
530             msg_Warn( p_demux, "invalid track[%d, n=%d]", i_track, tk.i_number );
531             tk.p_es = NULL;
532             continue;
533         }
534
535         if( !strcmp( tk.psz_codec, "V_MS/VFW/FOURCC" ) )
536         {
537             if( tk.i_extra_data < (int)sizeof( BITMAPINFOHEADER ) )
538             {
539                 msg_Err( p_demux, "missing/invalid BITMAPINFOHEADER" );
540                 tk.fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
541             }
542             else
543             {
544                 BITMAPINFOHEADER *p_bih = (BITMAPINFOHEADER*)tk.p_extra_data;
545
546                 tk.fmt.video.i_width = GetDWLE( &p_bih->biWidth );
547                 tk.fmt.video.i_height= GetDWLE( &p_bih->biHeight );
548                 tk.fmt.i_codec       = GetFOURCC( &p_bih->biCompression );
549
550                 tk.fmt.i_extra       = GetDWLE( &p_bih->biSize ) - sizeof( BITMAPINFOHEADER );
551                 if( tk.fmt.i_extra > 0 )
552                 {
553                     tk.fmt.p_extra = malloc( tk.fmt.i_extra );
554                     memcpy( tk.fmt.p_extra, &p_bih[1], tk.fmt.i_extra );
555                 }
556             }
557         }
558         else if( !strcmp( tk.psz_codec, "V_MPEG1" ) ||
559                  !strcmp( tk.psz_codec, "V_MPEG2" ) )
560         {
561             tk.fmt.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'v' );
562         }
563         else if( !strncmp( tk.psz_codec, "V_MPEG4", 7 ) )
564         {
565             if( !strcmp( tk.psz_codec, "V_MPEG4/MS/V3" ) )
566             {
567                 tk.fmt.i_codec = VLC_FOURCC( 'D', 'I', 'V', '3' );
568             }
569             else
570             {
571                 tk.fmt.i_codec = VLC_FOURCC( 'm', 'p', '4', 'v' );
572             }
573         }
574         else if( !strcmp( tk.psz_codec, "V_QUICKTIME" ) )
575         {
576             MP4_Box_t *p_box = (MP4_Box_t*)malloc( sizeof( MP4_Box_t ) );
577             MP4_Stream_t *p_mp4_stream = MP4_MemoryStream( p_demux->s,
578                                                            tk.i_extra_data,
579                                                            tk.p_extra_data );
580             MP4_ReadBoxCommon( p_mp4_stream, p_box );
581             MP4_ReadBox_sample_vide( p_mp4_stream, p_box );
582             tk.fmt.i_codec = p_box->i_type;
583             tk.fmt.video.i_width = p_box->data.p_sample_vide->i_width;
584             tk.fmt.video.i_height = p_box->data.p_sample_vide->i_height;
585             tk.fmt.i_extra = p_box->data.p_sample_vide->i_qt_image_description;
586             tk.fmt.p_extra = malloc( tk.fmt.i_extra );
587             memcpy( tk.fmt.p_extra, p_box->data.p_sample_vide->p_qt_image_description, tk.fmt.i_extra );
588             MP4_FreeBox_sample_vide( p_box );
589             free( p_box );
590             free( p_mp4_stream );
591         }
592         else if( !strcmp( tk.psz_codec, "A_MS/ACM" ) )
593         {
594             if( tk.i_extra_data < (int)sizeof( WAVEFORMATEX ) )
595             {
596                 msg_Err( p_demux, "missing/invalid WAVEFORMATEX" );
597                 tk.fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
598             }
599             else
600             {
601                 WAVEFORMATEX *p_wf = (WAVEFORMATEX*)tk.p_extra_data;
602
603                 wf_tag_to_fourcc( GetWLE( &p_wf->wFormatTag ), &tk.fmt.i_codec, NULL );
604
605                 tk.fmt.audio.i_channels   = GetWLE( &p_wf->nChannels );
606                 tk.fmt.audio.i_rate = GetDWLE( &p_wf->nSamplesPerSec );
607                 tk.fmt.i_bitrate    = GetDWLE( &p_wf->nAvgBytesPerSec ) * 8;
608                 tk.fmt.audio.i_blockalign = GetWLE( &p_wf->nBlockAlign );;
609                 tk.fmt.audio.i_bitspersample = GetWLE( &p_wf->wBitsPerSample );
610
611                 tk.fmt.i_extra            = GetWLE( &p_wf->cbSize );
612                 if( tk.fmt.i_extra > 0 )
613                 {
614                     tk.fmt.p_extra = malloc( tk.fmt.i_extra );
615                     memcpy( tk.fmt.p_extra, &p_wf[1], tk.fmt.i_extra );
616                 }
617             }
618         }
619         else if( !strcmp( tk.psz_codec, "A_MPEG/L3" ) ||
620                  !strcmp( tk.psz_codec, "A_MPEG/L2" ) ||
621                  !strcmp( tk.psz_codec, "A_MPEG/L1" ) )
622         {
623             tk.fmt.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'a' );
624         }
625         else if( !strcmp( tk.psz_codec, "A_AC3" ) )
626         {
627             tk.fmt.i_codec = VLC_FOURCC( 'a', '5', '2', ' ' );
628         }
629         else if( !strcmp( tk.psz_codec, "A_DTS" ) )
630         {
631             tk.fmt.i_codec = VLC_FOURCC( 'd', 't', 's', ' ' );
632         }
633         else if( !strcmp( tk.psz_codec, "A_FLAC" ) )
634         {
635             tk.fmt.i_codec = VLC_FOURCC( 'f', 'l', 'a', 'c' );
636             tk.fmt.i_extra = tk.i_extra_data;
637             tk.fmt.p_extra = malloc( tk.i_extra_data );
638             memcpy( tk.fmt.p_extra,tk.p_extra_data, tk.i_extra_data );
639         }
640         else if( !strcmp( tk.psz_codec, "A_VORBIS" ) )
641         {
642             int i, i_offset = 1, i_size[3], i_extra;
643             uint8_t *p_extra;
644
645             tk.fmt.i_codec = VLC_FOURCC( 'v', 'o', 'r', 'b' );
646
647             /* Split the 3 headers */
648             if( tk.p_extra_data[0] != 0x02 )
649                 msg_Err( p_demux, "invalid vorbis header" );
650
651             for( i = 0; i < 2; i++ )
652             {
653                 i_size[i] = 0;
654                 while( i_offset < tk.i_extra_data )
655                 {
656                     i_size[i] += tk.p_extra_data[i_offset];
657                     if( tk.p_extra_data[i_offset++] != 0xff ) break;
658                 }
659             }
660
661             i_size[0] = __MIN(i_size[0], tk.i_extra_data - i_offset);
662             i_size[1] = __MIN(i_size[1], tk.i_extra_data -i_offset -i_size[0]);
663             i_size[2] = tk.i_extra_data - i_offset - i_size[0] - i_size[1];
664
665             tk.fmt.i_extra = 3 * 2 + i_size[0] + i_size[1] + i_size[2];
666             tk.fmt.p_extra = malloc( tk.fmt.i_extra );
667             p_extra = (uint8_t *)tk.fmt.p_extra; i_extra = 0;
668             for( i = 0; i < 3; i++ )
669             {
670                 *(p_extra++) = i_size[i] >> 8;
671                 *(p_extra++) = i_size[i] & 0xFF;
672                 memcpy( p_extra, tk.p_extra_data + i_offset + i_extra,
673                         i_size[i] );
674                 p_extra += i_size[i];
675                 i_extra += i_size[i];
676             }
677         }
678         else if( !strncmp( tk.psz_codec, "A_AAC/MPEG2/", strlen( "A_AAC/MPEG2/" ) ) ||
679                  !strncmp( tk.psz_codec, "A_AAC/MPEG4/", strlen( "A_AAC/MPEG4/" ) ) )
680         {
681             int i_profile, i_srate;
682             static unsigned int i_sample_rates[] =
683             {
684                     96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
685                         16000, 12000, 11025, 8000,  7350,  0,     0,     0
686             };
687
688             tk.fmt.i_codec = VLC_FOURCC( 'm', 'p', '4', 'a' );
689             /* create data for faad (MP4DecSpecificDescrTag)*/
690
691             if( !strcmp( &tk.psz_codec[12], "MAIN" ) )
692             {
693                 i_profile = 0;
694             }
695             else if( !strcmp( &tk.psz_codec[12], "LC" ) )
696             {
697                 i_profile = 1;
698             }
699             else if( !strcmp( &tk.psz_codec[12], "SSR" ) )
700             {
701                 i_profile = 2;
702             }
703             else
704             {
705                 i_profile = 3;
706             }
707
708             for( i_srate = 0; i_srate < 13; i_srate++ )
709             {
710                 if( i_sample_rates[i_srate] == tk.fmt.audio.i_rate )
711                 {
712                     break;
713                 }
714             }
715             msg_Dbg( p_demux, "profile=%d srate=%d", i_profile, i_srate );
716
717             tk.fmt.i_extra = 2;
718             tk.fmt.p_extra = malloc( tk.fmt.i_extra );
719             ((uint8_t*)tk.fmt.p_extra)[0] = ((i_profile + 1) << 3) | ((i_srate&0xe) >> 1);
720             ((uint8_t*)tk.fmt.p_extra)[1] = ((i_srate & 0x1) << 7) | (tk.fmt.audio.i_channels << 3);
721         }
722         else if( !strcmp( tk.psz_codec, "A_PCM/INT/BIG" ) ||
723                  !strcmp( tk.psz_codec, "A_PCM/INT/LIT" ) ||
724                  !strcmp( tk.psz_codec, "A_PCM/FLOAT/IEEE" ) )
725         {
726             if( !strcmp( tk.psz_codec, "A_PCM/INT/BIG" ) )
727             {
728                 tk.fmt.i_codec = VLC_FOURCC( 't', 'w', 'o', 's' );
729             }
730             else
731             {
732                 tk.fmt.i_codec = VLC_FOURCC( 'a', 'r', 'a', 'w' );
733             }
734             tk.fmt.audio.i_blockalign = ( tk.fmt.audio.i_bitspersample + 7 ) / 8 * tk.fmt.audio.i_channels;
735         }
736         else if( !strcmp( tk.psz_codec, "S_TEXT/UTF8" ) )
737         {
738             tk.fmt.i_codec = VLC_FOURCC( 's', 'u', 'b', 't' );
739             tk.fmt.subs.psz_encoding = strdup( "UTF-8" );
740         }
741         else if( !strcmp( tk.psz_codec, "S_TEXT/SSA" ) ||
742                  !strcmp( tk.psz_codec, "S_TEXT/ASS" ) ||
743                  !strcmp( tk.psz_codec, "S_SSA" ) ||
744                  !strcmp( tk.psz_codec, "S_ASS" ))
745         {
746             tk.fmt.i_codec = VLC_FOURCC( 's', 's', 'a', ' ' );
747             tk.fmt.subs.psz_encoding = strdup( "UTF-8" );
748         }
749         else if( !strcmp( tk.psz_codec, "S_VOBSUB" ) )
750         {
751             tk.fmt.i_codec = VLC_FOURCC( 's','p','u',' ' );
752             if( tk.i_extra_data )
753             {
754                 char *p_start;
755                 char *p_buf = (char *)malloc( tk.i_extra_data + 1);
756                 memcpy( p_buf, tk.p_extra_data , tk.i_extra_data );
757                 p_buf[tk.i_extra_data] = '\0';
758                 
759                 p_start = strstr( p_buf, "size:" );
760                 if( sscanf( p_start, "size: %dx%d",
761                         &tk.fmt.subs.spu.i_original_frame_width, &tk.fmt.subs.spu.i_original_frame_height ) == 2 )
762                 {
763                     msg_Dbg( p_demux, "original frame size vobsubs: %dx%d", tk.fmt.subs.spu.i_original_frame_width, tk.fmt.subs.spu.i_original_frame_height );
764                 }
765                 else
766                 {
767                     msg_Warn( p_demux, "reading original frame size for vobsub failed" );
768                 }
769                 free( p_buf );
770             }
771         }
772         else
773         {
774             msg_Err( p_demux, "unknow codec id=`%s'", tk.psz_codec );
775             tk.fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
776         }
777         if( tk.b_default )
778         {
779             tk.fmt.i_priority = 1000;
780         }
781
782         tk.p_es = es_out_Add( p_demux->out, &tk.fmt );
783 #undef tk
784     }
785
786     /* add information */
787     InformationCreate( p_demux );
788
789     return VLC_SUCCESS;
790
791 error:
792     delete p_sys->es;
793     delete p_sys->in;
794     free( p_sys );
795     return VLC_EGENERIC;
796 }
797
798 /*****************************************************************************
799  * Close: frees unused data
800  *****************************************************************************/
801 static void Close( vlc_object_t *p_this )
802 {
803     demux_t     *p_demux = (demux_t*)p_this;
804     demux_sys_t *p_sys   = p_demux->p_sys;
805     int         i_track;
806
807     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
808     {
809 #define tk  p_sys->track[i_track]
810         if( tk.fmt.psz_description )
811         {
812             free( tk.fmt.psz_description );
813         }
814         if( tk.psz_codec )
815         {
816             free( tk.psz_codec );
817         }
818         if( tk.fmt.psz_language )
819         {
820             free( tk.fmt.psz_language );
821         }
822 #undef tk
823     }
824     free( p_sys->track );
825
826     if( p_sys->psz_writing_application  )
827     {
828         free( p_sys->psz_writing_application );
829     }
830     if( p_sys->psz_muxing_application  )
831     {
832         free( p_sys->psz_muxing_application );
833     }
834
835     delete p_sys->segment;
836
837     delete p_sys->ep;
838     delete p_sys->es;
839     delete p_sys->in;
840
841     free( p_sys );
842 }
843
844 /*****************************************************************************
845  * Control:
846  *****************************************************************************/
847 static int Control( demux_t *p_demux, int i_query, va_list args )
848 {
849     demux_sys_t *p_sys = p_demux->p_sys;
850     int64_t     *pi64;
851     double      *pf, f;
852
853     vlc_meta_t **pp_meta;
854
855     switch( i_query )
856     {
857         case DEMUX_GET_META:
858             pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
859             *pp_meta = vlc_meta_Duplicate( p_sys->meta );
860             return VLC_SUCCESS;
861
862         case DEMUX_GET_LENGTH:
863             pi64 = (int64_t*)va_arg( args, int64_t * );
864             if( p_sys->f_duration > 0.0 )
865             {
866                 *pi64 = (int64_t)(p_sys->f_duration * 1000);
867                 return VLC_SUCCESS;
868             }
869             return VLC_EGENERIC;
870
871         case DEMUX_GET_POSITION:
872             pf = (double*)va_arg( args, double * );
873             *pf = (double)p_sys->in->getFilePointer() / (double)stream_Size( p_demux->s );
874             return VLC_SUCCESS;
875
876         case DEMUX_SET_POSITION:
877             f = (double)va_arg( args, double );
878             Seek( p_demux, -1, (int)(100.0 * f) );
879             return VLC_SUCCESS;
880
881         case DEMUX_GET_TIME:
882             pi64 = (int64_t*)va_arg( args, int64_t * );
883             if( p_sys->f_duration > 0.0 )
884             {
885                 mtime_t i_duration = (mtime_t)( p_sys->f_duration / 1000 );
886
887                 /* FIXME */
888                 *pi64 = (mtime_t)1000000 *
889                         (mtime_t)i_duration*
890                         (mtime_t)p_sys->in->getFilePointer() /
891                         (mtime_t)stream_Size( p_demux->s );
892                 return VLC_SUCCESS;
893             }
894             return VLC_EGENERIC;
895
896         case DEMUX_GET_TITLE_INFO:
897             if( p_sys->title && p_sys->title->i_seekpoint > 0 )
898             {
899                 input_title_t ***ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
900                 int *pi_int    = (int*)va_arg( args, int* );
901
902                 *pi_int = 1;
903                 *ppp_title = (input_title_t**)malloc( sizeof( input_title_t**) );
904
905                 (*ppp_title)[0] = vlc_input_title_Duplicate( p_sys->title );
906
907                 return VLC_SUCCESS;
908             }
909             return VLC_EGENERIC;
910
911         case DEMUX_SET_TITLE:
912             if( p_sys->title && p_sys->title->i_seekpoint > 0 )
913             {
914                 return VLC_SUCCESS;
915             }
916             return VLC_EGENERIC;
917
918         case DEMUX_SET_SEEKPOINT:
919             /* FIXME do a better implementation */
920             if( p_sys->title && p_sys->title->i_seekpoint > 0 )
921             {
922                 int i_skp = (int)va_arg( args, int );
923
924                 Seek( p_demux, (int64_t)p_sys->title->seekpoint[i_skp]->i_time_offset, -1);
925                 return VLC_SUCCESS;
926             }
927             return VLC_EGENERIC;
928
929
930         case DEMUX_SET_TIME:
931         case DEMUX_GET_FPS:
932         default:
933             return VLC_EGENERIC;
934     }
935 }
936
937 static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, int64_t *pi_ref2, int64_t *pi_duration )
938 {
939     demux_sys_t *p_sys = p_demux->p_sys;
940
941     *pp_block = NULL;
942     *pi_ref1  = -1;
943     *pi_ref2  = -1;
944
945     for( ;; )
946     {
947         EbmlElement *el;
948         int         i_level;
949
950         if( p_demux->b_die )
951         {
952             return VLC_EGENERIC;
953         }
954
955         el = p_sys->ep->Get();
956         i_level = p_sys->ep->GetLevel();
957
958         if( el == NULL && *pp_block != NULL )
959         {
960             /* update the index */
961 #define idx p_sys->index[p_sys->i_index - 1]
962             if( p_sys->i_index > 0 && idx.i_time == -1 )
963             {
964                 idx.i_time        = (*pp_block)->GlobalTimecode() / (mtime_t)1000;
965                 idx.b_key         = *pi_ref1 == -1 ? VLC_TRUE : VLC_FALSE;
966             }
967 #undef idx
968             return VLC_SUCCESS;
969         }
970
971         if( el == NULL )
972         {
973             if( p_sys->ep->GetLevel() > 1 )
974             {
975                 p_sys->ep->Up();
976                 continue;
977             }
978             msg_Warn( p_demux, "EOF" );
979             return VLC_EGENERIC;
980         }
981
982         /* do parsing */
983         if( i_level == 1 )
984         {
985             if( MKV_IS_ID( el, KaxCluster ) )
986             {
987                 p_sys->cluster = (KaxCluster*)el;
988
989                 /* add it to the index */
990                 if( p_sys->i_index == 0 ||
991                     ( p_sys->i_index > 0 && p_sys->index[p_sys->i_index - 1].i_position < (int64_t)p_sys->cluster->GetElementPosition() ) )
992                 {
993                     IndexAppendCluster( p_demux, p_sys->cluster );
994                 }
995
996                 p_sys->ep->Down();
997             }
998             else if( MKV_IS_ID( el, KaxCues ) )
999             {
1000                 msg_Warn( p_demux, "find KaxCues FIXME" );
1001                 return VLC_EGENERIC;
1002             }
1003             else
1004             {
1005                 msg_Dbg( p_demux, "unknown (%s)", typeid( el ).name() );
1006             }
1007         }
1008         else if( i_level == 2 )
1009         {
1010             if( MKV_IS_ID( el, KaxClusterTimecode ) )
1011             {
1012                 KaxClusterTimecode &ctc = *(KaxClusterTimecode*)el;
1013
1014                 ctc.ReadData( p_sys->es->I_O(), SCOPE_ALL_DATA );
1015                 p_sys->cluster->InitTimecode( uint64( ctc ), p_sys->i_timescale );
1016             }
1017             else if( MKV_IS_ID( el, KaxBlockGroup ) )
1018             {
1019                 p_sys->ep->Down();
1020             }
1021         }
1022         else if( i_level == 3 )
1023         {
1024             if( MKV_IS_ID( el, KaxBlock ) )
1025             {
1026                 *pp_block = (KaxBlock*)el;
1027
1028                 (*pp_block)->ReadData( p_sys->es->I_O() );
1029                 (*pp_block)->SetParent( *p_sys->cluster );
1030
1031                 p_sys->ep->Keep();
1032             }
1033             else if( MKV_IS_ID( el, KaxBlockDuration ) )
1034             {
1035                 KaxBlockDuration &dur = *(KaxBlockDuration*)el;
1036
1037                 dur.ReadData( p_sys->es->I_O() );
1038                 *pi_duration = uint64( dur );
1039             }
1040             else if( MKV_IS_ID( el, KaxReferenceBlock ) )
1041             {
1042                 KaxReferenceBlock &ref = *(KaxReferenceBlock*)el;
1043
1044                 ref.ReadData( p_sys->es->I_O() );
1045                 if( *pi_ref1 == -1 )
1046                 {
1047                     *pi_ref1 = int64( ref );
1048                 }
1049                 else
1050                 {
1051                     *pi_ref2 = int64( ref );
1052                 }
1053             }
1054         }
1055         else
1056         {
1057             msg_Err( p_demux, "invalid level = %d", i_level );
1058             return VLC_EGENERIC;
1059         }
1060     }
1061 }
1062
1063 static block_t *MemToBlock( demux_t *p_demux, uint8_t *p_mem, int i_mem)
1064 {
1065     block_t *p_block;
1066     if( !(p_block = block_New( p_demux, i_mem ) ) ) return NULL;
1067     memcpy( p_block->p_buffer, p_mem, i_mem );
1068     //p_block->i_rate = p_input->stream.control.i_rate;
1069     return p_block;
1070 }
1071
1072 static void BlockDecode( demux_t *p_demux, KaxBlock *block, mtime_t i_pts,
1073                          mtime_t i_duration )
1074 {
1075     demux_sys_t *p_sys = p_demux->p_sys;
1076
1077     int             i_track;
1078     unsigned int    i;
1079     vlc_bool_t      b;
1080
1081 #define tk  p_sys->track[i_track]
1082     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
1083     {
1084         if( tk.i_number == block->TrackNum() )
1085         {
1086             break;
1087         }
1088     }
1089
1090     if( i_track >= p_sys->i_track )
1091     {
1092         msg_Err( p_demux, "invalid track number=%d", block->TrackNum() );
1093         return;
1094     }
1095
1096     es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk.p_es, &b );
1097     if( !b )
1098     {
1099         tk.b_inited = VLC_FALSE;
1100         return;
1101     }
1102
1103     /* First send init data */
1104     if( !tk.b_inited && tk.i_data_init > 0 )
1105     {
1106         block_t *p_init;
1107
1108         msg_Dbg( p_demux, "sending header (%d bytes)", tk.i_data_init );
1109         p_init = MemToBlock( p_demux, tk.p_data_init, tk.i_data_init );
1110         if( p_init ) es_out_Send( p_demux->out, tk.p_es, p_init );
1111     }
1112     tk.b_inited = VLC_TRUE;
1113
1114
1115     for( i = 0; i < block->NumberFrames(); i++ )
1116     {
1117         block_t *p_block;
1118         DataBuffer &data = block->GetBuffer(i);
1119
1120         p_block = MemToBlock( p_demux, data.Buffer(), data.Size() );
1121
1122         if( p_block == NULL )
1123         {
1124             break;
1125         }
1126
1127 #if defined(HAVE_ZLIB_H)
1128         if( tk.i_compression_type )
1129         {
1130             p_block = block_zlib_decompress( VLC_OBJECT(p_demux), p_block );
1131         }
1132 #endif
1133
1134         if( tk.fmt.i_cat != VIDEO_ES )
1135             p_block->i_dts = p_block->i_pts = i_pts;
1136         else
1137         {
1138             p_block->i_dts = i_pts;
1139             p_block->i_pts = 0;
1140         }
1141
1142         if( tk.fmt.i_cat == SPU_ES && strcmp( tk.psz_codec, "S_VOBSUB" ) )
1143         {
1144             p_block->i_length = i_duration * 1000;
1145         }
1146         es_out_Send( p_demux->out, tk.p_es, p_block );
1147
1148         /* use time stamp only for first block */
1149         i_pts = 0;
1150     }
1151
1152 #undef tk
1153 }
1154
1155 static void Seek( demux_t *p_demux, mtime_t i_date, int i_percent)
1156 {
1157     demux_sys_t *p_sys = p_demux->p_sys;
1158
1159     KaxBlock    *block;
1160     int64_t     i_block_duration;
1161     int64_t     i_block_ref1;
1162     int64_t     i_block_ref2;
1163
1164     int         i_index;
1165     int         i_track_skipping;
1166     int         i_track;
1167
1168     msg_Dbg( p_demux, "seek request to "I64Fd" (%d%%)", i_date, i_percent );
1169     if( i_date < 0 && i_percent < 0 )
1170     {
1171         return;
1172     }
1173     if( i_percent > 100 ) i_percent = 100;
1174
1175     delete p_sys->ep;
1176     p_sys->ep = new EbmlParser( p_sys->es, p_sys->segment );
1177     p_sys->cluster = NULL;
1178
1179     /* seek without index or without date */
1180     if( config_GetInt( p_demux, "mkv-seek-percent" ) || !p_sys->b_cues || i_date < 0 )
1181     {
1182         int64_t i_pos = i_percent * stream_Size( p_demux->s ) / 100;
1183
1184         msg_Dbg( p_demux, "inacurate way of seeking" );
1185         for( i_index = 0; i_index < p_sys->i_index; i_index++ )
1186         {
1187             if( p_sys->index[i_index].i_position >= i_pos)
1188             {
1189                 break;
1190             }
1191         }
1192         if( i_index == p_sys->i_index )
1193         {
1194             i_index--;
1195         }
1196
1197         p_sys->in->setFilePointer( p_sys->index[i_index].i_position,
1198                                    seek_beginning );
1199
1200         if( p_sys->index[i_index].i_position < i_pos )
1201         {
1202             EbmlElement *el;
1203
1204             msg_Warn( p_demux, "searching for cluster, could take some time" );
1205
1206             /* search a cluster */
1207             while( ( el = p_sys->ep->Get() ) != NULL )
1208             {
1209                 if( MKV_IS_ID( el, KaxCluster ) )
1210                 {
1211                     KaxCluster *cluster = (KaxCluster*)el;
1212
1213                     /* add it to the index */
1214                     IndexAppendCluster( p_demux, cluster );
1215
1216                     if( (int64_t)cluster->GetElementPosition() >= i_pos )
1217                     {
1218                         p_sys->cluster = cluster;
1219                         p_sys->ep->Down();
1220                         break;
1221                     }
1222                 }
1223             }
1224         }
1225     }
1226     else
1227     {
1228         for( i_index = 0; i_index < p_sys->i_index; i_index++ )
1229         {
1230             if( p_sys->index[i_index].i_time >= i_date )
1231             {
1232                 break;
1233             }
1234         }
1235
1236         if( i_index > 0 )
1237         {
1238             i_index--;
1239         }
1240
1241         msg_Dbg( p_demux, "seek got "I64Fd" (%d%%)",
1242                  p_sys->index[i_index].i_time,
1243                  (int)( 100 * p_sys->index[i_index].i_position /
1244                         stream_Size( p_demux->s ) ) );
1245
1246         p_sys->in->setFilePointer( p_sys->index[i_index].i_position,
1247                                    seek_beginning );
1248     }
1249
1250     /* now parse until key frame */
1251 #define tk  p_sys->track[i_track]
1252     i_track_skipping = 0;
1253     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
1254     {
1255         if( tk.fmt.i_cat == VIDEO_ES )
1256         {
1257             tk.b_search_keyframe = VLC_TRUE;
1258             i_track_skipping++;
1259         }
1260     }
1261
1262     while( i_track_skipping > 0 )
1263     {
1264         if( BlockGet( p_demux, &block, &i_block_ref1, &i_block_ref2, &i_block_duration ) )
1265         {
1266             msg_Warn( p_demux, "cannot get block EOF?" );
1267
1268             return;
1269         }
1270
1271         p_sys->i_pts = block->GlobalTimecode() / (mtime_t) 1000 + 1;
1272
1273         for( i_track = 0; i_track < p_sys->i_track; i_track++ )
1274         {
1275             if( tk.i_number == block->TrackNum() )
1276             {
1277                 break;
1278             }
1279         }
1280
1281         if( i_track < p_sys->i_track )
1282         {
1283             if( tk.fmt.i_cat == VIDEO_ES && i_block_ref1 == -1 && tk.b_search_keyframe )
1284             {
1285                 tk.b_search_keyframe = VLC_FALSE;
1286                 i_track_skipping--;
1287             }
1288             if( tk.fmt.i_cat == VIDEO_ES && !tk.b_search_keyframe )
1289             {
1290                 BlockDecode( p_demux, block, 0, 0 );
1291             }
1292         }
1293
1294         delete block;
1295     }
1296 #undef tk
1297 }
1298
1299 /*****************************************************************************
1300  * Demux: reads and demuxes data packets
1301  *****************************************************************************
1302  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
1303  *****************************************************************************/
1304 static int Demux( demux_t *p_demux)
1305 {
1306     demux_sys_t *p_sys = p_demux->p_sys;
1307     mtime_t        i_start_pts;
1308     int            i_block_count = 0;
1309
1310     KaxBlock *block;
1311     int64_t i_block_duration;
1312     int64_t i_block_ref1;
1313     int64_t i_block_ref2;
1314
1315     i_start_pts = -1;
1316
1317     for( ;; )
1318     {
1319         if( BlockGet( p_demux, &block, &i_block_ref1, &i_block_ref2, &i_block_duration ) )
1320         {
1321             msg_Warn( p_demux, "cannot get block EOF?" );
1322
1323             return 0;
1324         }
1325
1326         p_sys->i_pts = block->GlobalTimecode() / (mtime_t) 1000 + 1;
1327
1328         if( p_sys->i_pts > 0 )
1329         {
1330             es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pts );
1331         }
1332
1333         BlockDecode( p_demux, block, p_sys->i_pts, i_block_duration );
1334
1335         delete block;
1336         i_block_count++;
1337
1338         if( i_start_pts == -1 )
1339         {
1340             i_start_pts = p_sys->i_pts;
1341         }
1342         else if( p_sys->i_pts > i_start_pts + (mtime_t)100000 || i_block_count > 5 )
1343         {
1344             return 1;
1345         }
1346     }
1347 }
1348
1349
1350
1351 /*****************************************************************************
1352  * Stream managment
1353  *****************************************************************************/
1354 vlc_stream_io_callback::vlc_stream_io_callback( stream_t *s_ )
1355 {
1356     s = s_;
1357     mb_eof = VLC_FALSE;
1358 }
1359
1360 uint32 vlc_stream_io_callback::read( void *p_buffer, size_t i_size )
1361 {
1362     if( i_size <= 0 || mb_eof )
1363     {
1364         return 0;
1365     }
1366
1367     return stream_Read( s, p_buffer, i_size );
1368 }
1369 void vlc_stream_io_callback::setFilePointer(int64_t i_offset, seek_mode mode )
1370 {
1371     int64_t i_pos;
1372
1373     switch( mode )
1374     {
1375         case seek_beginning:
1376             i_pos = i_offset;
1377             break;
1378         case seek_end:
1379             i_pos = stream_Size( s ) - i_offset;
1380             break;
1381         default:
1382             i_pos= stream_Tell( s ) + i_offset;
1383             break;
1384     }
1385
1386     if( i_pos < 0 || i_pos >= stream_Size( s ) )
1387     {
1388         mb_eof = VLC_TRUE;
1389         return;
1390     }
1391
1392     mb_eof = VLC_FALSE;
1393     if( stream_Seek( s, i_pos ) )
1394     {
1395         mb_eof = VLC_TRUE;
1396     }
1397     return;
1398 }
1399 size_t vlc_stream_io_callback::write( const void *p_buffer, size_t i_size )
1400 {
1401     return 0;
1402 }
1403 uint64 vlc_stream_io_callback::getFilePointer( void )
1404 {
1405     return stream_Tell( s );
1406 }
1407 void vlc_stream_io_callback::close( void )
1408 {
1409     return;
1410 }
1411
1412
1413 /*****************************************************************************
1414  * Ebml Stream parser
1415  *****************************************************************************/
1416 EbmlParser::EbmlParser( EbmlStream *es, EbmlElement *el_start )
1417 {
1418     int i;
1419
1420     m_es = es;
1421     m_got = NULL;
1422     m_el[0] = el_start;
1423
1424     for( i = 1; i < 6; i++ )
1425     {
1426         m_el[i] = NULL;
1427     }
1428     mi_level = 1;
1429     mi_user_level = 1;
1430     mb_keep = VLC_FALSE;
1431 }
1432
1433 EbmlParser::~EbmlParser( void )
1434 {
1435     int i;
1436
1437     for( i = 1; i < mi_level; i++ )
1438     {
1439         if( !mb_keep )
1440         {
1441             delete m_el[i];
1442         }
1443         mb_keep = VLC_FALSE;
1444     }
1445 }
1446
1447 void EbmlParser::Up( void )
1448 {
1449     if( mi_user_level == mi_level )
1450     {
1451         fprintf( stderr," arrrrrrrrrrrrrg Up cannot escape itself\n" );
1452     }
1453
1454     mi_user_level--;
1455 }
1456
1457 void EbmlParser::Down( void )
1458 {
1459     mi_user_level++;
1460     mi_level++;
1461 }
1462
1463 void EbmlParser::Keep( void )
1464 {
1465     mb_keep = VLC_TRUE;
1466 }
1467
1468 int EbmlParser::GetLevel( void )
1469 {
1470     return mi_user_level;
1471 }
1472
1473 EbmlElement *EbmlParser::Get( void )
1474 {
1475     int i_ulev = 0;
1476
1477     if( mi_user_level != mi_level )
1478     {
1479         return NULL;
1480     }
1481     if( m_got )
1482     {
1483         EbmlElement *ret = m_got;
1484         m_got = NULL;
1485
1486         return ret;
1487     }
1488
1489     if( m_el[mi_level] )
1490     {
1491         m_el[mi_level]->SkipData( *m_es, m_el[mi_level]->Generic().Context );
1492         if( !mb_keep )
1493         {
1494             delete m_el[mi_level];
1495         }
1496         mb_keep = VLC_FALSE;
1497     }
1498
1499     m_el[mi_level] = m_es->FindNextElement( m_el[mi_level - 1]->Generic().Context, i_ulev, 0xFFFFFFFFL, true, 1 );
1500     if( i_ulev > 0 )
1501     {
1502         while( i_ulev > 0 )
1503         {
1504             if( mi_level == 1 )
1505             {
1506                 mi_level = 0;
1507                 return NULL;
1508             }
1509
1510             delete m_el[mi_level - 1];
1511             m_got = m_el[mi_level -1] = m_el[mi_level];
1512             m_el[mi_level] = NULL;
1513
1514             mi_level--;
1515             i_ulev--;
1516         }
1517         return NULL;
1518     }
1519     else if( m_el[mi_level] == NULL )
1520     {
1521         fprintf( stderr," m_el[mi_level] == NULL\n" );
1522     }
1523
1524     return m_el[mi_level];
1525 }
1526
1527
1528 /*****************************************************************************
1529  * Tools
1530  *  * LoadCues : load the cues element and update index
1531  *
1532  *  * LoadTags : load ... the tags element
1533  *
1534  *  * InformationCreate : create all information, load tags if present
1535  *
1536  *****************************************************************************/
1537 static void LoadCues( demux_t *p_demux )
1538 {
1539     demux_sys_t *p_sys = p_demux->p_sys;
1540     int64_t     i_sav_position = p_sys->in->getFilePointer();
1541     EbmlParser  *ep;
1542     EbmlElement *el, *cues;
1543
1544     msg_Dbg( p_demux, "loading cues" );
1545     p_sys->in->setFilePointer( p_sys->i_cues_position, seek_beginning );
1546     cues = p_sys->es->FindNextID( KaxCues::ClassInfos, 0xFFFFFFFFL);
1547
1548     if( cues == NULL )
1549     {
1550         msg_Err( p_demux, "cannot load cues (broken seekhead or file)" );
1551         p_sys->in->setFilePointer( i_sav_position, seek_beginning );
1552         return;
1553     }
1554
1555     ep = new EbmlParser( p_sys->es, cues );
1556     while( ( el = ep->Get() ) != NULL )
1557     {
1558         if( MKV_IS_ID( el, KaxCuePoint ) )
1559         {
1560 #define idx p_sys->index[p_sys->i_index]
1561
1562             idx.i_track       = -1;
1563             idx.i_block_number= -1;
1564             idx.i_position    = -1;
1565             idx.i_time        = 0;
1566             idx.b_key         = VLC_TRUE;
1567
1568             ep->Down();
1569             while( ( el = ep->Get() ) != NULL )
1570             {
1571                 if( MKV_IS_ID( el, KaxCueTime ) )
1572                 {
1573                     KaxCueTime &ctime = *(KaxCueTime*)el;
1574
1575                     ctime.ReadData( p_sys->es->I_O() );
1576
1577                     idx.i_time = uint64( ctime ) * p_sys->i_timescale / (mtime_t)1000;
1578                 }
1579                 else if( MKV_IS_ID( el, KaxCueTrackPositions ) )
1580                 {
1581                     ep->Down();
1582                     while( ( el = ep->Get() ) != NULL )
1583                     {
1584                         if( MKV_IS_ID( el, KaxCueTrack ) )
1585                         {
1586                             KaxCueTrack &ctrack = *(KaxCueTrack*)el;
1587
1588                             ctrack.ReadData( p_sys->es->I_O() );
1589                             idx.i_track = uint16( ctrack );
1590                         }
1591                         else if( MKV_IS_ID( el, KaxCueClusterPosition ) )
1592                         {
1593                             KaxCueClusterPosition &ccpos = *(KaxCueClusterPosition*)el;
1594
1595                             ccpos.ReadData( p_sys->es->I_O() );
1596                             idx.i_position = p_sys->segment->GetGlobalPosition( uint64( ccpos ) );
1597                         }
1598                         else if( MKV_IS_ID( el, KaxCueBlockNumber ) )
1599                         {
1600                             KaxCueBlockNumber &cbnum = *(KaxCueBlockNumber*)el;
1601
1602                             cbnum.ReadData( p_sys->es->I_O() );
1603                             idx.i_block_number = uint32( cbnum );
1604                         }
1605                         else
1606                         {
1607                             msg_Dbg( p_demux, "         * Unknown (%s)", typeid(*el).name() );
1608                         }
1609                     }
1610                     ep->Up();
1611                 }
1612                 else
1613                 {
1614                     msg_Dbg( p_demux, "     * Unknown (%s)", typeid(*el).name() );
1615                 }
1616             }
1617             ep->Up();
1618
1619 #if 0
1620             msg_Dbg( p_demux, " * added time="I64Fd" pos="I64Fd
1621                      " track=%d bnum=%d", idx.i_time, idx.i_position,
1622                      idx.i_track, idx.i_block_number );
1623 #endif
1624
1625             p_sys->i_index++;
1626             if( p_sys->i_index >= p_sys->i_index_max )
1627             {
1628                 p_sys->i_index_max += 1024;
1629                 p_sys->index = (mkv_index_t*)realloc( p_sys->index, sizeof( mkv_index_t ) * p_sys->i_index_max );
1630             }
1631 #undef idx
1632         }
1633         else
1634         {
1635             msg_Dbg( p_demux, " * Unknown (%s)", typeid(*el).name() );
1636         }
1637     }
1638     delete ep;
1639     delete cues;
1640
1641     p_sys->b_cues = VLC_TRUE;
1642
1643     msg_Dbg( p_demux, "loading cues done." );
1644     p_sys->in->setFilePointer( i_sav_position, seek_beginning );
1645 }
1646
1647 static void LoadTags( demux_t *p_demux )
1648 {
1649     demux_sys_t *p_sys = p_demux->p_sys;
1650     int64_t     i_sav_position = p_sys->in->getFilePointer();
1651     EbmlParser  *ep;
1652     EbmlElement *el, *tags;
1653
1654     msg_Dbg( p_demux, "loading tags" );
1655     p_sys->in->setFilePointer( p_sys->i_tags_position, seek_beginning );
1656     tags = p_sys->es->FindNextID( KaxTags::ClassInfos, 0xFFFFFFFFL);
1657
1658     if( tags == NULL )
1659     {
1660         msg_Err( p_demux, "cannot load tags (broken seekhead or file)" );
1661         p_sys->in->setFilePointer( i_sav_position, seek_beginning );
1662         return;
1663     }
1664
1665     msg_Dbg( p_demux, "Tags" );
1666     ep = new EbmlParser( p_sys->es, tags );
1667     while( ( el = ep->Get() ) != NULL )
1668     {
1669         if( MKV_IS_ID( el, KaxTag ) )
1670         {
1671             msg_Dbg( p_demux, "+ Tag" );
1672             ep->Down();
1673             while( ( el = ep->Get() ) != NULL )
1674             {
1675                 if( MKV_IS_ID( el, KaxTagTargets ) )
1676                 {
1677                     msg_Dbg( p_demux, "|   + Targets" );
1678                     ep->Down();
1679                     while( ( el = ep->Get() ) != NULL )
1680                     {
1681                         msg_Dbg( p_demux, "|   |   + Unknown (%s)", typeid( *el ).name() );
1682                     }
1683                     ep->Up();
1684                 }
1685                 else if( MKV_IS_ID( el, KaxTagGeneral ) )
1686                 {
1687                     msg_Dbg( p_demux, "|   + General" );
1688                     ep->Down();
1689                     while( ( el = ep->Get() ) != NULL )
1690                     {
1691                         msg_Dbg( p_demux, "|   |   + Unknown (%s)", typeid( *el ).name() );
1692                     }
1693                     ep->Up();
1694                 }
1695                 else if( MKV_IS_ID( el, KaxTagGenres ) )
1696                 {
1697                     msg_Dbg( p_demux, "|   + Genres" );
1698                     ep->Down();
1699                     while( ( el = ep->Get() ) != NULL )
1700                     {
1701                         msg_Dbg( p_demux, "|   |   + Unknown (%s)", typeid( *el ).name() );
1702                     }
1703                     ep->Up();
1704                 }
1705                 else if( MKV_IS_ID( el, KaxTagAudioSpecific ) )
1706                 {
1707                     msg_Dbg( p_demux, "|   + Audio Specific" );
1708                     ep->Down();
1709                     while( ( el = ep->Get() ) != NULL )
1710                     {
1711                         msg_Dbg( p_demux, "|   |   + Unknown (%s)", typeid( *el ).name() );
1712                     }
1713                     ep->Up();
1714                 }
1715                 else if( MKV_IS_ID( el, KaxTagImageSpecific ) )
1716                 {
1717                     msg_Dbg( p_demux, "|   + Images Specific" );
1718                     ep->Down();
1719                     while( ( el = ep->Get() ) != NULL )
1720                     {
1721                         msg_Dbg( p_demux, "|   |   + Unknown (%s)", typeid( *el ).name() );
1722                     }
1723                     ep->Up();
1724                 }
1725                 else if( MKV_IS_ID( el, KaxTagMultiComment ) )
1726                 {
1727                     msg_Dbg( p_demux, "|   + Multi Comment" );
1728                 }
1729                 else if( MKV_IS_ID( el, KaxTagMultiCommercial ) )
1730                 {
1731                     msg_Dbg( p_demux, "|   + Multi Commercial" );
1732                 }
1733                 else if( MKV_IS_ID( el, KaxTagMultiDate ) )
1734                 {
1735                     msg_Dbg( p_demux, "|   + Multi Date" );
1736                 }
1737                 else if( MKV_IS_ID( el, KaxTagMultiEntity ) )
1738                 {
1739                     msg_Dbg( p_demux, "|   + Multi Entity" );
1740                 }
1741                 else if( MKV_IS_ID( el, KaxTagMultiIdentifier ) )
1742                 {
1743                     msg_Dbg( p_demux, "|   + Multi Identifier" );
1744                 }
1745                 else if( MKV_IS_ID( el, KaxTagMultiLegal ) )
1746                 {
1747                     msg_Dbg( p_demux, "|   + Multi Legal" );
1748                 }
1749                 else if( MKV_IS_ID( el, KaxTagMultiTitle ) )
1750                 {
1751                     msg_Dbg( p_demux, "|   + Multi Title" );
1752                 }
1753                 else
1754                 {
1755                     msg_Dbg( p_demux, "|   + Unknown (%s)", typeid( *el ).name() );
1756                 }
1757             }
1758             ep->Up();
1759         }
1760         else
1761         {
1762             msg_Dbg( p_demux, "+ Unknown (%s)", typeid( *el ).name() );
1763         }
1764     }
1765     delete ep;
1766     delete tags;
1767
1768     msg_Dbg( p_demux, "loading tags done." );
1769     p_sys->in->setFilePointer( i_sav_position, seek_beginning );
1770 }
1771
1772 /*****************************************************************************
1773  * ParseInfo:
1774  *****************************************************************************/
1775 static void ParseSeekHead( demux_t *p_demux, EbmlElement *seekhead )
1776 {
1777     demux_sys_t *p_sys = p_demux->p_sys;
1778     EbmlElement *el;
1779     EbmlMaster  *m;
1780     unsigned int i;
1781     int i_upper_level = 0;
1782
1783     msg_Dbg( p_demux, "|   + Seek head" );
1784
1785     /* Master elements */
1786     m = static_cast<EbmlMaster *>(seekhead);
1787     m->Read( *p_sys->es, seekhead->Generic().Context, i_upper_level, el, true );
1788
1789     for( i = 0; i < m->ListSize(); i++ )
1790     {
1791         EbmlElement *l = (*m)[i];
1792
1793         if( MKV_IS_ID( l, KaxSeek ) )
1794         {
1795             EbmlMaster *sk = static_cast<EbmlMaster *>(l);
1796             EbmlId id = EbmlVoid::ClassInfos.GlobalId;
1797             int64_t i_pos = -1;
1798
1799             unsigned int j;
1800
1801             for( j = 0; j < sk->ListSize(); j++ )
1802             {
1803                 EbmlElement *l = (*sk)[j];
1804
1805                 if( MKV_IS_ID( l, KaxSeekID ) )
1806                 {
1807                     KaxSeekID &sid = *(KaxSeekID*)l;
1808                     id = EbmlId( sid.GetBuffer(), sid.GetSize() );
1809                 }
1810                 else if( MKV_IS_ID( l, KaxSeekPosition ) )
1811                 {
1812                     KaxSeekPosition &spos = *(KaxSeekPosition*)l;
1813                     i_pos = uint64( spos );
1814                 }
1815                 else
1816                 {
1817                     msg_Dbg( p_demux, "|   |   |   + Unknown (%s)", typeid(*l).name() );
1818                 }
1819             }
1820
1821             if( i_pos >= 0 )
1822             {
1823                 if( id == KaxCues::ClassInfos.GlobalId )
1824                 {
1825                     msg_Dbg( p_demux, "|   |   |   = cues at "I64Fd, i_pos );
1826                     p_sys->i_cues_position = p_sys->segment->GetGlobalPosition( i_pos );
1827                 }
1828                 else if( id == KaxChapters::ClassInfos.GlobalId )
1829                 {
1830                     msg_Dbg( p_demux, "|   |   |   = chapters at "I64Fd, i_pos );
1831                     p_sys->i_chapters_position = p_sys->segment->GetGlobalPosition( i_pos );
1832                 }
1833                 else if( id == KaxTags::ClassInfos.GlobalId )
1834                 {
1835                     msg_Dbg( p_demux, "|   |   |   = tags at "I64Fd, i_pos );
1836                     p_sys->i_tags_position = p_sys->segment->GetGlobalPosition( i_pos );
1837                 }
1838             }
1839         }
1840         else
1841         {
1842             msg_Dbg( p_demux, "|   |   + Unknown (%s)", typeid(*l).name() );
1843         }
1844     }
1845 }
1846
1847 /*****************************************************************************
1848  * ParseTracks:
1849  *****************************************************************************/
1850 static void ParseTrackEntry( demux_t *p_demux, EbmlMaster *m )
1851 {
1852     demux_sys_t *p_sys = p_demux->p_sys;
1853     unsigned int i;
1854
1855     mkv_track_t *tk;
1856
1857     msg_Dbg( p_demux, "|   |   + Track Entry" );
1858
1859     p_sys->i_track++;
1860     p_sys->track = (mkv_track_t*)realloc( p_sys->track, sizeof( mkv_track_t ) * (p_sys->i_track + 1 ) );
1861
1862     /* Init the track */
1863     tk = &p_sys->track[p_sys->i_track - 1];
1864
1865     memset( tk, 0, sizeof( mkv_track_t ) );
1866
1867     es_format_Init( &tk->fmt, UNKNOWN_ES, 0 );
1868     tk->fmt.psz_language = strdup("English");
1869     tk->fmt.psz_description = NULL;
1870
1871     tk->b_default = VLC_TRUE;
1872     tk->b_enabled = VLC_TRUE;
1873     tk->i_number = p_sys->i_track - 1;
1874     tk->i_extra_data = 0;
1875     tk->p_extra_data = NULL;
1876     tk->psz_codec = NULL;
1877     tk->i_default_duration = 0;
1878     tk->f_timecodescale = 1.0;
1879
1880     tk->b_inited = VLC_FALSE;
1881     tk->i_data_init = 0;
1882     tk->p_data_init = NULL;
1883
1884     tk->psz_codec_name = NULL;
1885     tk->psz_codec_settings = NULL;
1886     tk->psz_codec_info_url = NULL;
1887     tk->psz_codec_download_url = NULL;
1888     
1889     tk->i_compression_type = MATROSKA_COMPRESSION_NONE;
1890
1891     for( i = 0; i < m->ListSize(); i++ )
1892     {
1893         EbmlElement *l = (*m)[i];
1894
1895         if( MKV_IS_ID( l, KaxTrackNumber ) )
1896         {
1897             KaxTrackNumber &tnum = *(KaxTrackNumber*)l;
1898
1899             tk->i_number = uint32( tnum );
1900             msg_Dbg( p_demux, "|   |   |   + Track Number=%u", uint32( tnum ) );
1901         }
1902         else  if( MKV_IS_ID( l, KaxTrackUID ) )
1903         {
1904             KaxTrackUID &tuid = *(KaxTrackUID*)l;
1905
1906             msg_Dbg( p_demux, "|   |   |   + Track UID=%u",  uint32( tuid ) );
1907         }
1908         else  if( MKV_IS_ID( l, KaxTrackType ) )
1909         {
1910             char *psz_type;
1911             KaxTrackType &ttype = *(KaxTrackType*)l;
1912
1913             switch( uint8(ttype) )
1914             {
1915                 case track_audio:
1916                     psz_type = "audio";
1917                     tk->fmt.i_cat = AUDIO_ES;
1918                     break;
1919                 case track_video:
1920                     psz_type = "video";
1921                     tk->fmt.i_cat = VIDEO_ES;
1922                     break;
1923                 case track_subtitle:
1924                     psz_type = "subtitle";
1925                     tk->fmt.i_cat = SPU_ES;
1926                     break;
1927                 default:
1928                     psz_type = "unknown";
1929                     tk->fmt.i_cat = UNKNOWN_ES;
1930                     break;
1931             }
1932
1933             msg_Dbg( p_demux, "|   |   |   + Track Type=%s", psz_type );
1934         }
1935 //        else  if( EbmlId( *l ) == KaxTrackFlagEnabled::ClassInfos.GlobalId )
1936 //        {
1937 //            KaxTrackFlagEnabled &fenb = *(KaxTrackFlagEnabled*)l;
1938
1939 //            tk->b_enabled = uint32( fenb );
1940 //            msg_Dbg( p_demux, "|   |   |   + Track Enabled=%u",
1941 //                     uint32( fenb )  );
1942 //        }
1943         else  if( MKV_IS_ID( l, KaxTrackFlagDefault ) )
1944         {
1945             KaxTrackFlagDefault &fdef = *(KaxTrackFlagDefault*)l;
1946
1947             tk->b_default = uint32( fdef );
1948             msg_Dbg( p_demux, "|   |   |   + Track Default=%u", uint32( fdef )  );
1949         }
1950         else  if( MKV_IS_ID( l, KaxTrackFlagLacing ) )
1951         {
1952             KaxTrackFlagLacing &lac = *(KaxTrackFlagLacing*)l;
1953
1954             msg_Dbg( p_demux, "|   |   |   + Track Lacing=%d", uint32( lac ) );
1955         }
1956         else  if( MKV_IS_ID( l, KaxTrackMinCache ) )
1957         {
1958             KaxTrackMinCache &cmin = *(KaxTrackMinCache*)l;
1959
1960             msg_Dbg( p_demux, "|   |   |   + Track MinCache=%d", uint32( cmin ) );
1961         }
1962         else  if( MKV_IS_ID( l, KaxTrackMaxCache ) )
1963         {
1964             KaxTrackMaxCache &cmax = *(KaxTrackMaxCache*)l;
1965
1966             msg_Dbg( p_demux, "|   |   |   + Track MaxCache=%d", uint32( cmax ) );
1967         }
1968         else  if( MKV_IS_ID( l, KaxTrackDefaultDuration ) )
1969         {
1970             KaxTrackDefaultDuration &defd = *(KaxTrackDefaultDuration*)l;
1971
1972             tk->i_default_duration = uint64(defd);
1973             msg_Dbg( p_demux, "|   |   |   + Track Default Duration="I64Fd, uint64(defd) );
1974         }
1975         else  if( MKV_IS_ID( l, KaxTrackTimecodeScale ) )
1976         {
1977             KaxTrackTimecodeScale &ttcs = *(KaxTrackTimecodeScale*)l;
1978
1979             tk->f_timecodescale = float( ttcs );
1980             msg_Dbg( p_demux, "|   |   |   + Track TimeCodeScale=%f", tk->f_timecodescale );
1981         }
1982         else if( MKV_IS_ID( l, KaxTrackName ) )
1983         {
1984             KaxTrackName &tname = *(KaxTrackName*)l;
1985
1986             tk->fmt.psz_description = UTF8ToStr( UTFstring( tname ) );
1987             msg_Dbg( p_demux, "|   |   |   + Track Name=%s", tk->fmt.psz_description );
1988         }
1989         else  if( MKV_IS_ID( l, KaxTrackLanguage ) )
1990         {
1991             KaxTrackLanguage &lang = *(KaxTrackLanguage*)l;
1992
1993             tk->fmt.psz_language = strdup( string( lang ).c_str() );
1994             msg_Dbg( p_demux,
1995                      "|   |   |   + Track Language=`%s'", tk->fmt.psz_language );
1996         }
1997         else  if( MKV_IS_ID( l, KaxCodecID ) )
1998         {
1999             KaxCodecID &codecid = *(KaxCodecID*)l;
2000
2001             tk->psz_codec = strdup( string( codecid ).c_str() );
2002             msg_Dbg( p_demux, "|   |   |   + Track CodecId=%s", string( codecid ).c_str() );
2003         }
2004         else  if( MKV_IS_ID( l, KaxCodecPrivate ) )
2005         {
2006             KaxCodecPrivate &cpriv = *(KaxCodecPrivate*)l;
2007
2008             tk->i_extra_data = cpriv.GetSize();
2009             if( tk->i_extra_data > 0 )
2010             {
2011                 tk->p_extra_data = (uint8_t*)malloc( tk->i_extra_data );
2012                 memcpy( tk->p_extra_data, cpriv.GetBuffer(), tk->i_extra_data );
2013             }
2014             msg_Dbg( p_demux, "|   |   |   + Track CodecPrivate size="I64Fd, cpriv.GetSize() );
2015         }
2016         else if( MKV_IS_ID( l, KaxCodecName ) )
2017         {
2018             KaxCodecName &cname = *(KaxCodecName*)l;
2019
2020             tk->psz_codec_name = UTF8ToStr( UTFstring( cname ) );
2021             msg_Dbg( p_demux, "|   |   |   + Track Codec Name=%s", tk->psz_codec_name );
2022         }
2023         else if( MKV_IS_ID( l, KaxContentEncodings ) )
2024         {
2025             EbmlMaster *cencs = static_cast<EbmlMaster*>(l);
2026             MkvTree( p_demux, 3, "Content Encodings" );
2027             for( unsigned int i = 0; i < cencs->ListSize(); i++ )
2028             {
2029                 EbmlElement *l2 = (*cencs)[i];
2030                 if( MKV_IS_ID( l2, KaxContentEncoding ) )
2031                 {
2032                     MkvTree( p_demux, 4, "Content Encoding" );
2033                     EbmlMaster *cenc = static_cast<EbmlMaster*>(l2);
2034                     for( unsigned int i = 0; i < cenc->ListSize(); i++ )
2035                     {
2036                         EbmlElement *l3 = (*cenc)[i];
2037                         if( MKV_IS_ID( l3, KaxContentEncodingOrder ) )
2038                         {
2039                             KaxContentEncodingOrder &encord = *(KaxContentEncodingOrder*)l3;
2040                             MkvTree( p_demux, 5, "Order: %i", uint32( encord ) );
2041                         }
2042                         else if( MKV_IS_ID( l3, KaxContentEncodingScope ) )
2043                         {
2044                             KaxContentEncodingScope &encscope = *(KaxContentEncodingScope*)l3;
2045                             MkvTree( p_demux, 5, "Scope: %i", uint32( encscope ) );
2046                         }
2047                         else if( MKV_IS_ID( l3, KaxContentEncodingType ) )
2048                         {
2049                             KaxContentEncodingType &enctype = *(KaxContentEncodingType*)l3;
2050                             MkvTree( p_demux, 5, "Type: %i", uint32( enctype ) );
2051                         }
2052                         else if( MKV_IS_ID( l3, KaxContentCompression ) )
2053                         {
2054                             EbmlMaster *compr = static_cast<EbmlMaster*>(l3);
2055                             MkvTree( p_demux, 5, "Content Compression" );
2056                             for( unsigned int i = 0; i < compr->ListSize(); i++ )
2057                             {
2058                                 EbmlElement *l4 = (*compr)[i];
2059                                 if( MKV_IS_ID( l4, KaxContentCompAlgo ) )
2060                                 {
2061                                     KaxContentCompAlgo &compalg = *(KaxContentCompAlgo*)l4;
2062                                     MkvTree( p_demux, 6, "Compression Algorithm: %i", uint32(compalg) );
2063                                     if( uint32( compalg ) == 0 )
2064                                     {
2065                                         tk->i_compression_type = MATROSKA_COMPRESSION_ZLIB;
2066                                     }
2067                                 }
2068                                 else
2069                                 {
2070                                     MkvTree( p_demux, 6, "Unknown (%s)", typeid(*l4).name() );
2071                                 }
2072                             }
2073                         }
2074
2075                         else
2076                         {
2077                             MkvTree( p_demux, 5, "Unknown (%s)", typeid(*l3).name() );
2078                         }
2079                     }
2080                     
2081                 }
2082                 else
2083                 {
2084                     MkvTree( p_demux, 4, "Unknown (%s)", typeid(*l2).name() );
2085                 }
2086             }
2087                 
2088         }
2089 //        else if( EbmlId( *l ) == KaxCodecSettings::ClassInfos.GlobalId )
2090 //        {
2091 //            KaxCodecSettings &cset = *(KaxCodecSettings*)l;
2092
2093 //            tk->psz_codec_settings = UTF8ToStr( UTFstring( cset ) );
2094 //            msg_Dbg( p_demux, "|   |   |   + Track Codec Settings=%s", tk->psz_codec_settings );
2095 //        }
2096 //        else if( EbmlId( *l ) == KaxCodecInfoURL::ClassInfos.GlobalId )
2097 //        {
2098 //            KaxCodecInfoURL &ciurl = *(KaxCodecInfoURL*)l;
2099
2100 //            tk->psz_codec_info_url = strdup( string( ciurl ).c_str() );
2101 //            msg_Dbg( p_demux, "|   |   |   + Track Codec Info URL=%s", tk->psz_codec_info_url );
2102 //        }
2103 //        else if( EbmlId( *l ) == KaxCodecDownloadURL::ClassInfos.GlobalId )
2104 //        {
2105 //            KaxCodecDownloadURL &cdurl = *(KaxCodecDownloadURL*)l;
2106
2107 //            tk->psz_codec_download_url = strdup( string( cdurl ).c_str() );
2108 //            msg_Dbg( p_demux, "|   |   |   + Track Codec Info URL=%s", tk->psz_codec_download_url );
2109 //        }
2110 //        else if( EbmlId( *l ) == KaxCodecDecodeAll::ClassInfos.GlobalId )
2111 //        {
2112 //            KaxCodecDecodeAll &cdall = *(KaxCodecDecodeAll*)l;
2113
2114 //            msg_Dbg( p_demux, "|   |   |   + Track Codec Decode All=%u <== UNUSED", uint8( cdall ) );
2115 //        }
2116 //        else if( EbmlId( *l ) == KaxTrackOverlay::ClassInfos.GlobalId )
2117 //        {
2118 //            KaxTrackOverlay &tovr = *(KaxTrackOverlay*)l;
2119
2120 //            msg_Dbg( p_demux, "|   |   |   + Track Overlay=%u <== UNUSED", uint32( tovr ) );
2121 //        }
2122         else  if( MKV_IS_ID( l, KaxTrackVideo ) )
2123         {
2124             EbmlMaster *tkv = static_cast<EbmlMaster*>(l);
2125             unsigned int j;
2126
2127             msg_Dbg( p_demux, "|   |   |   + Track Video" );
2128             tk->f_fps = 0.0;
2129
2130             for( j = 0; j < tkv->ListSize(); j++ )
2131             {
2132                 EbmlElement *l = (*tkv)[j];
2133 //                if( EbmlId( *el4 ) == KaxVideoFlagInterlaced::ClassInfos.GlobalId )
2134 //                {
2135 //                    KaxVideoFlagInterlaced &fint = *(KaxVideoFlagInterlaced*)el4;
2136
2137 //                    msg_Dbg( p_demux, "|   |   |   |   + Track Video Interlaced=%u", uint8( fint ) );
2138 //                }
2139 //                else if( EbmlId( *el4 ) == KaxVideoStereoMode::ClassInfos.GlobalId )
2140 //                {
2141 //                    KaxVideoStereoMode &stereo = *(KaxVideoStereoMode*)el4;
2142
2143 //                    msg_Dbg( p_demux, "|   |   |   |   + Track Video Stereo Mode=%u", uint8( stereo ) );
2144 //                }
2145 //                else
2146                 if( MKV_IS_ID( l, KaxVideoPixelWidth ) )
2147                 {
2148                     KaxVideoPixelWidth &vwidth = *(KaxVideoPixelWidth*)l;
2149
2150                     tk->fmt.video.i_width = uint16( vwidth );
2151                     msg_Dbg( p_demux, "|   |   |   |   + width=%d", uint16( vwidth ) );
2152                 }
2153                 else if( MKV_IS_ID( l, KaxVideoPixelHeight ) )
2154                 {
2155                     KaxVideoPixelWidth &vheight = *(KaxVideoPixelWidth*)l;
2156
2157                     tk->fmt.video.i_height = uint16( vheight );
2158                     msg_Dbg( p_demux, "|   |   |   |   + height=%d", uint16( vheight ) );
2159                 }
2160                 else if( MKV_IS_ID( l, KaxVideoDisplayWidth ) )
2161                 {
2162                     KaxVideoDisplayWidth &vwidth = *(KaxVideoDisplayWidth*)l;
2163
2164                     tk->fmt.video.i_visible_width = uint16( vwidth );
2165                     msg_Dbg( p_demux, "|   |   |   |   + display width=%d", uint16( vwidth ) );
2166                 }
2167                 else if( MKV_IS_ID( l, KaxVideoDisplayHeight ) )
2168                 {
2169                     KaxVideoDisplayWidth &vheight = *(KaxVideoDisplayWidth*)l;
2170
2171                     tk->fmt.video.i_visible_height = uint16( vheight );
2172                     msg_Dbg( p_demux, "|   |   |   |   + display height=%d", uint16( vheight ) );
2173                 }
2174                 else if( MKV_IS_ID( l, KaxVideoFrameRate ) )
2175                 {
2176                     KaxVideoFrameRate &vfps = *(KaxVideoFrameRate*)l;
2177
2178                     tk->f_fps = float( vfps );
2179                     msg_Dbg( p_demux, "   |   |   |   + fps=%f", float( vfps ) );
2180                 }
2181 //                else if( EbmlId( *l ) == KaxVideoDisplayUnit::ClassInfos.GlobalId )
2182 //                {
2183 //                     KaxVideoDisplayUnit &vdmode = *(KaxVideoDisplayUnit*)l;
2184
2185 //                    msg_Dbg( p_demux, "|   |   |   |   + Track Video Display Unit=%s",
2186 //                             uint8( vdmode ) == 0 ? "pixels" : ( uint8( vdmode ) == 1 ? "centimeters": "inches" ) );
2187 //                }
2188 //                else if( EbmlId( *l ) == KaxVideoAspectRatio::ClassInfos.GlobalId )
2189 //                {
2190 //                    KaxVideoAspectRatio &ratio = *(KaxVideoAspectRatio*)l;
2191
2192 //                    msg_Dbg( p_demux, "   |   |   |   + Track Video Aspect Ratio Type=%u", uint8( ratio ) );
2193 //                }
2194 //                else if( EbmlId( *l ) == KaxVideoGamma::ClassInfos.GlobalId )
2195 //                {
2196 //                    KaxVideoGamma &gamma = *(KaxVideoGamma*)l;
2197
2198 //                    msg_Dbg( p_demux, "   |   |   |   + fps=%f", float( gamma ) );
2199 //                }
2200                 else
2201                 {
2202                     msg_Dbg( p_demux, "|   |   |   |   + Unknown (%s)", typeid(*l).name() );
2203                 }
2204             }
2205         }
2206         else  if( MKV_IS_ID( l, KaxTrackAudio ) )
2207         {
2208             EbmlMaster *tka = static_cast<EbmlMaster*>(l);
2209             unsigned int j;
2210
2211             msg_Dbg( p_demux, "|   |   |   + Track Audio" );
2212
2213             for( j = 0; j < tka->ListSize(); j++ )
2214             {
2215                 EbmlElement *l = (*tka)[j];
2216
2217                 if( MKV_IS_ID( l, KaxAudioSamplingFreq ) )
2218                 {
2219                     KaxAudioSamplingFreq &afreq = *(KaxAudioSamplingFreq*)l;
2220
2221                     tk->fmt.audio.i_rate = (int)float( afreq );
2222                     msg_Dbg( p_demux, "|   |   |   |   + afreq=%d", tk->fmt.audio.i_rate );
2223                 }
2224                 else if( MKV_IS_ID( l, KaxAudioChannels ) )
2225                 {
2226                     KaxAudioChannels &achan = *(KaxAudioChannels*)l;
2227
2228                     tk->fmt.audio.i_channels = uint8( achan );
2229                     msg_Dbg( p_demux, "|   |   |   |   + achan=%u", uint8( achan ) );
2230                 }
2231                 else if( MKV_IS_ID( l, KaxAudioBitDepth ) )
2232                 {
2233                     KaxAudioBitDepth &abits = *(KaxAudioBitDepth*)l;
2234
2235                     tk->fmt.audio.i_bitspersample = uint8( abits );
2236                     msg_Dbg( p_demux, "|   |   |   |   + abits=%u", uint8( abits ) );
2237                 }
2238                 else
2239                 {
2240                     msg_Dbg( p_demux, "|   |   |   |   + Unknown (%s)", typeid(*l).name() );
2241                 }
2242             }
2243         }
2244         else
2245         {
2246             msg_Dbg( p_demux, "|   |   |   + Unknown (%s)",
2247                      typeid(*l).name() );
2248         }
2249     }
2250 }
2251
2252 static void ParseTracks( demux_t *p_demux, EbmlElement *tracks )
2253 {
2254     demux_sys_t *p_sys = p_demux->p_sys;
2255     EbmlElement *el;
2256     EbmlMaster  *m;
2257     unsigned int i;
2258     int i_upper_level = 0;
2259
2260     msg_Dbg( p_demux, "|   + Tracks" );
2261
2262     /* Master elements */
2263     m = static_cast<EbmlMaster *>(tracks);
2264     m->Read( *p_sys->es, tracks->Generic().Context, i_upper_level, el, true );
2265
2266     for( i = 0; i < m->ListSize(); i++ )
2267     {
2268         EbmlElement *l = (*m)[i];
2269
2270         if( MKV_IS_ID( l, KaxTrackEntry ) )
2271         {
2272             ParseTrackEntry( p_demux, static_cast<EbmlMaster *>(l) );
2273         }
2274         else
2275         {
2276             msg_Dbg( p_demux, "|   |   + Unknown (%s)", typeid(*l).name() );
2277         }
2278     }
2279 }
2280
2281 /*****************************************************************************
2282  * ParseInfo:
2283  *****************************************************************************/
2284 static void ParseInfo( demux_t *p_demux, EbmlElement *info )
2285 {
2286     demux_sys_t *p_sys = p_demux->p_sys;
2287     EbmlElement *el;
2288     EbmlMaster  *m;
2289     unsigned int i;
2290     int i_upper_level = 0;
2291
2292     msg_Dbg( p_demux, "|   + Information" );
2293
2294     /* Master elements */
2295     m = static_cast<EbmlMaster *>(info);
2296     m->Read( *p_sys->es, info->Generic().Context, i_upper_level, el, true );
2297
2298     for( i = 0; i < m->ListSize(); i++ )
2299     {
2300         EbmlElement *l = (*m)[i];
2301
2302         if( MKV_IS_ID( l, KaxSegmentUID ) )
2303         {
2304             KaxSegmentUID &uid = *(KaxSegmentUID*)l;
2305
2306             msg_Dbg( p_demux, "|   |   + UID=%d", uint32(uid) );
2307         }
2308         else if( MKV_IS_ID( l, KaxTimecodeScale ) )
2309         {
2310             KaxTimecodeScale &tcs = *(KaxTimecodeScale*)l;
2311
2312             p_sys->i_timescale = uint64(tcs);
2313
2314             msg_Dbg( p_demux, "|   |   + TimecodeScale="I64Fd,
2315                      p_sys->i_timescale );
2316         }
2317         else if( MKV_IS_ID( l, KaxDuration ) )
2318         {
2319             KaxDuration &dur = *(KaxDuration*)l;
2320
2321             p_sys->f_duration = float(dur);
2322
2323             msg_Dbg( p_demux, "|   |   + Duration=%f",
2324                      p_sys->f_duration );
2325         }
2326         else if( MKV_IS_ID( l, KaxMuxingApp ) )
2327         {
2328             KaxMuxingApp &mapp = *(KaxMuxingApp*)l;
2329
2330             p_sys->psz_muxing_application = UTF8ToStr( UTFstring( mapp ) );
2331
2332             msg_Dbg( p_demux, "|   |   + Muxing Application=%s",
2333                      p_sys->psz_muxing_application );
2334         }
2335         else if( MKV_IS_ID( l, KaxWritingApp ) )
2336         {
2337             KaxWritingApp &wapp = *(KaxWritingApp*)l;
2338
2339             p_sys->psz_writing_application = UTF8ToStr( UTFstring( wapp ) );
2340
2341             msg_Dbg( p_demux, "|   |   + Writing Application=%s",
2342                      p_sys->psz_writing_application );
2343         }
2344         else if( MKV_IS_ID( l, KaxSegmentFilename ) )
2345         {
2346             KaxSegmentFilename &sfn = *(KaxSegmentFilename*)l;
2347
2348             p_sys->psz_segment_filename = UTF8ToStr( UTFstring( sfn ) );
2349
2350             msg_Dbg( p_demux, "|   |   + Segment Filename=%s",
2351                      p_sys->psz_segment_filename );
2352         }
2353         else if( MKV_IS_ID( l, KaxTitle ) )
2354         {
2355             KaxTitle &title = *(KaxTitle*)l;
2356
2357             p_sys->psz_title = UTF8ToStr( UTFstring( title ) );
2358
2359             msg_Dbg( p_demux, "|   |   + Title=%s", p_sys->psz_title );
2360         }
2361 #if defined( HAVE_GMTIME_R ) && !defined( SYS_DARWIN )
2362         else if( MKV_IS_ID( l, KaxDateUTC ) )
2363         {
2364             KaxDateUTC &date = *(KaxDateUTC*)l;
2365             time_t i_date;
2366             struct tm tmres;
2367             char   buffer[256];
2368
2369             i_date = date.GetEpochDate();
2370             memset( buffer, 0, 256 );
2371             if( gmtime_r( &i_date, &tmres ) &&
2372                 asctime_r( &tmres, buffer ) )
2373             {
2374                 buffer[strlen( buffer)-1]= '\0';
2375                 p_sys->psz_date_utc = strdup( buffer );
2376                 msg_Dbg( p_demux, "|   |   + Date=%s", p_sys->psz_date_utc );
2377             }
2378         }
2379 #endif
2380         else
2381         {
2382             msg_Dbg( p_demux, "|   |   + Unknown (%s)", typeid(*l).name() );
2383         }
2384     }
2385
2386     p_sys->f_duration = p_sys->f_duration * p_sys->i_timescale / 1000000.0;
2387 }
2388
2389
2390 /*****************************************************************************
2391  * ParseChapterAtom
2392  *****************************************************************************/
2393 static void ParseChapterAtom( demux_t *p_demux, int i_level, EbmlMaster *ca )
2394 {
2395     demux_sys_t *p_sys = p_demux->p_sys;
2396     unsigned int i;
2397     seekpoint_t *sk;
2398
2399     if( p_sys->title == NULL )
2400     {
2401         p_sys->title = vlc_input_title_New();
2402     }
2403     sk = vlc_seekpoint_New();
2404
2405     msg_Dbg( p_demux, "|   |   |   + ChapterAtom (level=%d)", i_level );
2406     for( i = 0; i < ca->ListSize(); i++ )
2407     {
2408         EbmlElement *l = (*ca)[i];
2409
2410         if( MKV_IS_ID( l, KaxChapterUID ) )
2411         {
2412             KaxChapterUID &uid = *(KaxChapterUID*)l;
2413             uint32_t i_uid = uint32( uid );
2414             msg_Dbg( p_demux, "|   |   |   |   + ChapterUID: 0x%x", i_uid );
2415         }
2416         else if( MKV_IS_ID( l, KaxChapterTimeStart ) )
2417         {
2418             KaxChapterTimeStart &start =*(KaxChapterTimeStart*)l;
2419             sk->i_time_offset = uint64( start ) / I64C(1000);
2420
2421             msg_Dbg( p_demux, "|   |   |   |   + ChapterTimeStart: %lld", sk->i_time_offset );
2422         }
2423         else if( MKV_IS_ID( l, KaxChapterTimeEnd ) )
2424         {
2425             KaxChapterTimeEnd &end =*(KaxChapterTimeEnd*)l;
2426             int64_t i_end = uint64( end );
2427
2428             msg_Dbg( p_demux, "|   |   |   |   + ChapterTimeEnd: %lld", i_end );
2429         }
2430         else if( MKV_IS_ID( l, KaxChapterDisplay ) )
2431         {
2432             EbmlMaster *cd = static_cast<EbmlMaster *>(l);
2433             unsigned int j;
2434
2435             msg_Dbg( p_demux, "|   |   |   |   + ChapterDisplay" );
2436             for( j = 0; j < cd->ListSize(); j++ )
2437             {
2438                 EbmlElement *l= (*cd)[j];
2439
2440                 if( MKV_IS_ID( l, KaxChapterString ) )
2441                 {
2442                     KaxChapterString &name =*(KaxChapterString*)l;
2443                     char *psz = UTF8ToStr( UTFstring( name ) );
2444                     sk->psz_name = strdup( psz );
2445                     msg_Dbg( p_demux, "|   |   |   |   |    + ChapterString '%s'", psz );
2446                 }
2447                 else if( MKV_IS_ID( l, KaxChapterLanguage ) )
2448                 {
2449                     KaxChapterLanguage &lang =*(KaxChapterLanguage*)l;
2450                     const char *psz = string( lang ).c_str();
2451
2452                     msg_Dbg( p_demux, "|   |   |   |   |    + ChapterLanguage '%s'", psz );
2453                 }
2454                 else if( MKV_IS_ID( l, KaxChapterCountry ) )
2455                 {
2456                     KaxChapterCountry &ct =*(KaxChapterCountry*)l;
2457                     const char *psz = string( ct ).c_str();
2458
2459                     msg_Dbg( p_demux, "|   |   |   |   |    + ChapterCountry '%s'", psz );
2460                 }
2461             }
2462         }
2463         else if( MKV_IS_ID( l, KaxChapterAtom ) )
2464         {
2465             ParseChapterAtom( p_demux, i_level+1, static_cast<EbmlMaster *>(l) );
2466         }
2467     }
2468     // A start time of '0' is ok. A missing ChapterTime element is ok, too, because '0' is its default value.
2469     p_sys->title->i_seekpoint++;
2470     p_sys->title->seekpoint = (seekpoint_t**)realloc( p_sys->title->seekpoint, p_sys->title->i_seekpoint * sizeof( seekpoint_t* ) );
2471     p_sys->title->seekpoint[p_sys->title->i_seekpoint-1] = sk;
2472 }
2473
2474 /*****************************************************************************
2475  * ParseChapters:
2476  *****************************************************************************/
2477 static void ParseChapters( demux_t *p_demux, EbmlElement *chapters )
2478 {
2479     demux_sys_t *p_sys = p_demux->p_sys;
2480     EbmlElement *el;
2481     EbmlMaster  *m;
2482     unsigned int i;
2483     int i_upper_level = 0;
2484
2485
2486     /* Master elements */
2487     m = static_cast<EbmlMaster *>(chapters);
2488     m->Read( *p_sys->es, chapters->Generic().Context, i_upper_level, el, true );
2489
2490     for( i = 0; i < m->ListSize(); i++ )
2491     {
2492         EbmlElement *l = (*m)[i];
2493
2494         if( MKV_IS_ID( l, KaxEditionEntry ) )
2495         {
2496             EbmlMaster *E = static_cast<EbmlMaster *>(l );
2497             unsigned int j;
2498             msg_Dbg( p_demux, "|   |   + EditionEntry" );
2499             for( j = 0; j < E->ListSize(); j++ )
2500             {
2501                 EbmlElement *l = (*E)[j];
2502
2503                 if( MKV_IS_ID( l, KaxChapterAtom ) )
2504                 {
2505                     ParseChapterAtom( p_demux, 0, static_cast<EbmlMaster *>(l) );
2506                 }
2507                 else
2508                 {
2509                     msg_Dbg( p_demux, "|   |   |   + Unknown (%s)", typeid(*l).name() );
2510                 }
2511             }
2512         }
2513         else
2514         {
2515             msg_Dbg( p_demux, "|   |   + Unknown (%s)", typeid(*l).name() );
2516         }
2517     }
2518 }
2519
2520 /*****************************************************************************
2521  * InformationCreate:
2522  *****************************************************************************/
2523 static void InformationCreate( demux_t *p_demux )
2524 {
2525     demux_sys_t *p_sys = p_demux->p_sys;
2526     int         i_track;
2527
2528     p_sys->meta = vlc_meta_New();
2529
2530     if( p_sys->psz_title )
2531     {
2532         vlc_meta_Add( p_sys->meta, VLC_META_TITLE, p_sys->psz_title );
2533     }
2534     if( p_sys->psz_date_utc )
2535     {
2536         vlc_meta_Add( p_sys->meta, VLC_META_DATE, p_sys->psz_date_utc );
2537     }
2538     if( p_sys->psz_segment_filename )
2539     {
2540         vlc_meta_Add( p_sys->meta, _("Segment filename"), p_sys->psz_segment_filename );
2541     }
2542     if( p_sys->psz_muxing_application )
2543     {
2544         vlc_meta_Add( p_sys->meta, _("Muxing application"), p_sys->psz_muxing_application );
2545     }
2546     if( p_sys->psz_writing_application )
2547     {
2548         vlc_meta_Add( p_sys->meta, _("Writing application"), p_sys->psz_writing_application );
2549     }
2550
2551     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
2552     {
2553         mkv_track_t *tk = &p_sys->track[i_track];
2554         vlc_meta_t *mtk = vlc_meta_New();
2555
2556         p_sys->meta->track = (vlc_meta_t**)realloc( p_sys->meta->track,
2557                                                     sizeof( vlc_meta_t * ) * ( p_sys->meta->i_track + 1 ) );
2558         p_sys->meta->track[p_sys->meta->i_track++] = mtk;
2559
2560         if( tk->fmt.psz_description )
2561         {
2562             vlc_meta_Add( p_sys->meta, VLC_META_DESCRIPTION, tk->fmt.psz_description );
2563         }
2564         if( tk->psz_codec_name )
2565         {
2566             vlc_meta_Add( p_sys->meta, VLC_META_CODEC_NAME, tk->psz_codec_name );
2567         }
2568         if( tk->psz_codec_settings )
2569         {
2570             vlc_meta_Add( p_sys->meta, VLC_META_SETTING, tk->psz_codec_settings );
2571         }
2572         if( tk->psz_codec_info_url )
2573         {
2574             vlc_meta_Add( p_sys->meta, VLC_META_CODEC_DESCRIPTION, tk->psz_codec_info_url );
2575         }
2576         if( tk->psz_codec_download_url )
2577         {
2578             vlc_meta_Add( p_sys->meta, VLC_META_URL, tk->psz_codec_download_url );
2579         }
2580     }
2581
2582     if( p_sys->i_tags_position >= 0 )
2583     {
2584         vlc_bool_t b_seekable;
2585
2586         stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b_seekable );
2587         if( b_seekable )
2588         {
2589             LoadTags( p_demux );
2590         }
2591     }
2592 }
2593
2594
2595 /*****************************************************************************
2596  * Divers
2597  *****************************************************************************/
2598
2599 static void IndexAppendCluster( demux_t *p_demux, KaxCluster *cluster )
2600 {
2601     demux_sys_t *p_sys = p_demux->p_sys;
2602
2603 #define idx p_sys->index[p_sys->i_index]
2604     idx.i_track       = -1;
2605     idx.i_block_number= -1;
2606     idx.i_position    = cluster->GetElementPosition();
2607     idx.i_time        = -1;
2608     idx.b_key         = VLC_TRUE;
2609
2610     p_sys->i_index++;
2611     if( p_sys->i_index >= p_sys->i_index_max )
2612     {
2613         p_sys->i_index_max += 1024;
2614         p_sys->index = (mkv_index_t*)realloc( p_sys->index, sizeof( mkv_index_t ) * p_sys->i_index_max );
2615     }
2616 #undef idx
2617 }
2618
2619 static char * UTF8ToStr( const UTFstring &u )
2620 {
2621     int     i_src;
2622     const wchar_t *src;
2623     char *dst, *p;
2624
2625     i_src = u.length();
2626     src   = u.c_str();
2627
2628     p = dst = (char*)malloc( i_src + 1);
2629     while( i_src > 0 )
2630     {
2631         if( *src < 255 )
2632         {
2633             *p++ = (char)*src;
2634         }
2635         else
2636         {
2637             *p++ = '?';
2638         }
2639         src++;
2640         i_src--;
2641     }
2642     *p++= '\0';
2643
2644     return dst;
2645 }
2646