* mkv: avoid seeking at the same place (was sooooo slow 'cause of
[vlc.git] / modules / demux / mkv.cpp
1 /*****************************************************************************
2  * mkv.cpp : matroska demuxer
3  *****************************************************************************
4  * Copyright (C) 2001 VideoLAN
5  * $Id: mkv.cpp,v 1.7 2003/06/24 00:33:39 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     /* Initialize access plug-in structures. */
542     if( p_input->i_mtu == 0 )
543     {
544         /* Improve speed. */
545         p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
546     }
547
548     /* Set the demux function */
549     p_input->pf_demux = Demux;
550
551     /* peek the begining */
552     if( input_Peek( p_input, &p_peek, 4 ) < 4 )
553     {
554         msg_Warn( p_input, "cannot peek" );
555         return VLC_EGENERIC;
556     }
557
558     /* is a valid file */
559     if( p_peek[0] != 0x1a || p_peek[1] != 0x45 || p_peek[2] != 0xdf || p_peek[3] != 0xa3 )
560     {
561         msg_Warn( p_input, "matroska module discarded (invalid header)" );
562         return VLC_EGENERIC;
563     }
564
565     p_input->p_demux_data = p_sys = (demux_sys_t*)malloc( sizeof( demux_sys_t ) );
566     memset( p_sys, 0, sizeof( demux_sys_t ) );
567
568     p_sys->in = new vlc_stream_io_callback( p_input );
569     p_sys->es = new EbmlStream( *p_sys->in );
570     p_sys->f_duration   = -1;
571     p_sys->i_timescale     = MKVD_TIMECODESCALE;
572     p_sys->i_track      = 0;
573     p_sys->track        = (mkv_track_t*)malloc( sizeof( mkv_track_t ) );
574     p_sys->i_pts   = 0;
575     p_sys->i_cues_position = -1;
576     p_sys->i_chapters_position = -1;
577
578     p_sys->b_cues       = VLC_FALSE;
579     p_sys->i_index      = 0;
580     p_sys->i_index_max  = 1024;
581     p_sys->index        = (mkv_index_t*)malloc( sizeof( mkv_index_t ) * p_sys->i_index_max );
582
583     if( p_sys->es == NULL )
584     {
585         msg_Err( p_input, "failed to create EbmlStream" );
586         delete p_sys->in;
587         free( p_sys );
588         return VLC_EGENERIC;
589     }
590     /* Find the EbmlHead element */
591     el = p_sys->es->FindNextID(EbmlHead::ClassInfos, 0xFFFFFFFFL);
592     if( el == NULL )
593     {
594         msg_Err( p_input, "cannot find EbmlHead" );
595         goto error;
596     }
597     msg_Dbg( p_input, "EbmlHead" );
598     /* skip it */
599     el->SkipData( *p_sys->es, el->Generic().Context );
600     delete el;
601
602     /* Find a segment */
603     el = p_sys->es->FindNextID( KaxSegment::ClassInfos, 0xFFFFFFFFL);
604     if( el == NULL )
605     {
606         msg_Err( p_input, "cannot find KaxSegment" );
607         goto error;
608     }
609     msg_Dbg( p_input, "+ Segment" );
610     p_sys->segment = (KaxSegment*)el;
611     p_sys->cluster = NULL;
612
613     p_sys->ep = new EbmlParser( p_sys->es, el );
614
615     while( ( el1 = p_sys->ep->Get() ) != NULL )
616     {
617         if( EbmlId( *el1 ) == KaxInfo::ClassInfos.GlobalId )
618         {
619             msg_Dbg( p_input, "|   + Informations" );
620
621             p_sys->ep->Down();
622             while( ( el2 = p_sys->ep->Get() ) != NULL )
623             {
624                 if( EbmlId( *el2 ) == KaxTimecodeScale::ClassInfos.GlobalId )
625                 {
626                     KaxTimecodeScale &tcs = *(KaxTimecodeScale*)el2;
627
628                     tcs.ReadData( p_sys->es->I_O() );
629                     p_sys->i_timescale = uint64(tcs);
630
631                     msg_Dbg( p_input, "|   |   + TimecodeScale=%lld", p_sys->i_timescale );
632                 }
633                 else if( EbmlId( *el2 ) == KaxDuration::ClassInfos.GlobalId )
634                 {
635                     KaxDuration &dur = *(KaxDuration*)el2;
636
637                     dur.ReadData( p_sys->es->I_O() );
638                     p_sys->f_duration = float(dur);
639
640                     msg_Dbg( p_input, "|   |   + Duration=%f", p_sys->f_duration );
641                 }
642                 else
643                 {
644                     msg_Dbg( p_input, "|   |   + Unknow (%s)", typeid(*el2).name() );
645                 }
646             }
647             p_sys->ep->Up();
648         }
649         else if( EbmlId( *el1 ) == KaxTracks::ClassInfos.GlobalId )
650         {
651             msg_Dbg( p_input, "|   + Tracks" );
652
653             p_sys->ep->Down();
654             while( ( el2 = p_sys->ep->Get() ) != NULL )
655             {
656                 if( EbmlId( *el2 ) == KaxTrackEntry::ClassInfos.GlobalId )
657                 {
658                     msg_Dbg( p_input, "|   |   + Track Entry" );
659
660                     p_sys->i_track++;
661                     p_sys->track = (mkv_track_t*)realloc( p_sys->track, sizeof( mkv_track_t ) * (p_sys->i_track + 1 ) );
662 #define tk  p_sys->track[p_sys->i_track - 1]
663                     memset( &tk, 0, sizeof( mkv_track_t ) );
664                     tk.i_cat = UNKNOWN_ES;
665                     tk.b_default = VLC_FALSE;
666                     tk.i_number = p_sys->i_track - 1;
667                     tk.i_extra_data = 0;
668                     tk.p_extra_data = NULL;
669                     tk.i_codec = 0;
670                     tk.psz_codec = NULL;
671                     tk.psz_language = NULL;
672                     tk.i_default_duration = 0;
673
674                     tk.b_inited = VLC_FALSE;
675                     tk.i_data_init = 0;
676                     tk.p_data_init = NULL;
677
678                     p_sys->ep->Down();
679
680                     while( ( el3 = p_sys->ep->Get() ) != NULL )
681                     {
682                         if( EbmlId( *el3 ) == KaxTrackNumber::ClassInfos.GlobalId )
683                         {
684                             KaxTrackNumber &tnum = *(KaxTrackNumber*)el3;
685                             tnum.ReadData( p_sys->es->I_O() );
686
687                             tk.i_number = uint32( tnum );
688                             msg_Dbg( p_input, "|   |   |   + Track Number=%u", uint32( tnum ) );
689                         }
690                         else  if( EbmlId( *el3 ) == KaxTrackUID::ClassInfos.GlobalId )
691                         {
692                             KaxTrackUID &tuid = *(KaxTrackUID*)el3;
693                             tuid.ReadData( p_sys->es->I_O() );
694
695                             msg_Dbg( p_input, "|   |   |   + Track UID=%u", uint32( tuid ) );
696                         }
697                         else  if( EbmlId( *el3 ) == KaxTrackDefaultDuration::ClassInfos.GlobalId )
698                         {
699                             KaxTrackDefaultDuration &defd = *(KaxTrackDefaultDuration*)el3;
700                             defd.ReadData( p_sys->es->I_O() );
701
702                             tk.i_default_duration = uint64(defd);
703                             msg_Dbg( p_input, "|   |   |   + Track Default Duration=%lld", uint64(defd) );
704                         }
705                         else  if( EbmlId( *el3 ) == KaxTrackType::ClassInfos.GlobalId )
706                         {
707                             char *psz_type;
708                             KaxTrackType &ttype = *(KaxTrackType*)el3;
709                             ttype.ReadData( p_sys->es->I_O() );
710                             switch( uint8(ttype) )
711                             {
712                                 case track_audio:
713                                     psz_type = "audio";
714                                     tk.i_cat = AUDIO_ES;
715                                     break;
716                                 case track_video:
717                                     psz_type = "video";
718                                     tk.i_cat = VIDEO_ES;
719                                     break;
720                                 case track_subtitle:
721                                     psz_type = "subtitle";
722                                     tk.i_cat = SPU_ES;
723                                     break;
724                                 default:
725                                     psz_type = "unknown";
726                                     tk.i_cat = UNKNOWN_ES;
727                                     break;
728                             }
729
730                             msg_Dbg( p_input, "|   |   |   + Track Type=%s", psz_type );
731                         }
732                         else  if( EbmlId( *el3 ) == KaxTrackAudio::ClassInfos.GlobalId )
733                         {
734                             msg_Dbg( p_input, "|   |   |   + Track Audio" );
735                             tk.i_channels = 0;
736                             tk.i_samplerate = 0;
737                             tk.i_bitspersample = 0;
738
739                             p_sys->ep->Down();
740
741                             while( ( el4 = p_sys->ep->Get() ) != NULL )
742                             {
743                                 if( EbmlId( *el4 ) == KaxAudioSamplingFreq::ClassInfos.GlobalId )
744                                 {
745                                     KaxAudioSamplingFreq &afreq = *(KaxAudioSamplingFreq*)el4;
746                                     afreq.ReadData( p_sys->es->I_O() );
747
748                                     tk.i_samplerate = (int)float( afreq );
749                                     msg_Dbg( p_input, "|   |   |   |   + afreq=%d", tk.i_samplerate );
750                                 }
751                                 else if( EbmlId( *el4 ) == KaxAudioChannels::ClassInfos.GlobalId )
752                                 {
753                                     KaxAudioChannels &achan = *(KaxAudioChannels*)el4;
754                                     achan.ReadData( p_sys->es->I_O() );
755
756                                     tk.i_channels = uint8( achan );
757                                     msg_Dbg( p_input, "|   |   |   |   + achan=%u", uint8( achan ) );
758                                 }
759                                 else if( EbmlId( *el4 ) == KaxAudioBitDepth::ClassInfos.GlobalId )
760                                 {
761                                     KaxAudioBitDepth &abits = *(KaxAudioBitDepth*)el4;
762                                     abits.ReadData( p_sys->es->I_O() );
763
764                                     tk.i_bitspersample = uint8( abits );
765                                     msg_Dbg( p_input, "|   |   |   |   + abits=%u", uint8( abits ) );
766                                 }
767                                 else
768                                 {
769                                     msg_Dbg( p_input, "|   |   |   |   + Unknow (%s)", typeid(*el4).name() );
770                                 }
771                             }
772                             p_sys->ep->Up();
773                         }
774                         else  if( EbmlId( *el3 ) == KaxTrackVideo::ClassInfos.GlobalId )
775                         {
776                             msg_Dbg( p_input, "|   |   |   + Track Video" );
777                             tk.i_width  = 0;
778                             tk.i_height = 0;
779                             tk.i_display_width  = 0;
780                             tk.i_display_height = 0;
781                             tk.f_fps = 0.0;
782
783                             p_sys->ep->Down();
784
785                             while( ( el4 = p_sys->ep->Get() ) != NULL )
786                             {
787                                 if( EbmlId( *el4 ) == KaxVideoPixelWidth::ClassInfos.GlobalId )
788                                 {
789                                     KaxVideoPixelWidth &vwidth = *(KaxVideoPixelWidth*)el4;
790                                     vwidth.ReadData( p_sys->es->I_O() );
791
792                                     tk.i_width = uint16( vwidth );
793                                     msg_Dbg( p_input, "|   |   |   |   + width=%d", uint16( vwidth ) );
794                                 }
795                                 else if( EbmlId( *el4 ) == KaxVideoPixelHeight::ClassInfos.GlobalId )
796                                 {
797                                     KaxVideoPixelWidth &vheight = *(KaxVideoPixelWidth*)el4;
798                                     vheight.ReadData( p_sys->es->I_O() );
799
800                                     tk.i_height = uint16( vheight );
801                                     msg_Dbg( p_input, "|   |   |   |   + height=%d", uint16( vheight ) );
802                                 }
803                                 else if( EbmlId( *el4 ) == KaxVideoDisplayWidth::ClassInfos.GlobalId )
804                                 {
805                                     KaxVideoDisplayWidth &vwidth = *(KaxVideoDisplayWidth*)el4;
806                                     vwidth.ReadData( p_sys->es->I_O() );
807
808                                     tk.i_display_width = uint16( vwidth );
809                                     msg_Dbg( p_input, "|   |   |   |   + display width=%d", uint16( vwidth ) );
810                                 }
811                                 else if( EbmlId( *el4 ) == KaxVideoDisplayHeight::ClassInfos.GlobalId )
812                                 {
813                                     KaxVideoDisplayWidth &vheight = *(KaxVideoDisplayWidth*)el4;
814                                     vheight.ReadData( p_sys->es->I_O() );
815
816                                     tk.i_display_height = uint16( vheight );
817                                     msg_Dbg( p_input, "|   |   |   |   + display height=%d", uint16( vheight ) );
818                                 }
819                                 else if( EbmlId( *el4 ) == KaxVideoFrameRate::ClassInfos.GlobalId )
820                                 {
821                                     KaxVideoFrameRate &vfps = *(KaxVideoFrameRate*)el4;
822                                     vfps.ReadData( p_sys->es->I_O() );
823
824                                     tk.f_fps = float( vfps );
825                                     msg_Dbg( p_input, "   |   |   |   + fps=%f", float( vfps ) );
826                                 }
827                                 else
828                                 {
829                                     msg_Dbg( p_input, "|   |   |   |   + Unknow (%s)", typeid(*el4).name() );
830                                 }
831                             }
832                             p_sys->ep->Up();
833                         }
834                         else  if( EbmlId( *el3 ) == KaxCodecID::ClassInfos.GlobalId )
835                         {
836                             KaxCodecID &codecid = *(KaxCodecID*)el3;
837                             codecid.ReadData( p_sys->es->I_O() );
838
839                             tk.psz_codec = strdup( string( codecid ).c_str() );
840                             msg_Dbg( p_input, "|   |   |   + Track CodecId=%s", string( codecid ).c_str() );
841                         }
842                         else  if( EbmlId( *el3 ) == KaxCodecPrivate::ClassInfos.GlobalId )
843                         {
844                             KaxCodecPrivate &cpriv = *(KaxCodecPrivate*)el3;
845                             cpriv.ReadData( p_sys->es->I_O() );
846
847                             tk.i_extra_data = cpriv.GetSize();
848                             if( tk.i_extra_data > 0 )
849                             {
850                                 tk.p_extra_data = (uint8_t*)malloc( tk.i_extra_data );
851                                 memcpy( tk.p_extra_data, cpriv.GetBuffer(), tk.i_extra_data );
852                             }
853                             msg_Dbg( p_input, "|   |   |   + Track CodecPrivate size=%lld", cpriv.GetSize() );
854                         }
855                         else  if( EbmlId( *el3 ) == KaxTrackFlagDefault::ClassInfos.GlobalId )
856                         {
857                             KaxTrackFlagDefault &fdef = *(KaxTrackFlagDefault*)el3;
858                             fdef.ReadData( p_sys->es->I_O() );
859
860                             tk.b_default = uint32( fdef );
861                             msg_Dbg( p_input, "|   |   |   + Track Default=%u", uint32( fdef )  );
862                         }
863                         else  if( EbmlId( *el3 ) == KaxTrackLanguage::ClassInfos.GlobalId )
864                         {
865                             KaxTrackLanguage &lang = *(KaxTrackLanguage*)el3;
866
867                             lang.ReadData( p_sys->es->I_O() );
868
869                             tk.psz_language = strdup( string( lang ).c_str() );
870                             msg_Dbg( p_input, "|   |   |   + Track Language=`%s'", string( lang ).c_str() );
871                         }
872                         else  if( EbmlId( *el3 ) == KaxTrackFlagLacing::ClassInfos.GlobalId )
873                         {
874                             KaxTrackFlagLacing &lac = *(KaxTrackFlagLacing*)el3;
875                             lac.ReadData( p_sys->es->I_O() );
876
877                             msg_Dbg( p_input, "|   |   |   + Track Lacing=%d", uint32( lac ) );
878                         }
879                         else  if( EbmlId( *el3 ) == KaxTrackMinCache::ClassInfos.GlobalId )
880                         {
881                             KaxTrackMinCache &cmin = *(KaxTrackMinCache*)el3;
882                             cmin.ReadData( p_sys->es->I_O() );
883
884                             msg_Dbg( p_input, "|   |   |   + Track MinCache=%d", uint32( cmin ) );
885                         }
886                         else  if( EbmlId( *el3 ) == KaxTrackMaxCache::ClassInfos.GlobalId )
887                         {
888                             KaxTrackMaxCache &cmax = *(KaxTrackMaxCache*)el3;
889                             cmax.ReadData( p_sys->es->I_O() );
890
891                             msg_Dbg( p_input, "|   |   |   + Track MaxCache=%d", uint32( cmax ) );
892                         }
893                         else
894                         {
895                             msg_Dbg( p_input, "|   |   |   + Unknow (%s)", typeid(*el3).name() );
896                         }
897                     }
898                     p_sys->ep->Up();
899                 }
900                 else
901                 {
902                     msg_Dbg( p_input, "|   |   + Unknow (%s)", typeid(*el2).name() );
903                 }
904 #undef tk
905             }
906             p_sys->ep->Up();
907         }
908         else if( EbmlId( *el1 ) == KaxSeekHead::ClassInfos.GlobalId )
909         {
910             msg_Dbg( p_input, "|   + Seek head" );
911             p_sys->ep->Down();
912             while( ( el = p_sys->ep->Get() ) != NULL )
913             {
914                 if( EbmlId( *el ) == KaxSeek::ClassInfos.GlobalId )
915                 {
916                     EbmlId id = EbmlVoid::ClassInfos.GlobalId;
917                     int64_t i_pos = -1;
918
919                     //msg_Dbg( p_input, "|   |   + Seek" );
920                     p_sys->ep->Down();
921                     while( ( el = p_sys->ep->Get() ) != NULL )
922                     {
923                         if( EbmlId( *el ) == KaxSeekID::ClassInfos.GlobalId )
924                         {
925                             KaxSeekID &sid = *(KaxSeekID*)el;
926
927                             sid.ReadData( p_sys->es->I_O() );
928
929                             id = EbmlId( sid.GetBuffer(), sid.GetSize() );
930                         }
931                         else  if( EbmlId( *el ) == KaxSeekPosition::ClassInfos.GlobalId )
932                         {
933                             KaxSeekPosition &spos = *(KaxSeekPosition*)el;
934
935                             spos.ReadData( p_sys->es->I_O() );
936
937                             i_pos = uint64( spos );
938                         }
939                         else
940                         {
941                             msg_Dbg( p_input, "|   |   |   + Unknow (%s)", typeid(*el).name() );
942                         }
943                     }
944                     p_sys->ep->Up();
945
946                     if( i_pos >= 0 )
947                     {
948                         if( id == KaxCues::ClassInfos.GlobalId )
949                         {
950                             msg_Dbg( p_input, "|   |   |   = cues at %lld", i_pos );
951                             p_sys->i_cues_position = p_sys->segment->GetGlobalPosition( i_pos );
952                         }
953                         else if( id == KaxChapters::ClassInfos.GlobalId )
954                         {
955                             msg_Dbg( p_input, "|   |   |   = chapters at %lld", i_pos );
956                             p_sys->i_chapters_position = p_sys->segment->GetGlobalPosition( i_pos );
957                         }
958                     }
959                 }
960                 else
961                 {
962                     msg_Dbg( p_input, "|   |   + Unknow (%s)", typeid(*el).name() );
963                 }
964             }
965             p_sys->ep->Up();
966         }
967         else if( EbmlId( *el1 ) == KaxCues::ClassInfos.GlobalId )
968         {
969             msg_Dbg( p_input, "|   + Cues" );
970         }
971         else if( EbmlId( *el1 ) == KaxCluster::ClassInfos.GlobalId )
972         {
973             msg_Dbg( p_input, "|   + Cluster" );
974
975             p_sys->cluster = (KaxCluster*)el1;
976
977             p_sys->ep->Down();
978             /* stop parsing the stream */
979             break;
980         }
981         else if( EbmlId( *el1 ) == KaxAttachements::ClassInfos.GlobalId )
982         {
983             msg_Dbg( p_input, "|   + Attachements FIXME TODO (but probably never supported)" );
984         }
985         else if( EbmlId( *el1 ) == KaxChapters::ClassInfos.GlobalId )
986         {
987             msg_Dbg( p_input, "|   + Chapters FIXME TODO" );
988         }
989         else if( EbmlId( *el1 ) == KaxTag::ClassInfos.GlobalId )
990         {
991             msg_Dbg( p_input, "|   + Tags FIXME TODO" );
992         }
993         else
994         {
995             msg_Dbg( p_input, "|   + Unknow (%s)", typeid(*el1).name() );
996         }
997     }
998
999     if( p_sys->cluster == NULL )
1000     {
1001         msg_Err( p_input, "cannot find any cluster, damaged file ?" );
1002         goto error;
1003     }
1004
1005     if( p_sys->i_chapters_position >= 0 )
1006     {
1007         msg_Warn( p_input, "chapters unsupported" );
1008     }
1009
1010 #if 0
1011     if( p_sys->i_cues_position == -1 && config_GetInt( p_input, "mkv-index" ) != 0 )
1012     {
1013         int64_t i_sav_position = p_sys->in->getFilePointer();
1014         EbmlParser *ep;
1015
1016         /* parse to find cues gathering info on all clusters */
1017         msg_Dbg( p_input, "no cues referenced, looking for one" );
1018
1019         /* ugly but like easier */
1020         p_sys->in->setFilePointer( p_sys->cluster->GetElementPosition(), seek_beginning );
1021
1022         ep = new EbmlParser( p_sys->es, p_sys->segment );
1023         while( ( el = ep->Get() ) != NULL )
1024         {
1025             if( EbmlId( *el ) == KaxCluster::ClassInfos.GlobalId )
1026             {
1027                 int64_t i_pos = el->GetElementPosition();
1028
1029                 msg_Dbg( p_input, "found a cluster at %lld", i_pos );
1030             }
1031             else if( EbmlId( *el ) == KaxCues::ClassInfos.GlobalId )
1032             {
1033                 msg_Dbg( p_input, "found a Cues !" );
1034             }
1035         }
1036         delete ep;
1037         msg_Dbg( p_input, "lookind done." );
1038
1039         p_sys->in->setFilePointer( i_sav_position, seek_beginning );
1040     }
1041 #endif
1042
1043     /* *** Load the cue if found *** */
1044     if( p_sys->i_cues_position >= 0 && p_input->stream.b_seekable )
1045     {
1046         int64_t i_sav_position = p_sys->in->getFilePointer();
1047         EbmlParser *ep;
1048         EbmlElement *cues;
1049
1050         msg_Dbg( p_input, "loading cues" );
1051         p_sys->in->setFilePointer( p_sys->i_cues_position, seek_beginning );
1052         cues = p_sys->es->FindNextID( KaxCues::ClassInfos, 0xFFFFFFFFL);
1053
1054         if( cues == NULL )
1055         {
1056             msg_Err( p_input, "cannot load cues (broken seekhead or file)" );
1057         }
1058         else
1059         {
1060             ep = new EbmlParser( p_sys->es, cues );
1061             while( ( el = ep->Get() ) != NULL )
1062             {
1063                 if( EbmlId( *el ) == KaxCuePoint::ClassInfos.GlobalId )
1064                 {
1065 #define idx p_sys->index[p_sys->i_index]
1066
1067                     idx.i_track       = -1;
1068                     idx.i_block_number= -1;
1069                     idx.i_position    = -1;
1070                     idx.i_time        = -1;
1071                     idx.b_key         = VLC_TRUE;
1072
1073                     ep->Down();
1074                     while( ( el = ep->Get() ) != NULL )
1075                     {
1076                         if( EbmlId( *el ) == KaxCueTime::ClassInfos.GlobalId )
1077                         {
1078                             KaxCueTime &ctime = *(KaxCueTime*)el;
1079
1080                             ctime.ReadData( p_sys->es->I_O() );
1081
1082                             idx.i_time = uint64( ctime ) * (mtime_t)1000000000 / p_sys->i_timescale;
1083                         }
1084                         else if( EbmlId( *el ) == KaxCueTrackPositions::ClassInfos.GlobalId )
1085                         {
1086                             ep->Down();
1087                             while( ( el = ep->Get() ) != NULL )
1088                             {
1089                                 if( EbmlId( *el ) == KaxCueTrack::ClassInfos.GlobalId )
1090                                 {
1091                                     KaxCueTrack &ctrack = *(KaxCueTrack*)el;
1092
1093                                     ctrack.ReadData( p_sys->es->I_O() );
1094                                     idx.i_track = uint16( ctrack );
1095                                 }
1096                                 else if( EbmlId( *el ) == KaxCueClusterPosition::ClassInfos.GlobalId )
1097                                 {
1098                                     KaxCueClusterPosition &ccpos = *(KaxCueClusterPosition*)el;
1099
1100                                     ccpos.ReadData( p_sys->es->I_O() );
1101                                     idx.i_position = p_sys->segment->GetGlobalPosition( uint64( ccpos ) );
1102                                 }
1103                                 else if( EbmlId( *el ) == KaxCueBlockNumber::ClassInfos.GlobalId )
1104                                 {
1105                                     KaxCueBlockNumber &cbnum = *(KaxCueBlockNumber*)el;
1106
1107                                     cbnum.ReadData( p_sys->es->I_O() );
1108                                     idx.i_block_number = uint32( cbnum );
1109                                 }
1110                                 else
1111                                 {
1112                                     msg_Dbg( p_input, "         * Unknow (%s)", typeid(*el).name() );
1113                                 }
1114                             }
1115                             ep->Up();
1116                         }
1117                         else
1118                         {
1119                             msg_Dbg( p_input, "     * Unknow (%s)", typeid(*el).name() );
1120                         }
1121                     }
1122                     ep->Up();
1123
1124                     msg_Dbg( p_input, " * added time=%lld pos=%lld track=%d bnum=%d",
1125                              idx.i_time, idx.i_position, idx.i_track, idx.i_block_number );
1126
1127                     p_sys->i_index++;
1128                     if( p_sys->i_index >= p_sys->i_index_max )
1129                     {
1130                         p_sys->i_index_max += 1024;
1131                         p_sys->index = (mkv_index_t*)realloc( p_sys->index, sizeof( mkv_index_t ) * p_sys->i_index_max );
1132                     }
1133 #undef idx
1134                 }
1135                 else
1136                 {
1137                     msg_Dbg( p_input, " * Unknow (%s)", typeid(*el).name() );
1138                 }
1139             }
1140             delete ep;
1141             delete cues;
1142
1143             p_sys->b_cues = VLC_TRUE;
1144         }
1145
1146         msg_Dbg( p_input, "loading cues done." );
1147         p_sys->in->setFilePointer( i_sav_position, seek_beginning );
1148     }
1149
1150     if( !p_sys->b_cues || p_sys->i_index <= 0 )
1151     {
1152         msg_Warn( p_input, "no cues/empty cues found -> seek won't be precise" );
1153
1154         IndexAppendCluster( p_input, p_sys->cluster );
1155
1156         p_sys->b_cues = VLC_FALSE;
1157     }
1158
1159     /* Create one program */
1160     vlc_mutex_lock( &p_input->stream.stream_lock );
1161     if( input_InitStream( p_input, 0 ) == -1)
1162     {
1163         vlc_mutex_unlock( &p_input->stream.stream_lock );
1164         msg_Err( p_input, "cannot init stream" );
1165         goto error;
1166     }
1167     if( input_AddProgram( p_input, 0, 0) == NULL )
1168     {
1169         vlc_mutex_unlock( &p_input->stream.stream_lock );
1170         msg_Err( p_input, "cannot add program" );
1171         goto error;
1172     }
1173     p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
1174     if( p_sys->f_duration > 1001.0 )
1175     {
1176         mtime_t i_duration = (mtime_t)( p_sys->f_duration / 1000.0 );
1177         p_input->stream.i_mux_rate = p_input->stream.p_selected_area->i_size / 50 / i_duration;
1178     }
1179     else
1180     {
1181         p_input->stream.i_mux_rate = 0;
1182     }
1183     vlc_mutex_unlock( &p_input->stream.stream_lock );
1184
1185     /* add all es */
1186     msg_Dbg( p_input, "found %d es", p_sys->i_track );
1187     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
1188     {
1189 #define tk  p_sys->track[i_track]
1190         if( tk.i_cat == UNKNOWN_ES )
1191         {
1192             msg_Warn( p_input, "invalid track[%d, n=%d]", i_track, tk.i_number );
1193             tk.p_es = NULL;
1194             continue;
1195         }
1196         tk.p_es = input_AddES( p_input,
1197                                p_input->stream.p_selected_program,
1198                                i_track + 1,
1199                                tk.i_cat,
1200                                tk.psz_language, 0 );
1201         if( !strcmp( tk.psz_codec, "V_MS/VFW/FOURCC" ) )
1202         {
1203             if( tk.i_extra_data < (int)sizeof( BITMAPINFOHEADER ) )
1204             {
1205                 msg_Err( p_input, "missing/invalid BITMAPINFOHEADER" );
1206                 tk.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1207             }
1208             else
1209             {
1210                 BITMAPINFOHEADER *p_bih = (BITMAPINFOHEADER*)tk.p_extra_data;
1211
1212                 p_bih->biSize           = GetDWLE( &p_bih->biSize );
1213                 p_bih->biWidth          = GetDWLE( &p_bih->biWidth );
1214                 p_bih->biHeight         = GetDWLE( &p_bih->biHeight );
1215                 p_bih->biPlanes         = GetWLE( &p_bih->biPlanes );
1216                 p_bih->biBitCount       = GetWLE( &p_bih->biBitCount );
1217                 p_bih->biCompression    = GetFOURCC( &p_bih->biCompression );
1218                 p_bih->biSizeImage      = GetDWLE( &p_bih->biSizeImage );
1219                 p_bih->biXPelsPerMeter  = GetDWLE( &p_bih->biXPelsPerMeter );
1220                 p_bih->biYPelsPerMeter  = GetDWLE( &p_bih->biYPelsPerMeter );
1221                 p_bih->biClrUsed        = GetDWLE( &p_bih->biClrUsed );
1222                 p_bih->biClrImportant   = GetDWLE( &p_bih->biClrImportant );
1223
1224
1225                 tk.i_codec = p_bih->biCompression;
1226                 tk.p_es->p_bitmapinfoheader = p_bih;
1227             }
1228         }
1229         else if( !strcmp( tk.psz_codec, "V_MPEG1" ) ||
1230                  !strcmp( tk.psz_codec, "V_MPEG2" ) )
1231         {
1232             tk.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'v' );
1233         }
1234         else if( !strncmp( tk.psz_codec, "V_MPEG4", 7 ) )
1235         {
1236             BITMAPINFOHEADER *p_bih;
1237
1238             tk.i_extra_data = sizeof( BITMAPINFOHEADER );
1239             tk.p_extra_data = (uint8_t*)malloc( tk.i_extra_data );
1240
1241             p_bih = (BITMAPINFOHEADER*)tk.p_extra_data;
1242             memset( p_bih, 0, sizeof( BITMAPINFOHEADER ) );
1243             p_bih->biSize  = sizeof( BITMAPINFOHEADER );
1244             p_bih->biWidth = tk.i_width;
1245             p_bih->biHeight= tk.i_height;
1246
1247             if( !strcmp( tk.psz_codec, "V_MPEG4/MS/V3" ) )
1248             {
1249                 tk.i_codec = VLC_FOURCC( 'D', 'I', 'V', '3' );
1250             }
1251             else
1252             {
1253                 tk.i_codec = VLC_FOURCC( 'm', 'p', '4', 'v' );
1254             }
1255         }
1256         else if( !strcmp( tk.psz_codec, "A_MS/ACM" ) )
1257         {
1258             if( tk.i_extra_data < (int)sizeof( WAVEFORMATEX ) )
1259             {
1260                 msg_Err( p_input, "missing/invalid WAVEFORMATEX" );
1261                 tk.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1262             }
1263             else
1264             {
1265                 WAVEFORMATEX *p_wf = (WAVEFORMATEX*)tk.p_extra_data;
1266
1267                 p_wf->wFormatTag        = GetWLE( &p_wf->wFormatTag );
1268                 p_wf->nChannels         = GetWLE( &p_wf->nChannels );
1269                 p_wf->nSamplesPerSec    = GetDWLE( &p_wf->nSamplesPerSec );
1270                 p_wf->nAvgBytesPerSec   = GetDWLE( &p_wf->nAvgBytesPerSec );
1271                 p_wf->nBlockAlign       = GetWLE( &p_wf->nBlockAlign );
1272                 p_wf->wBitsPerSample    = GetWLE( &p_wf->wBitsPerSample );
1273                 p_wf->cbSize            = GetWLE( &p_wf->cbSize );
1274
1275                 switch( p_wf->wFormatTag )
1276                 {
1277                     case WAVE_FORMAT_PCM:
1278                         tk.i_codec = VLC_FOURCC( 'a', 'r', 'a', 'w' );
1279                         break;
1280                     case WAVE_FORMAT_ADPCM:
1281                         tk.i_codec = VLC_FOURCC( 'm', 's', 0x00, 0x02 );
1282                         break;
1283                     case WAVE_FORMAT_ALAW:
1284                         tk.i_codec = VLC_FOURCC( 'a', 'l', 'a', 'w' );
1285                         break;
1286                     case WAVE_FORMAT_MULAW:
1287                         tk.i_codec = VLC_FOURCC( 'm', 'l', 'a', 'w' );
1288                         break;
1289                     case WAVE_FORMAT_IMA_ADPCM:
1290                         tk.i_codec = VLC_FOURCC( 'm', 's', 0x00, 0x11 );
1291                         break;
1292                     case WAVE_FORMAT_MPEG:
1293                     case WAVE_FORMAT_MPEGLAYER3:
1294                         tk.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'a' );
1295                         break;
1296                     case WAVE_FORMAT_A52:
1297                         tk.i_codec = VLC_FOURCC( 'a', '5', '2', ' ' );
1298                         break;
1299                     case WAVE_FORMAT_WMA1:
1300                         tk.i_codec = VLC_FOURCC( 'w', 'm', 'a', '1' );
1301                         break;
1302                     case WAVE_FORMAT_WMA2:
1303                         tk.i_codec = VLC_FOURCC( 'w', 'm', 'a', '2' );
1304                         break;
1305                     case WAVE_FORMAT_WMA3:
1306                         tk.i_codec = VLC_FOURCC( 'w', 'm', 'a', '3' );
1307                         break;
1308                     default:
1309                         msg_Err( p_input, "unknown wFormatTag=0x%x", p_wf->wFormatTag );
1310                         tk.i_codec = VLC_FOURCC( 'm', 's', p_wf->wFormatTag >> 8, p_wf->wFormatTag&0xff );
1311                         break;
1312                 }
1313                 tk.p_es->p_waveformatex = p_wf;
1314             }
1315         }
1316         else if( !strcmp( tk.psz_codec, "A_MPEG/L3" ) ||
1317                  !strcmp( tk.psz_codec, "A_MPEG/L2" ) ||
1318                  !strcmp( tk.psz_codec, "A_MPEG/L1" ) )
1319         {
1320             tk.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'a' );
1321         }
1322         else if( !strcmp( tk.psz_codec, "A_AC3" ) )
1323         {
1324             tk.i_codec = VLC_FOURCC( 'a', '5', '2', ' ' );
1325         }
1326         else if( !strcmp( tk.psz_codec, "A_DTS" ) )
1327         {
1328             tk.i_codec = VLC_FOURCC( 'd', 't', 's', ' ' );
1329         }
1330         else if( !strcmp( tk.psz_codec, "A_VORBIS" ) )
1331         {
1332             tk.i_codec = VLC_FOURCC( 'v', 'o', 'r', 'b' );
1333             tk.i_data_init = tk.i_extra_data;
1334             tk.p_data_init = tk.p_extra_data;
1335         }
1336         else if( !strncmp( tk.psz_codec, "A_AAC/MPEG2/", strlen( "A_AAC/MPEG2/" ) ) ||
1337                  !strncmp( tk.psz_codec, "A_AAC/MPEG4/", strlen( "A_AAC/MPEG4/" ) ) )
1338         {
1339             int i_profile, i_srate;
1340             static int i_sample_rates[] =
1341             {
1342                     96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
1343                         16000, 12000, 11025, 8000,  7350,  0,     0,     0
1344             };
1345             WAVEFORMATEX *p_wf;
1346
1347             tk.i_codec = VLC_FOURCC( 'm', 'p', '4', 'a' );
1348             /* create data for faad (MP4DecSpecificDescrTag)*/
1349
1350             if( !strcmp( &tk.psz_codec[12], "MAIN" ) )
1351             {
1352                 i_profile = 0;
1353             }
1354             else if( !strcmp( &tk.psz_codec[12], "LC" ) )
1355             {
1356                 i_profile = 1;
1357             }
1358             else if( !strcmp( &tk.psz_codec[12], "SSR" ) )
1359             {
1360                 i_profile = 2;
1361             }
1362             else
1363             {
1364                 i_profile = 3;
1365             }
1366
1367             for( i_srate = 0; i_srate < 13; i_srate++ )
1368             {
1369                 if( i_sample_rates[i_srate] == tk.i_samplerate )
1370                 {
1371                     break;
1372                 }
1373             }
1374             msg_Dbg( p_input, "profile=%d srate=%d", i_profile, i_srate );
1375
1376             tk.i_extra_data = sizeof( WAVEFORMATEX ) + 2;
1377             tk.p_extra_data = (uint8_t*)malloc( tk.i_extra_data );
1378             p_wf = (WAVEFORMATEX*)tk.p_extra_data;
1379
1380             p_wf->wFormatTag = WAVE_FORMAT_UNKNOWN;
1381             p_wf->nChannels  = tk.i_channels;
1382             p_wf->nSamplesPerSec = tk.i_samplerate;
1383             p_wf->nAvgBytesPerSec = 0;
1384             p_wf->nBlockAlign = 0;
1385             p_wf->wBitsPerSample = 0;
1386             p_wf->cbSize = 2;
1387
1388             tk.p_extra_data[sizeof( WAVEFORMATEX )+ 0] = ((i_profile + 1) << 3) | ((i_srate&0xe) >> 1);
1389             tk.p_extra_data[sizeof( WAVEFORMATEX )+ 1] = ((i_srate & 0x1) << 7) | (tk.i_channels << 3);
1390
1391             tk.p_es->p_waveformatex = p_wf;
1392         }
1393         else if( !strcmp( tk.psz_codec, "A_PCM/INT/BIG" ) ||
1394                  !strcmp( tk.psz_codec, "A_PCM/INT/LIT" ) ||
1395                  !strcmp( tk.psz_codec, "A_PCM/FLOAT/IEEE" ) )
1396         {
1397             WAVEFORMATEX *p_wf;
1398
1399             tk.i_extra_data = sizeof( WAVEFORMATEX );
1400             tk.p_extra_data = (uint8_t*)malloc( tk.i_extra_data );
1401
1402             p_wf = (WAVEFORMATEX*)tk.p_extra_data;
1403
1404             if( !strncmp( &tk.psz_codec[6], "INT", 3 ) )
1405             {
1406                 p_wf->wFormatTag = WAVE_FORMAT_PCM;
1407             }
1408             else
1409             {
1410                 p_wf->wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
1411             }
1412             p_wf->nChannels  = tk.i_channels;
1413             p_wf->nSamplesPerSec = tk.i_samplerate;
1414             p_wf->nAvgBytesPerSec = 0;
1415             p_wf->nBlockAlign = ( tk.i_bitspersample + 7 ) / 8 * tk.i_channels;
1416             p_wf->wBitsPerSample = tk.i_bitspersample;
1417             p_wf->cbSize = 0;
1418
1419             tk.p_es->p_waveformatex = p_wf;
1420
1421             if( !strcmp( tk.psz_codec, "A_PCM/INT/BIG" ) )
1422             {
1423                 tk.i_codec = VLC_FOURCC( 't', 'w', 'o', 's' );
1424             }
1425             else
1426             {
1427                 tk.i_codec = VLC_FOURCC( 'a', 'r', 'a', 'w' );
1428             }
1429         }
1430         else if( !strcmp( tk.psz_codec, "S_TEXT/UTF8" ) )
1431         {
1432             tk.i_codec = VLC_FOURCC( 's', 'u', 'b', 't' );
1433         }
1434         else
1435         {
1436             msg_Err( p_input, "unknow codec id=`%s'", tk.psz_codec );
1437             tk.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1438         }
1439
1440         tk.p_es->i_fourcc = tk.i_codec;
1441 #undef tk
1442     }
1443
1444     /* select track all video, one audio, no spu TODO : improve */
1445     b_audio_selected = VLC_FALSE;
1446     i_audio_channel = 0;
1447     i_spu_channel = 0;
1448     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
1449     {
1450 #define tk  p_sys->track[i_track]
1451         switch( tk.i_cat )
1452         {
1453             case VIDEO_ES:
1454                 vlc_mutex_lock( &p_input->stream.stream_lock );
1455                 input_SelectES( p_input, tk.p_es );
1456                 vlc_mutex_unlock( &p_input->stream.stream_lock );
1457                 break;
1458
1459             case AUDIO_ES:
1460                 if( ( !b_audio_selected && config_GetInt( p_input, "audio-channel" ) < 0 ) ||
1461                     i_audio_channel == config_GetInt( p_input, "audio-channel" ) )
1462                 {
1463                     vlc_mutex_lock( &p_input->stream.stream_lock );
1464                     input_SelectES( p_input, tk.p_es );
1465                     vlc_mutex_unlock( &p_input->stream.stream_lock );
1466
1467                     b_audio_selected = tk.p_es->p_decoder_fifo ? VLC_TRUE : VLC_FALSE;
1468                 }
1469                 i_audio_channel++;
1470                 break;
1471             case SPU_ES:
1472                 if( i_spu_channel == config_GetInt( p_input, "spu-channel" ) )
1473                 {
1474                     vlc_mutex_lock( &p_input->stream.stream_lock );
1475                     input_SelectES( p_input, tk.p_es );
1476                     vlc_mutex_unlock( &p_input->stream.stream_lock );
1477                 }
1478                 i_spu_channel++;
1479                 break;
1480         }
1481 #undef tk
1482     }
1483
1484     if( !b_audio_selected )
1485     {
1486         msg_Warn( p_input, "cannot find/select audio track" );
1487     }
1488
1489     return VLC_SUCCESS;
1490
1491 error:
1492     delete p_sys->es;
1493     delete p_sys->in;
1494     free( p_sys );
1495     return VLC_EGENERIC;
1496 }
1497
1498 /*****************************************************************************
1499  * Deactivate: frees unused data
1500  *****************************************************************************/
1501 static void Deactivate( vlc_object_t *p_this )
1502 {
1503     input_thread_t *p_input = (input_thread_t *)p_this;
1504     demux_sys_t    *p_sys   = p_input->p_demux_data;
1505
1506     int             i_track;
1507
1508     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
1509     {
1510 #define tk  p_sys->track[i_track]
1511         if( tk.psz_codec )
1512         {
1513             free( tk.psz_codec );
1514         }
1515         if( tk.psz_language )
1516         {
1517             free( tk.psz_language );
1518         }
1519 #undef tk
1520     }
1521     free( p_sys->track );
1522
1523     delete p_sys->ep;
1524     delete p_sys->es;
1525     delete p_sys->in;
1526
1527     free( p_sys );
1528 }
1529
1530 static int BlockGet( input_thread_t *p_input, KaxBlock **pp_block, int64_t *pi_ref1, int64_t *pi_ref2, int64_t *pi_duration )
1531 {
1532     demux_sys_t    *p_sys   = p_input->p_demux_data;
1533
1534     *pp_block = NULL;
1535     *pi_ref1  = -1;
1536     *pi_ref2  = -1;
1537
1538     for( ;; )
1539     {
1540         EbmlElement *el;
1541         int         i_level;
1542
1543         if( p_input->b_die )
1544         {
1545             return VLC_EGENERIC;
1546         }
1547
1548         el = p_sys->ep->Get();
1549         i_level = p_sys->ep->GetLevel();
1550
1551         if( el == NULL && *pp_block != NULL )
1552         {
1553             /* update the index */
1554 #define idx p_sys->index[p_sys->i_index - 1]
1555             if( p_sys->i_index > 0 && idx.i_time == -1 )
1556             {
1557                 idx.i_time        = (*pp_block)->GlobalTimecode() * (mtime_t) 1000 / p_sys->i_timescale;
1558                 idx.b_key         = *pi_ref1 == -1 ? VLC_TRUE : VLC_FALSE;
1559             }
1560 #undef idx
1561             return VLC_SUCCESS;
1562         }
1563
1564         if( el == NULL )
1565         {
1566             if( p_sys->ep->GetLevel() > 1 )
1567             {
1568                 p_sys->ep->Up();
1569                 continue;
1570             }
1571             msg_Warn( p_input, "EOF" );
1572             return VLC_EGENERIC;
1573         }
1574
1575         /* do parsing */
1576         if( i_level == 1 )
1577         {
1578             if( EbmlId( *el ) == KaxCluster::ClassInfos.GlobalId )
1579             {
1580                 p_sys->cluster = (KaxCluster*)el;
1581
1582                 /* add it to the index */
1583                 if( p_sys->i_index == 0 ||
1584                     ( p_sys->i_index > 0 && p_sys->index[p_sys->i_index - 1].i_position < p_sys->cluster->GetElementPosition() ) )
1585                 {
1586                     IndexAppendCluster( p_input, p_sys->cluster );
1587                 }
1588
1589                 p_sys->ep->Down();
1590             }
1591             else if( EbmlId( *el ) == KaxCues::ClassInfos.GlobalId )
1592             {
1593                 msg_Warn( p_input, "find KaxCues FIXME" );
1594                 return VLC_EGENERIC;
1595             }
1596             else
1597             {
1598                 msg_Dbg( p_input, "unknown (%s)", typeid( el ).name() );
1599             }
1600         }
1601         else if( i_level == 2 )
1602         {
1603             if( EbmlId( *el ) == KaxClusterTimecode::ClassInfos.GlobalId )
1604             {
1605                 KaxClusterTimecode &ctc = *(KaxClusterTimecode*)el;
1606
1607                 ctc.ReadData( p_sys->es->I_O() );
1608                 p_sys->cluster->InitTimecode( uint64( ctc ), p_sys->i_timescale );
1609             }
1610             else if( EbmlId( *el ) == KaxBlockGroup::ClassInfos.GlobalId )
1611             {
1612                 p_sys->ep->Down();
1613             }
1614         }
1615         else if( i_level == 3 )
1616         {
1617             if( EbmlId( *el ) == KaxBlock::ClassInfos.GlobalId )
1618             {
1619                 *pp_block = (KaxBlock*)el;
1620
1621                 (*pp_block)->ReadData( p_sys->es->I_O() );
1622                 (*pp_block)->SetParent( *p_sys->cluster );
1623
1624                 p_sys->ep->Keep();
1625             }
1626             else if( EbmlId( *el ) == KaxBlockDuration::ClassInfos.GlobalId )
1627             {
1628                 KaxBlockDuration &dur = *(KaxBlockDuration*)el;
1629
1630                 dur.ReadData( p_sys->es->I_O() );
1631                 *pi_duration = uint64( dur );
1632             }
1633             else if( EbmlId( *el ) == KaxReferenceBlock::ClassInfos.GlobalId )
1634             {
1635                 KaxReferenceBlock &ref = *(KaxReferenceBlock*)el;
1636
1637                 ref.ReadData( p_sys->es->I_O() );
1638                 if( *pi_ref1 == -1 )
1639                 {
1640                     *pi_ref1 = int64( ref );
1641                 }
1642                 else
1643                 {
1644                     *pi_ref2 = int64( ref );
1645                 }
1646             }
1647         }
1648         else
1649         {
1650             msg_Err( p_input, "invalid level = %d", i_level );
1651             return VLC_EGENERIC;
1652         }
1653     }
1654 }
1655
1656 static pes_packet_t *MemToPES( input_thread_t *p_input, uint8_t *p_mem, int i_mem )
1657 {
1658     pes_packet_t *p_pes;
1659     data_packet_t *p_data;
1660
1661     if( ( p_pes = input_NewPES( p_input->p_method_data ) ) == NULL )
1662     {
1663         return NULL;
1664     }
1665
1666     p_data = input_NewPacket( p_input->p_method_data, i_mem);
1667
1668     memcpy( p_data->p_payload_start, p_mem, i_mem );
1669     p_data->p_payload_end = p_data->p_payload_start + i_mem;
1670
1671     p_pes->p_first = p_pes->p_last = p_data;
1672     p_pes->i_nb_data = 1;
1673     p_pes->i_pes_size = i_mem;
1674
1675     return p_pes;
1676 }
1677
1678 static void BlockDecode( input_thread_t *p_input, KaxBlock *block, mtime_t i_pts, mtime_t i_duration )
1679 {
1680     demux_sys_t    *p_sys   = p_input->p_demux_data;
1681
1682     int             i_track;
1683     unsigned int    i;
1684
1685 #define tk  p_sys->track[i_track]
1686     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
1687     {
1688         if( tk.i_number == block->TrackNum() )
1689         {
1690             break;
1691         }
1692     }
1693
1694     if( i_track >= p_sys->i_track )
1695     {
1696         msg_Err( p_input, "invalid track number=%d", block->TrackNum() );
1697         return;
1698     }
1699
1700     if( tk.p_es->p_decoder_fifo == NULL )
1701     {
1702         tk.b_inited = VLC_FALSE;
1703         return;
1704     }
1705
1706     /* First send init data */
1707     if( !tk.b_inited && tk.i_data_init > 0 )
1708     {
1709         pes_packet_t *p_init;
1710
1711         msg_Dbg( p_input, "sending header (%d bytes)", tk.i_data_init );
1712
1713         if( tk.i_codec == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
1714         {
1715             int i;
1716             int i_offset = 1;
1717             int i_size[3];
1718
1719             /* XXX hack split the 3 headers */
1720             if( tk.p_data_init[0] != 0x02 )
1721             {
1722                 msg_Err( p_input, "invalid vorbis header" );
1723             }
1724
1725             for( i = 0; i < 2; i++ )
1726             {
1727                 i_size[i] = 0;
1728                 while( i_offset < tk.i_data_init )
1729                 {
1730                     i_size[i] += tk.p_data_init[i_offset];
1731                     if( tk.p_data_init[i_offset++] != 0xff )
1732                     {
1733                         break;
1734                     }
1735                 }
1736             }
1737             i_size[0] = __MIN( i_size[0], tk.i_data_init - i_offset );
1738             i_size[1] = __MIN( i_size[1], tk.i_data_init - i_offset - i_size[0] );
1739             i_size[2] = tk.i_data_init - i_offset - i_size[0] - i_size[1];
1740
1741             p_init = MemToPES( p_input, &tk.p_data_init[i_offset], i_size[0] );
1742             if( p_init )
1743             {
1744                 input_DecodePES( tk.p_es->p_decoder_fifo, p_init );
1745             }
1746             p_init = MemToPES( p_input, &tk.p_data_init[i_offset+i_size[0]], i_size[1] );
1747             if( p_init )
1748             {
1749                 input_DecodePES( tk.p_es->p_decoder_fifo, p_init );
1750             }
1751             p_init = MemToPES( p_input, &tk.p_data_init[i_offset+i_size[0]+i_size[1]], i_size[2] );
1752             if( p_init )
1753             {
1754                 input_DecodePES( tk.p_es->p_decoder_fifo, p_init );
1755             }
1756         }
1757         else
1758         {
1759             p_init = MemToPES( p_input, tk.p_data_init, tk.i_data_init );
1760             if( p_init )
1761             {
1762                 input_DecodePES( tk.p_es->p_decoder_fifo, p_init );
1763             }
1764         }
1765     }
1766     tk.b_inited = VLC_TRUE;
1767
1768
1769     for( i = 0; i < block->NumberFrames(); i++ )
1770     {
1771         pes_packet_t *p_pes;
1772         DataBuffer &data = block->GetBuffer(i);
1773
1774         p_pes = MemToPES( p_input, data.Buffer(), data.Size() );
1775         if( p_pes == NULL )
1776         {
1777             break;
1778         }
1779
1780         p_pes->i_pts = i_pts;
1781         p_pes->i_dts = i_pts;
1782
1783         if( tk.i_cat == SPU_ES )
1784         {
1785             if( i_duration > 0 )
1786             {
1787                 /* FIXME not sure about that */
1788                 p_pes->i_dts += i_duration * 1000;// * (mtime_t) 1000 / p_sys->i_timescale;
1789             }
1790             else
1791             {
1792                 p_pes->i_dts = 0;
1793             }
1794             if( p_pes->p_first && p_pes->i_pes_size > 0 )
1795             {
1796                 p_pes->p_first->p_payload_end[-1] = '\0';
1797             }
1798         }
1799
1800         input_DecodePES( tk.p_es->p_decoder_fifo, p_pes );
1801
1802         /* use time stamp only for first block */
1803         i_pts = 0;
1804     }
1805
1806 #undef tk
1807 }
1808
1809 static void Seek( input_thread_t *p_input, mtime_t i_date, int i_percent)
1810 {
1811     demux_sys_t    *p_sys   = p_input->p_demux_data;
1812
1813     KaxBlock    *block;
1814     int64_t     i_block_duration;
1815     int64_t     i_block_ref1;
1816     int64_t     i_block_ref2;
1817
1818     int         i_index;
1819     int         i_track_skipping;
1820     int         i_track;
1821
1822     msg_Dbg( p_input, "seek request to %lld (%d%%)", i_date, i_percent );
1823     if( i_date < 0 && i_percent < 0 )
1824     {
1825         return;
1826     }
1827
1828     delete p_sys->ep;
1829     p_sys->ep = new EbmlParser( p_sys->es, p_sys->segment );
1830     p_sys->cluster = NULL;
1831
1832     /* seek without index or without date */
1833     if( !p_sys->b_cues || i_date < 0 )
1834     {
1835         int64_t i_pos = i_percent * p_input->stream.p_selected_area->i_size / 100;
1836
1837         msg_Warn( p_input, "imprecise way of seeking" );
1838         for( i_index = 0; i_index < p_sys->i_index; i_index++ )
1839         {
1840             if( p_sys->index[i_index].i_position >= i_pos)
1841             {
1842                 break;
1843             }
1844         }
1845         if( i_index == p_sys->i_index )
1846         {
1847             i_index--;
1848         }
1849
1850         p_sys->in->setFilePointer( p_sys->index[i_index].i_position, seek_beginning );
1851
1852         if( p_sys->index[i_index].i_position < i_pos )
1853         {
1854             EbmlElement *el;
1855
1856             msg_Warn( p_input, "searching for cluster, could take some time" );
1857
1858             /* search a cluster */
1859             while( ( el = p_sys->ep->Get() ) != NULL )
1860             {
1861                 if( EbmlId( *el ) == KaxCluster::ClassInfos.GlobalId )
1862                 {
1863                     KaxCluster *cluster = (KaxCluster*)el;
1864
1865                     /* add it to the index */
1866                     IndexAppendCluster( p_input, cluster );
1867
1868                     if( cluster->GetElementPosition() >= i_pos )
1869                     {
1870                         p_sys->cluster = cluster;
1871                         p_sys->ep->Down();
1872                         break;
1873                     }
1874                 }
1875             }
1876         }
1877     }
1878     else
1879     {
1880         for( i_index = 0; i_index < p_sys->i_index; i_index++ )
1881         {
1882             if( p_sys->index[i_index].i_time >= i_date )
1883             {
1884                 break;
1885             }
1886         }
1887
1888         if( i_index > 0 )
1889         {
1890             i_index--;
1891         }
1892
1893         msg_Dbg( p_input, "seek got %lld (%d%%)",
1894                  p_sys->index[i_index].i_time, (int)(100 * p_sys->index[i_index].i_position /p_input->stream.p_selected_area->i_size ) );
1895
1896         p_sys->in->setFilePointer( p_sys->index[i_index].i_position, seek_beginning );
1897     }
1898
1899     /* now parse until key frame */
1900 #define tk  p_sys->track[i_track]
1901     i_track_skipping = 0;
1902     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
1903     {
1904         if( tk.i_cat == VIDEO_ES )
1905         {
1906             tk.b_search_keyframe = VLC_TRUE;
1907             i_track_skipping++;
1908         }
1909     }
1910
1911     while( i_track_skipping > 0 )
1912     {
1913         if( BlockGet( p_input, &block, &i_block_ref1, &i_block_ref2, &i_block_duration ) )
1914         {
1915             msg_Warn( p_input, "cannot get block EOF?" );
1916
1917             return;
1918         }
1919
1920         p_sys->i_pts = block->GlobalTimecode() * (mtime_t) 1000 / p_sys->i_timescale;
1921
1922         for( i_track = 0; i_track < p_sys->i_track; i_track++ )
1923         {
1924             if( tk.i_number == block->TrackNum() )
1925             {
1926                 break;
1927             }
1928         }
1929
1930         if( i_track < p_sys->i_track )
1931         {
1932             if( tk.i_cat == VIDEO_ES && i_block_ref1 == -1 && tk.b_search_keyframe )
1933             {
1934                 tk.b_search_keyframe = VLC_FALSE;
1935                 i_track_skipping--;
1936             }
1937             if( tk.i_cat == VIDEO_ES && !tk.b_search_keyframe )
1938             {
1939                 BlockDecode( p_input, block, 0, 0 );
1940             }
1941         }
1942
1943         delete block;
1944     }
1945 #undef tk
1946 }
1947
1948 /*****************************************************************************
1949  * Demux: reads and demuxes data packets
1950  *****************************************************************************
1951  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
1952  *****************************************************************************/
1953 static int Demux( input_thread_t * p_input )
1954 {
1955     demux_sys_t    *p_sys   = p_input->p_demux_data;
1956     mtime_t        i_start_pts;
1957     int            i_block_count = 0;
1958
1959     KaxBlock *block;
1960     int64_t i_block_duration;
1961     int64_t i_block_ref1;
1962     int64_t i_block_ref2;
1963
1964     if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT )
1965     {
1966         mtime_t i_duration = (mtime_t)( p_sys->f_duration / 1000 );
1967         mtime_t i_date = -1;
1968         int i_percent  = -1;
1969
1970         if( i_duration > 0 )
1971         {
1972             i_date = (mtime_t)1000000 *
1973                      (mtime_t)i_duration*
1974                      (mtime_t)p_sys->in->getFilePointer() /
1975                      (mtime_t)p_input->stream.p_selected_area->i_size;
1976         }
1977         if( p_input->stream.p_selected_area->i_size > 0 )
1978         {
1979             i_percent = 100 * p_sys->in->getFilePointer() /
1980                             p_input->stream.p_selected_area->i_size;
1981         }
1982
1983         msg_Dbg( p_input, "call Seek" );
1984         Seek( p_input, i_date, i_percent);
1985         msg_Dbg( p_input, "Seek end" );
1986     }
1987
1988     i_start_pts = -1;
1989
1990     for( ;; )
1991     {
1992         mtime_t i_pts;
1993
1994         if( BlockGet( p_input, &block, &i_block_ref1, &i_block_ref2, &i_block_duration ) )
1995         {
1996             msg_Warn( p_input, "cannot get block EOF?" );
1997
1998             return 0;
1999         }
2000
2001         p_sys->i_pts = block->GlobalTimecode() * (mtime_t) 1000 / p_sys->i_timescale;
2002
2003         if( p_sys->i_pts > 0 )
2004         {
2005             input_ClockManageRef( p_input,
2006                                   p_input->stream.p_selected_program,
2007                                   p_sys->i_pts * 9 / 100 );
2008         }
2009
2010         i_pts = input_ClockGetTS( p_input,
2011                                   p_input->stream.p_selected_program,
2012                                   p_sys->i_pts * 9 / 100 );
2013
2014
2015
2016         BlockDecode( p_input, block, i_pts, i_block_duration );
2017
2018         delete block;
2019         i_block_count++;
2020
2021         if( i_start_pts == -1 )
2022         {
2023             i_start_pts = p_sys->i_pts;
2024         }
2025         else if( p_sys->i_pts > i_start_pts + (mtime_t)100000 || i_block_count > 5 )
2026         {
2027             return 1;
2028         }
2029     }
2030 }
2031
2032