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