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