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