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