]> git.sesse.net Git - vlc/blob - modules/demux/mkv.cpp
mkv.cpp: Enter/Leave on subchapters too
[vlc] / modules / demux / mkv.cpp
1 /*****************************************************************************
2  * mkv.cpp : matroska demuxer
3  *****************************************************************************
4  * Copyright (C) 2003-2004 VideoLAN
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Steve Lhomme <steve.lhomme@free.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include <stdlib.h>                                      /* malloc(), free() */
29
30 #include <vlc/vlc.h>
31
32 #ifdef HAVE_TIME_H
33 #   include <time.h>                                               /* time() */
34 #endif
35
36 #include <vlc/input.h>
37
38 #include <codecs.h>                        /* BITMAPINFOHEADER, WAVEFORMATEX */
39 #include "iso_lang.h"
40 #include "vlc_meta.h"
41
42 #include <iostream>
43 #include <cassert>
44 #include <typeinfo>
45 #include <string>
46 #include <vector>
47 #include <algorithm>
48
49 #ifdef HAVE_DIRENT_H
50 #   include <dirent.h>
51 #endif
52
53 /* libebml and matroska */
54 #include "ebml/EbmlHead.h"
55 #include "ebml/EbmlSubHead.h"
56 #include "ebml/EbmlStream.h"
57 #include "ebml/EbmlContexts.h"
58 #include "ebml/EbmlVoid.h"
59 #include "ebml/EbmlVersion.h"
60 #include "ebml/StdIOCallback.h"
61
62 #include "matroska/KaxAttachments.h"
63 #include "matroska/KaxBlock.h"
64 #include "matroska/KaxBlockData.h"
65 #include "matroska/KaxChapters.h"
66 #include "matroska/KaxCluster.h"
67 #include "matroska/KaxClusterData.h"
68 #include "matroska/KaxContexts.h"
69 #include "matroska/KaxCues.h"
70 #include "matroska/KaxCuesData.h"
71 #include "matroska/KaxInfo.h"
72 #include "matroska/KaxInfoData.h"
73 #include "matroska/KaxSeekHead.h"
74 #include "matroska/KaxSegment.h"
75 #include "matroska/KaxTag.h"
76 #include "matroska/KaxTags.h"
77 #include "matroska/KaxTagMulti.h"
78 #include "matroska/KaxTracks.h"
79 #include "matroska/KaxTrackAudio.h"
80 #include "matroska/KaxTrackVideo.h"
81 #include "matroska/KaxTrackEntryData.h"
82 #include "matroska/KaxContentEncoding.h"
83 #include "matroska/KaxVersion.h"
84
85 #include "ebml/StdIOCallback.h"
86
87 extern "C" {
88    #include "mp4/libmp4.h"
89 }
90 #ifdef HAVE_ZLIB_H
91 #   include <zlib.h>
92 #endif
93
94 #define MATROSKA_COMPRESSION_NONE 0
95 #define MATROSKA_COMPRESSION_ZLIB 1
96
97 #define MKVD_TIMECODESCALE 1000000
98
99 /**
100  * What's between a directory and a filename?
101  */
102 #if defined( WIN32 )
103     #define DIRECTORY_SEPARATOR '\\'
104 #else
105     #define DIRECTORY_SEPARATOR '/'
106 #endif
107
108 using namespace LIBMATROSKA_NAMESPACE;
109 using namespace std;
110
111 /*****************************************************************************
112  * Module descriptor
113  *****************************************************************************/
114 static int  Open ( vlc_object_t * );
115 static void Close( vlc_object_t * );
116
117 vlc_module_begin();
118     set_shortname( _("Matroska") );
119     set_description( _("Matroska stream demuxer" ) );
120     set_capability( "demux2", 50 );
121     set_callbacks( Open, Close );
122     set_category( CAT_INPUT );
123     set_subcategory( SUBCAT_INPUT_DEMUX );
124
125     add_bool( "mkv-use-ordered-chapters", 1, NULL,
126             N_("Ordered chapters"),
127             N_("Play ordered chapters as specified in the segment"), VLC_TRUE );
128
129     add_bool( "mkv-use-chapter-codec", 1, NULL,
130             N_("Chapter codecs"),
131             N_("Use chapter codecs found in the segment"), VLC_TRUE );
132
133     add_bool( "mkv-seek-percent", 0, NULL,
134             N_("Seek based on percent not time"),
135             N_("Seek based on percent not time"), VLC_TRUE );
136
137     add_bool( "mkv-use-dummy", 0, NULL,
138             N_("Dummy Elements"),
139             N_("Read and discard unknown EBML elements (not good for broken files)"), VLC_TRUE );
140
141     add_shortcut( "mka" );
142     add_shortcut( "mkv" );
143 vlc_module_end();
144
145 /*****************************************************************************
146  * Local prototypes
147  *****************************************************************************/
148 #ifdef HAVE_ZLIB_H
149 block_t *block_zlib_decompress( vlc_object_t *p_this, block_t *p_in_block ) {
150     int result, dstsize, n;
151     unsigned char *dst;
152     block_t *p_block;
153     z_stream d_stream;
154
155     d_stream.zalloc = (alloc_func)0;
156     d_stream.zfree = (free_func)0;
157     d_stream.opaque = (voidpf)0;
158     result = inflateInit(&d_stream);
159     if( result != Z_OK )
160     {
161         msg_Dbg( p_this, "inflateInit() failed. Result: %d", result );
162         return NULL;
163     }
164
165     d_stream.next_in = (Bytef *)p_in_block->p_buffer;
166     d_stream.avail_in = p_in_block->i_buffer;
167     n = 0;
168     p_block = block_New( p_this, 0 );
169     dst = NULL;
170     do
171     {
172         n++;
173         p_block = block_Realloc( p_block, 0, n * 1000 );
174         dst = (unsigned char *)p_block->p_buffer;
175         d_stream.next_out = (Bytef *)&dst[(n - 1) * 1000];
176         d_stream.avail_out = 1000;
177         result = inflate(&d_stream, Z_NO_FLUSH);
178         if( ( result != Z_OK ) && ( result != Z_STREAM_END ) )
179         {
180             msg_Dbg( p_this, "Zlib decompression failed. Result: %d", result );
181             return NULL;
182         }
183     }
184     while( ( d_stream.avail_out == 0 ) && ( d_stream.avail_in != 0 ) &&
185            ( result != Z_STREAM_END ) );
186
187     dstsize = d_stream.total_out;
188     inflateEnd( &d_stream );
189
190     p_block = block_Realloc( p_block, 0, dstsize );
191     p_block->i_buffer = dstsize;
192     block_Release( p_in_block );
193
194     return p_block;
195 }
196 #endif
197
198 /**
199  * Helper function to print the mkv parse tree
200  */
201 static void MkvTree( demux_t & demuxer, int i_level, char *psz_format, ... )
202 {
203     va_list args;
204     if( i_level > 9 )
205     {
206         msg_Err( &demuxer, "too deep tree" );
207         return;
208     }
209     va_start( args, psz_format );
210     static char *psz_foo = "|   |   |   |   |   |   |   |   |   |";
211     char *psz_foo2 = (char*)malloc( ( i_level * 4 + 3 + strlen( psz_format ) ) * sizeof(char) );
212     strncpy( psz_foo2, psz_foo, 4 * i_level );
213     psz_foo2[ 4 * i_level ] = '+';
214     psz_foo2[ 4 * i_level + 1 ] = ' ';
215     strcpy( &psz_foo2[ 4 * i_level + 2 ], psz_format );
216     __msg_GenericVa( VLC_OBJECT(&demuxer), VLC_MSG_DBG, "mkv", psz_foo2, args );
217     free( psz_foo2 );
218     va_end( args );
219 }
220     
221 /*****************************************************************************
222  * Stream managment
223  *****************************************************************************/
224 class vlc_stream_io_callback: public IOCallback
225 {
226   private:
227     stream_t       *s;
228     vlc_bool_t     mb_eof;
229
230   public:
231     vlc_stream_io_callback( stream_t * );
232
233     virtual uint32   read            ( void *p_buffer, size_t i_size);
234     virtual void     setFilePointer  ( int64_t i_offset, seek_mode mode = seek_beginning );
235     virtual size_t   write           ( const void *p_buffer, size_t i_size);
236     virtual uint64   getFilePointer  ( void );
237     virtual void     close           ( void );
238 };
239
240 /*****************************************************************************
241  * Ebml Stream parser
242  *****************************************************************************/
243 class EbmlParser
244 {
245   public:
246     EbmlParser( EbmlStream *es, EbmlElement *el_start, demux_t *p_demux );
247     virtual ~EbmlParser( void );
248
249     void Up( void );
250     void Down( void );
251     void Reset( demux_t *p_demux );
252     EbmlElement *Get( void );
253     void        Keep( void );
254
255     int GetLevel( void );
256
257   private:
258     EbmlStream  *m_es;
259     int         mi_level;
260     EbmlElement *m_el[10];
261     int64_t      mi_remain_size[10];
262
263     EbmlElement *m_got;
264
265     int         mi_user_level;
266     vlc_bool_t  mb_keep;
267     vlc_bool_t  mb_dummy;
268 };
269
270
271 /*****************************************************************************
272  * Some functions to manipulate memory
273  *****************************************************************************/
274 #define GetFOURCC( p )  __GetFOURCC( (uint8_t*)p )
275 static vlc_fourcc_t __GetFOURCC( uint8_t *p )
276 {
277     return VLC_FOURCC( p[0], p[1], p[2], p[3] );
278 }
279
280 /*****************************************************************************
281  * definitions of structures and functions used by this plugins
282  *****************************************************************************/
283 typedef struct
284 {
285     vlc_bool_t   b_default;
286     vlc_bool_t   b_enabled;
287     unsigned int i_number;
288
289     int          i_extra_data;
290     uint8_t      *p_extra_data;
291
292     char         *psz_codec;
293
294     uint64_t     i_default_duration;
295     float        f_timecodescale;
296
297     /* video */
298     es_format_t fmt;
299     float       f_fps;
300     es_out_id_t *p_es;
301
302     vlc_bool_t      b_inited;
303     /* data to be send first */
304     int             i_data_init;
305     uint8_t         *p_data_init;
306
307     /* hack : it's for seek */
308     vlc_bool_t      b_search_keyframe;
309     vlc_bool_t      b_silent;
310
311     /* informative */
312     char         *psz_codec_name;
313     char         *psz_codec_settings;
314     char         *psz_codec_info_url;
315     char         *psz_codec_download_url;
316     
317     /* encryption/compression */
318     int           i_compression_type;
319
320 } mkv_track_t;
321
322 typedef struct
323 {
324     int     i_track;
325     int     i_block_number;
326
327     int64_t i_position;
328     int64_t i_time;
329
330     vlc_bool_t b_key;
331 } mkv_index_t;
332
333 class demux_sys_t;
334
335 class chapter_codec_cmds_c
336 {
337 public:
338     chapter_codec_cmds_c( int codec_id = -1)
339     :i_codec_id( codec_id )
340     {}
341         
342     virtual ~chapter_codec_cmds_c() {}
343
344     void SetPrivate( const KaxChapterProcessPrivate & private_data )
345     {
346         m_private_data = *( new KaxChapterProcessPrivate( private_data ) );
347     }
348
349     void AddCommand( const KaxChapterProcessCommand & command );
350     
351     virtual bool Enter() { return true; }
352     virtual bool Leave() { return true; }
353
354     KaxChapterProcessPrivate m_private_data;
355
356 protected:
357     std::vector<KaxChapterProcessData> enter_cmds;
358     std::vector<KaxChapterProcessData> during_cmds;
359     std::vector<KaxChapterProcessData> leave_cmds;
360
361     int i_codec_id;
362 };
363
364 class dvd_command_interpretor_c
365 {
366 public:
367     dvd_command_interpretor_c( demux_sys_t & demuxer )
368     :sys( demuxer )
369     {
370         memset( p_GPRM, 0, sizeof(p_GPRM) );
371         memset( p_SPRM, 0, sizeof(p_SPRM) );
372         p_SPRM[ 1 ] = 15;
373         p_SPRM[ 2 ] = 62;
374         p_SPRM[ 3 ] = 1;
375         p_SPRM[ 4 ] = 1;
376         p_SPRM[ 7 ] = 1;
377         p_SPRM[ 8 ] = 1;
378         p_SPRM[ 16 ] = 0xFFFFu;
379         p_SPRM[ 18 ] = 0xFFFFu;
380     }
381     
382     bool Interpret( const binary * p_command, size_t i_size = 8 );
383     
384 protected:
385     uint16 GetGPRM( size_t index ) const
386     {
387         if ( index >= 0 && index < 16 )
388             return p_GPRM[ index ];
389         else return 0;
390     }
391
392     uint16 GetSPRM( size_t index ) const
393     {
394         // 21,22,23 reserved for future use
395         if ( index >= 0 && index < 21 )
396             return p_SPRM[ index ];
397         else return 0;
398     }
399
400     bool SetGPRM( size_t index, uint16 value )
401     {
402         if ( index >= 0 && index < 16 )
403         {
404             p_GPRM[ index ] = value;
405             return true;
406         }
407         return false;
408     }
409
410     bool SetSPRM( size_t index, uint16 value )
411     {
412         if ( index > 0 && index <= 13 && index != 12 )
413         {
414             p_SPRM[ index ] = value;
415             return true;
416         }
417         return false;
418     }
419
420     uint16       p_GPRM[16];
421     uint16       p_SPRM[24];
422     demux_sys_t  & sys;
423     
424     // DVD command IDs
425     static const uint16 CMD_JUMP_TT     = 0x3002;
426     static const uint16 CMD_CALLSS_VTSM = 0x3008;
427     
428     // callbacks when browsing inside CodecPrivate
429     static bool MatchTitleNumber( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size );
430 };
431
432 class dvd_chapter_codec_c : public chapter_codec_cmds_c
433 {
434 public:
435     dvd_chapter_codec_c( demux_sys_t & sys )
436     :chapter_codec_cmds_c( 1 )
437     ,interpretor( sys )
438     {}
439
440     bool Enter();
441     bool Leave();
442
443 protected:
444     dvd_command_interpretor_c interpretor; 
445 };
446
447 class matroska_script_codec_c : public chapter_codec_cmds_c
448 {
449 };
450
451 class chapter_translation_c
452 {
453 public:
454     KaxChapterTranslateID  translated;
455     unsigned int           codec_id;
456     std::vector<uint64_t>  editions;
457 };
458
459 class chapter_item_c
460 {
461 public:
462     chapter_item_c()
463     :i_start_time(0)
464     ,i_end_time(-1)
465     ,i_user_start_time(-1)
466     ,i_user_end_time(-1)
467     ,i_seekpoint_num(-1)
468     ,b_display_seekpoint(true)
469     ,psz_parent(NULL)
470     {}
471
472     virtual ~chapter_item_c()
473     {
474         std::vector<chapter_codec_cmds_c*>::iterator index = codecs.begin();
475         while ( index != codecs.end() )
476         {
477             delete (*index);
478             index++;
479         }
480         std::vector<chapter_item_c*>::iterator index_ = sub_chapters.begin();
481         while ( index_ != sub_chapters.end() )
482         {
483             delete (*index_);
484             index_++;
485         }
486     }
487
488     int64_t RefreshChapters( bool b_ordered, int64_t i_prev_user_time );
489     void PublishChapters( input_title_t & title, int i_level );
490     chapter_item_c * FindTimecode( mtime_t i_timecode );
491     void Append( const chapter_item_c & edition );
492     chapter_item_c * FindChapter( const chapter_item_c & chapter );
493     virtual chapter_item_c *BrowseCodecPrivate( unsigned int codec_id, 
494                                     bool (*match)(const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ), 
495                                     const void *p_cookie, 
496                                     size_t i_cookie_size );
497     
498     int64_t                     i_start_time, i_end_time;
499     int64_t                     i_user_start_time, i_user_end_time; /* the time in the stream when an edition is ordered */
500     std::vector<chapter_item_c*> sub_chapters;
501     int                         i_seekpoint_num;
502     int64_t                     i_uid;
503     bool                        b_display_seekpoint;
504     std::string                 psz_name;
505     chapter_item_c              *psz_parent;
506     
507     std::vector<chapter_codec_cmds_c*> codecs;
508
509     bool operator<( const chapter_item_c & item ) const
510     {
511         return ( i_user_start_time < item.i_user_start_time || (i_user_start_time == item.i_user_start_time && i_user_end_time < item.i_user_end_time) );
512     }
513
514     bool Enter();
515     bool Leave();
516 };
517
518 class chapter_edition_c : public chapter_item_c
519 {
520 public:
521     chapter_edition_c()
522     :b_ordered(false)
523     {}
524     
525     void RefreshChapters( );
526     mtime_t Duration() const;
527     void PublishChapters( input_title_t & title );
528     
529     bool                        b_ordered;
530 };
531
532 class matroska_segment_c
533 {
534 public:
535     matroska_segment_c( demux_sys_t & demuxer, EbmlStream & estream )
536         :segment(NULL)
537         ,es(estream)
538         ,i_timescale(MKVD_TIMECODESCALE)
539         ,i_duration(-1)
540         ,i_start_time(0)
541         ,i_cues_position(-1)
542         ,i_chapters_position(-1)
543         ,i_tags_position(-1)
544         ,cluster(NULL)
545         ,i_start_pos(0)
546         ,b_cues(VLC_FALSE)
547         ,i_index(0)
548         ,i_index_max(1024)
549         ,psz_muxing_application(NULL)
550         ,psz_writing_application(NULL)
551         ,psz_segment_filename(NULL)
552         ,psz_title(NULL)
553         ,psz_date_utc(NULL)
554         ,i_default_edition(0)
555         ,sys(demuxer)
556         ,ep(NULL)
557         ,b_preloaded(false)
558     {
559         index = (mkv_index_t*)malloc( sizeof( mkv_index_t ) * i_index_max );
560     }
561
562     virtual ~matroska_segment_c()
563     {
564         for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
565         {
566 #define tk  tracks[i_track]
567             if( tk->fmt.psz_description )
568             {
569                 free( tk->fmt.psz_description );
570             }
571             if( tk->psz_codec )
572             {
573                 free( tk->psz_codec );
574             }
575             if( tk->fmt.psz_language )
576             {
577                 free( tk->fmt.psz_language );
578             }
579             delete tk;
580 #undef tk
581         }
582         
583         if( psz_writing_application )
584         {
585             free( psz_writing_application );
586         }
587         if( psz_muxing_application )
588         {
589             free( psz_muxing_application );
590         }
591         if( psz_segment_filename )
592         {
593             free( psz_segment_filename );
594         }
595         if( psz_title )
596         {
597             free( psz_title );
598         }
599         if( psz_date_utc )
600         {
601             free( psz_date_utc );
602         }
603         if ( index )
604             free( index );
605
606         delete ep;
607
608         std::vector<chapter_edition_c*>::iterator index = stored_editions.begin();
609         while ( index != stored_editions.end() )
610         {
611             delete (*index);
612             index++;
613         }
614     }
615
616     KaxSegment              *segment;
617     EbmlStream              & es;
618
619     /* time scale */
620     uint64_t                i_timescale;
621
622     /* duration of the segment */
623     mtime_t                 i_duration;
624     mtime_t                 i_start_time;
625
626     /* all tracks */
627     std::vector<mkv_track_t*> tracks;
628
629     /* from seekhead */
630     int64_t                 i_cues_position;
631     int64_t                 i_chapters_position;
632     int64_t                 i_tags_position;
633
634     KaxCluster              *cluster;
635     int64_t                 i_start_pos;
636     KaxSegmentUID           segment_uid;
637     KaxPrevUID              prev_segment_uid;
638     KaxNextUID              next_segment_uid;
639
640     vlc_bool_t              b_cues;
641     int                     i_index;
642     int                     i_index_max;
643     mkv_index_t             *index;
644
645     /* info */
646     char                    *psz_muxing_application;
647     char                    *psz_writing_application;
648     char                    *psz_segment_filename;
649     char                    *psz_title;
650     char                    *psz_date_utc;
651
652     /* !!!!! GCC 3.3 bug on Darwin !!!!! */
653     /* when you remove this variable the compiler issues an atomicity error */
654     /* this variable only works when using std::vector<chapter_edition_c> */
655     std::vector<chapter_edition_c*> stored_editions;
656     int                             i_default_edition;
657
658     std::vector<chapter_translation_c> translations;
659     std::vector<KaxSegmentFamily>  families;
660     
661     demux_sys_t                    & sys;
662     EbmlParser                     *ep;
663     bool                           b_preloaded;
664
665     bool Preload( );
666     bool PreloadFamily( const matroska_segment_c & segment );
667     void ParseInfo( KaxInfo *info );
668     void ParseChapters( KaxChapters *chapters );
669     void ParseSeekHead( KaxSeekHead *seekhead );
670     void ParseTracks( KaxTracks *tracks );
671     void ParseChapterAtom( int i_level, KaxChapterAtom *ca, chapter_item_c & chapters );
672     void ParseTrackEntry( KaxTrackEntry *m );
673     void ParseCluster( );
674     void IndexAppendCluster( KaxCluster *cluster );
675     void LoadCues( );
676     void LoadTags( );
677     void InformationCreate( );
678     void Seek( mtime_t i_date, mtime_t i_time_offset );
679     int BlockGet( KaxBlock **pp_block, int64_t *pi_ref1, int64_t *pi_ref2, int64_t *pi_duration );
680     bool Select( mtime_t i_start_time );
681     void UnSelect( );
682
683     static bool CompareSegmentUIDs( const matroska_segment_c * item_a, const matroska_segment_c * item_b );
684 };
685
686 // class holding hard-linked segment together in the playback order
687 class virtual_segment_c
688 {
689 public:
690     virtual_segment_c( matroska_segment_c *p_segment )
691         :i_current_segment(0)
692         ,p_editions(NULL)
693         ,i_current_edition(-1)
694         ,psz_current_chapter(NULL)
695     {
696         linked_segments.push_back( p_segment );
697
698         AppendUID( p_segment->segment_uid );
699         AppendUID( p_segment->prev_segment_uid );
700         AppendUID( p_segment->next_segment_uid );
701     }
702
703     void Sort();
704     size_t AddSegment( matroska_segment_c *p_segment );
705     void PreloadLinked( );
706     mtime_t Duration( ) const;
707     void LoadCues( );
708     void Seek( demux_t & demuxer, mtime_t i_date, mtime_t i_time_offset, chapter_item_c *psz_chapter );
709
710     inline chapter_edition_c *Edition()
711     {
712         if ( i_current_edition >= 0 && size_t(i_current_edition) < p_editions->size() )
713             return (*p_editions)[i_current_edition];
714         return NULL;
715     }
716     
717     inline bool EditionIsOrdered() const
718     {
719         return (p_editions->size() != 0 && i_current_edition >= 0 && (*p_editions)[i_current_edition]->b_ordered);
720     }
721
722     matroska_segment_c * Segment() const
723     {
724         if ( linked_segments.size() == 0 || i_current_segment >= linked_segments.size() )
725             return NULL;
726         return linked_segments[i_current_segment];
727     }
728
729     inline const chapter_item_c *CurrentChapter() const {
730         return psz_current_chapter;
731     }
732
733     bool SelectNext()
734     {
735         if ( i_current_segment < linked_segments.size()-1 )
736         {
737             i_current_segment++;
738             return true;
739         }
740         return false;
741     }
742
743     bool FindUID( KaxSegmentUID & uid ) const
744     {
745         for ( size_t i=0; i<linked_uids.size(); i++ )
746         {
747             if ( linked_uids[i] == uid )
748                 return true;
749         }
750         return false;
751     }
752
753     void UpdateCurrentToChapter( demux_t & demux );
754     void PrepareChapters( );
755     bool Select( input_title_t & title );
756
757     chapter_item_c *BrowseCodecPrivate( unsigned int codec_id, 
758                                         bool (*match)(const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ), 
759                                         const void *p_cookie, 
760                                         size_t i_cookie_size );
761 protected:
762     std::vector<matroska_segment_c*> linked_segments;
763     std::vector<KaxSegmentUID>       linked_uids;
764     size_t                           i_current_segment;
765
766     std::vector<chapter_edition_c*>  *p_editions;
767     int                              i_current_edition;
768     chapter_item_c                   *psz_current_chapter;
769
770     void                             AppendUID( const EbmlBinary & UID );
771 };
772
773 class matroska_stream_c
774 {
775 public:
776     matroska_stream_c( demux_sys_t & demuxer )
777         :p_in(NULL)
778         ,p_es(NULL)
779         ,sys(demuxer)
780     {}
781
782     virtual ~matroska_stream_c()
783     {
784         delete p_in;
785         delete p_es;
786     }
787
788     IOCallback         *p_in;
789     EbmlStream         *p_es;
790
791     std::vector<matroska_segment_c*> segments;
792
793     demux_sys_t                      & sys;
794 };
795
796 class demux_sys_t
797 {
798 public:
799     demux_sys_t( demux_t & demux )
800         :demuxer(demux)
801         ,i_pts(0)
802         ,i_start_pts(0)
803         ,i_chapter_time(0)
804         ,meta(NULL)
805         ,title(NULL)
806         ,p_current_segment(NULL)
807         ,f_duration(-1.0)
808     {}
809
810     virtual ~demux_sys_t()
811     {
812         size_t i;
813         for ( i=0; i<streams.size(); i++ )
814             delete streams[i];
815         for ( i=0; i<opened_segments.size(); i++ )
816             delete opened_segments[i];
817         for ( i=0; i<used_segments.size(); i++ )
818             delete used_segments[i];
819     }
820
821     /* current data */
822     demux_t                 & demuxer;
823
824     mtime_t                 i_pts;
825     mtime_t                 i_start_pts;
826     mtime_t                 i_chapter_time;
827
828     vlc_meta_t              *meta;
829
830     input_title_t           *title;
831
832     std::vector<matroska_stream_c*>  streams;
833     std::vector<matroska_segment_c*> opened_segments;
834     std::vector<virtual_segment_c*>  used_segments;
835     virtual_segment_c                *p_current_segment;
836
837     /* duration of the stream */
838     float                   f_duration;
839
840     matroska_segment_c *FindSegment( const EbmlBinary & uid ) const;
841     chapter_item_c *BrowseCodecPrivate( unsigned int codec_id, 
842                                         bool (*match)(const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ), 
843                                         const void *p_cookie, 
844                                         size_t i_cookie_size, 
845                                         virtual_segment_c * & p_segment_found );
846
847     void PreloadFamily( const matroska_segment_c & of_segment );
848     void PreloadLinked( matroska_segment_c *p_segment );
849     bool PreparePlayback( );
850     matroska_stream_c *AnalyseAllSegmentsFound( EbmlStream *p_estream );
851
852 protected:
853     virtual_segment_c *VirtualFromSegments( matroska_segment_c *p_segment ) const;
854     bool IsUsedSegment( matroska_segment_c &p_segment ) const;
855 };
856
857 static int  Demux  ( demux_t * );
858 static int  Control( demux_t *, int, va_list );
859 static void Seek   ( demux_t *, mtime_t i_date, double f_percent, chapter_item_c *psz_chapter );
860
861 #define MKV_IS_ID( el, C ) ( EbmlId( (*el) ) == C::ClassInfos.GlobalId )
862
863 static char *UTF8ToStr          ( const UTFstring &u );
864
865 /*****************************************************************************
866  * Open: initializes matroska demux structures
867  *****************************************************************************/
868 static int Open( vlc_object_t * p_this )
869 {
870     demux_t            *p_demux = (demux_t*)p_this;
871     demux_sys_t        *p_sys;
872     matroska_stream_c  *p_stream;
873     matroska_segment_c *p_segment;
874     uint8_t            *p_peek;
875     std::string        s_path, s_filename;
876     vlc_stream_io_callback *p_io_callback;
877     EbmlStream         *p_io_stream;
878
879     /* peek the begining */
880     if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;
881
882     /* is a valid file */
883     if( p_peek[0] != 0x1a || p_peek[1] != 0x45 ||
884         p_peek[2] != 0xdf || p_peek[3] != 0xa3 ) return VLC_EGENERIC;
885
886     /* Set the demux function */
887     p_demux->pf_demux   = Demux;
888     p_demux->pf_control = Control;
889     p_demux->p_sys      = p_sys = new demux_sys_t( *p_demux );
890
891     p_io_callback = new vlc_stream_io_callback( p_demux->s );
892     p_io_stream = new EbmlStream( *p_io_callback );
893
894     if( p_io_stream == NULL )
895     {
896         msg_Err( p_demux, "failed to create EbmlStream" );
897         delete p_io_callback;
898         delete p_sys;
899         return VLC_EGENERIC;
900     }
901
902     p_stream = p_sys->AnalyseAllSegmentsFound( p_io_stream );
903     if( p_stream == NULL )
904     {
905         msg_Err( p_demux, "cannot find KaxSegment" );
906         goto error;
907     }
908     p_sys->streams.push_back( p_stream );
909
910     p_stream->p_in = p_io_callback;
911     p_stream->p_es = p_io_stream;
912
913     for (size_t i=0; i<p_stream->segments.size(); i++)
914     {
915         p_stream->segments[i]->Preload();
916     }
917
918     p_segment = p_stream->segments[0];
919     if( p_segment->cluster != NULL )
920     {
921         msg_Warn( p_demux, "cannot find any cluster, damaged file ?" );
922
923         // reset the stream reading to the first cluster of the segment used
924         p_stream->p_in->setFilePointer( p_segment->cluster->GetElementPosition() );
925     }
926
927     /* get the files from the same dir from the same family (based on p_demux->psz_path) */
928     if (p_demux->psz_path[0] != '\0' && !strcmp(p_demux->psz_access, ""))
929     {
930         // assume it's a regular file
931         // get the directory path
932         s_path = p_demux->psz_path;
933         if (s_path.at(s_path.length() - 1) == DIRECTORY_SEPARATOR)
934         {
935             s_path = s_path.substr(0,s_path.length()-1);
936         }
937         else
938         {
939             if (s_path.find_last_of(DIRECTORY_SEPARATOR) > 0) 
940             {
941                 s_path = s_path.substr(0,s_path.find_last_of(DIRECTORY_SEPARATOR));
942             }
943         }
944
945         struct dirent *p_file_item;
946         DIR *p_src_dir = opendir(s_path.c_str());
947
948         if (p_src_dir != NULL)
949         {
950             while ((p_file_item = (dirent *) readdir(p_src_dir)))
951             {
952                 if (strlen(p_file_item->d_name) > 4)
953                 {
954                     s_filename = s_path + DIRECTORY_SEPARATOR + p_file_item->d_name;
955
956                     if (!s_filename.compare(p_demux->psz_path))
957                         continue; // don't reuse the original opened file
958
959 #if defined(__GNUC__) && (__GNUC__ < 3)
960                     if (!s_filename.compare("mkv", s_filename.length() - 3, 3) || 
961                         !s_filename.compare("mka", s_filename.length() - 3, 3))
962 #else
963                     if (!s_filename.compare(s_filename.length() - 3, 3, "mkv") || 
964                         !s_filename.compare(s_filename.length() - 3, 3, "mka"))
965 #endif
966                     {
967                         // test wether this file belongs to the our family
968                         StdIOCallback *p_file_io = new StdIOCallback(s_filename.c_str(), MODE_READ);
969                         EbmlStream *p_estream = new EbmlStream(*p_file_io);
970
971                         p_stream = p_sys->AnalyseAllSegmentsFound( p_estream );
972                         if ( p_stream == NULL )
973                         {
974                             msg_Dbg( p_demux, "the file '%s' will not be used", s_filename.c_str() );
975                             delete p_estream;
976                             delete p_file_io;
977                         }
978                         else
979                         {
980                             p_stream->p_in = p_file_io;
981                             p_stream->p_es = p_estream;
982                             p_sys->streams.push_back( p_stream );
983                         }
984                     }
985                 }
986             }
987             closedir( p_src_dir );
988         }
989     }
990
991     p_sys->PreloadFamily( *p_segment );
992     p_sys->PreloadLinked( p_segment );
993     if ( !p_sys->PreparePlayback( ) )
994     {
995         msg_Err( p_demux, "cannot use the segment" );
996         goto error;
997     }
998     
999     return VLC_SUCCESS;
1000
1001 error:
1002     delete p_sys;
1003     return VLC_EGENERIC;
1004 }
1005
1006 /*****************************************************************************
1007  * Close: frees unused data
1008  *****************************************************************************/
1009 static void Close( vlc_object_t *p_this )
1010 {
1011     demux_t     *p_demux = (demux_t*)p_this;
1012     demux_sys_t *p_sys   = p_demux->p_sys;
1013
1014     delete p_sys;
1015 }
1016
1017 /*****************************************************************************
1018  * Control:
1019  *****************************************************************************/
1020 static int Control( demux_t *p_demux, int i_query, va_list args )
1021 {
1022     demux_sys_t        *p_sys = p_demux->p_sys;
1023     int64_t     *pi64;
1024     double      *pf, f;
1025     int         i_skp;
1026
1027     vlc_meta_t **pp_meta;
1028
1029     switch( i_query )
1030     {
1031         case DEMUX_GET_META:
1032             pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
1033             *pp_meta = vlc_meta_Duplicate( p_sys->meta );
1034             return VLC_SUCCESS;
1035
1036         case DEMUX_GET_LENGTH:
1037             pi64 = (int64_t*)va_arg( args, int64_t * );
1038             if( p_sys->f_duration > 0.0 )
1039             {
1040                 *pi64 = (int64_t)(p_sys->f_duration * 1000);
1041                 return VLC_SUCCESS;
1042             }
1043             return VLC_EGENERIC;
1044
1045         case DEMUX_GET_POSITION:
1046             pf = (double*)va_arg( args, double * );
1047             if ( p_sys->f_duration > 0.0 )
1048                 *pf = (double)(p_sys->i_pts >= p_sys->i_start_pts ? p_sys->i_pts : p_sys->i_start_pts ) / (1000.0 * p_sys->f_duration);
1049             return VLC_SUCCESS;
1050
1051         case DEMUX_SET_POSITION:
1052             f = (double)va_arg( args, double );
1053             Seek( p_demux, -1, f, NULL );
1054             return VLC_SUCCESS;
1055
1056         case DEMUX_GET_TIME:
1057             pi64 = (int64_t*)va_arg( args, int64_t * );
1058             *pi64 = p_sys->i_pts;
1059             return VLC_SUCCESS;
1060
1061         case DEMUX_GET_TITLE_INFO:
1062             if( p_sys->title && p_sys->title->i_seekpoint > 0 )
1063             {
1064                 input_title_t ***ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
1065                 int *pi_int    = (int*)va_arg( args, int* );
1066
1067                 *pi_int = 1;
1068                 *ppp_title = (input_title_t**)malloc( sizeof( input_title_t**) );
1069
1070                 (*ppp_title)[0] = vlc_input_title_Duplicate( p_sys->title );
1071
1072                 return VLC_SUCCESS;
1073             }
1074             return VLC_EGENERIC;
1075
1076         case DEMUX_SET_TITLE:
1077             /* TODO handle editions as titles & DVD titles as well */
1078             if( p_sys->title && p_sys->title->i_seekpoint > 0 )
1079             {
1080                 return VLC_SUCCESS;
1081             }
1082             return VLC_EGENERIC;
1083
1084         case DEMUX_SET_SEEKPOINT:
1085             i_skp = (int)va_arg( args, int );
1086
1087             if( p_sys->title && i_skp < p_sys->title->i_seekpoint)
1088             {
1089                 Seek( p_demux, (int64_t)p_sys->title->seekpoint[i_skp]->i_time_offset, -1, NULL);
1090                 p_demux->info.i_seekpoint |= INPUT_UPDATE_SEEKPOINT;
1091                 p_demux->info.i_seekpoint = i_skp;
1092                 return VLC_SUCCESS;
1093             }
1094             return VLC_EGENERIC;
1095
1096         case DEMUX_SET_TIME:
1097         case DEMUX_GET_FPS:
1098         default:
1099             return VLC_EGENERIC;
1100     }
1101 }
1102
1103 int matroska_segment_c::BlockGet( KaxBlock **pp_block, int64_t *pi_ref1, int64_t *pi_ref2, int64_t *pi_duration )
1104 {
1105     *pp_block = NULL;
1106     *pi_ref1  = -1;
1107     *pi_ref2  = -1;
1108
1109     for( ;; )
1110     {
1111         EbmlElement *el;
1112         int         i_level;
1113
1114         el = ep->Get();
1115         i_level = ep->GetLevel();
1116
1117         if( el == NULL && *pp_block != NULL )
1118         {
1119             /* update the index */
1120 #define idx index[i_index - 1]
1121             if( i_index > 0 && idx.i_time == -1 )
1122             {
1123                 idx.i_time        = (*pp_block)->GlobalTimecode() / (mtime_t)1000;
1124                 idx.b_key         = *pi_ref1 == -1 ? VLC_TRUE : VLC_FALSE;
1125             }
1126 #undef idx
1127             return VLC_SUCCESS;
1128         }
1129
1130         if( el == NULL )
1131         {
1132             if( ep->GetLevel() > 1 )
1133             {
1134                 ep->Up();
1135                 continue;
1136             }
1137             msg_Warn( &sys.demuxer, "EOF" );
1138             return VLC_EGENERIC;
1139         }
1140
1141         /* do parsing */
1142         if( i_level == 1 )
1143         {
1144             if( MKV_IS_ID( el, KaxCluster ) )
1145             {
1146                 cluster = (KaxCluster*)el;
1147
1148                 /* add it to the index */
1149                 if( i_index == 0 ||
1150                     ( i_index > 0 && index[i_index - 1].i_position < (int64_t)cluster->GetElementPosition() ) )
1151                 {
1152                     IndexAppendCluster( cluster );
1153                 }
1154
1155                 // reset silent tracks
1156                 for (size_t i=0; i<tracks.size(); i++)
1157                 {
1158                     tracks[i]->b_silent = VLC_FALSE;
1159                 }
1160
1161                 ep->Down();
1162             }
1163             else if( MKV_IS_ID( el, KaxCues ) )
1164             {
1165                 msg_Warn( &sys.demuxer, "find KaxCues FIXME" );
1166                 return VLC_EGENERIC;
1167             }
1168             else
1169             {
1170                 msg_Dbg( &sys.demuxer, "unknown (%s)", typeid( el ).name() );
1171             }
1172         }
1173         else if( i_level == 2 )
1174         {
1175             if( MKV_IS_ID( el, KaxClusterTimecode ) )
1176             {
1177                 KaxClusterTimecode &ctc = *(KaxClusterTimecode*)el;
1178
1179                 ctc.ReadData( es.I_O(), SCOPE_ALL_DATA );
1180                 cluster->InitTimecode( uint64( ctc ), i_timescale );
1181             }
1182             else if( MKV_IS_ID( el, KaxClusterSilentTracks ) )
1183             {
1184                 ep->Down();
1185             }
1186             else if( MKV_IS_ID( el, KaxBlockGroup ) )
1187             {
1188                 ep->Down();
1189             }
1190         }
1191         else if( i_level == 3 )
1192         {
1193             if( MKV_IS_ID( el, KaxBlock ) )
1194             {
1195                 *pp_block = (KaxBlock*)el;
1196
1197                 (*pp_block)->ReadData( es.I_O() );
1198                 (*pp_block)->SetParent( *cluster );
1199
1200                 ep->Keep();
1201             }
1202             else if( MKV_IS_ID( el, KaxBlockDuration ) )
1203             {
1204                 KaxBlockDuration &dur = *(KaxBlockDuration*)el;
1205
1206                 dur.ReadData( es.I_O() );
1207                 *pi_duration = uint64( dur );
1208             }
1209             else if( MKV_IS_ID( el, KaxReferenceBlock ) )
1210             {
1211                 KaxReferenceBlock &ref = *(KaxReferenceBlock*)el;
1212
1213                 ref.ReadData( es.I_O() );
1214                 if( *pi_ref1 == -1 )
1215                 {
1216                     *pi_ref1 = int64( ref );
1217                 }
1218                 else
1219                 {
1220                     *pi_ref2 = int64( ref );
1221                 }
1222             }
1223             else if( MKV_IS_ID( el, KaxClusterSilentTrackNumber ) )
1224             {
1225                 KaxClusterSilentTrackNumber &track_num = *(KaxClusterSilentTrackNumber*)el;
1226                 track_num.ReadData( es.I_O() );
1227                 // find the track
1228                 for (size_t i=0; i<tracks.size(); i++)
1229                 {
1230                     if ( tracks[i]->i_number == uint32(track_num))
1231                     {
1232                         tracks[i]->b_silent = VLC_TRUE;
1233                         break;
1234                     }
1235                 }
1236             }
1237         }
1238         else
1239         {
1240             msg_Err( &sys.demuxer, "invalid level = %d", i_level );
1241             return VLC_EGENERIC;
1242         }
1243     }
1244 }
1245
1246 static block_t *MemToBlock( demux_t *p_demux, uint8_t *p_mem, int i_mem)
1247 {
1248     block_t *p_block;
1249     if( !(p_block = block_New( p_demux, i_mem ) ) ) return NULL;
1250     memcpy( p_block->p_buffer, p_mem, i_mem );
1251     //p_block->i_rate = p_input->stream.control.i_rate;
1252     return p_block;
1253 }
1254
1255 static void BlockDecode( demux_t *p_demux, KaxBlock *block, mtime_t i_pts,
1256                          mtime_t i_duration )
1257 {
1258     demux_sys_t        *p_sys = p_demux->p_sys;
1259     matroska_segment_c *p_segment = p_sys->p_current_segment->Segment();
1260
1261     size_t          i_track;
1262     unsigned int    i;
1263     vlc_bool_t      b;
1264
1265 #define tk  p_segment->tracks[i_track]
1266     for( i_track = 0; i_track < p_segment->tracks.size(); i_track++ )
1267     {
1268         if( tk->i_number == block->TrackNum() )
1269         {
1270             break;
1271         }
1272     }
1273
1274     if( i_track >= p_segment->tracks.size() )
1275     {
1276         msg_Err( p_demux, "invalid track number=%d", block->TrackNum() );
1277         return;
1278     }
1279     if( tk->p_es == NULL )
1280     {
1281         msg_Err( p_demux, "unknown track number=%d", block->TrackNum() );
1282         return;
1283     }
1284     if( i_pts < p_sys->i_start_pts && tk->fmt.i_cat == AUDIO_ES )
1285     {
1286         return; /* discard audio packets that shouldn't be rendered */
1287     }
1288
1289     es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es, &b );
1290     if( !b )
1291     {
1292         tk->b_inited = VLC_FALSE;
1293         return;
1294     }
1295
1296     /* First send init data */
1297     if( !tk->b_inited && tk->i_data_init > 0 )
1298     {
1299         block_t *p_init;
1300
1301         msg_Dbg( p_demux, "sending header (%d bytes)", tk->i_data_init );
1302         p_init = MemToBlock( p_demux, tk->p_data_init, tk->i_data_init );
1303         if( p_init ) es_out_Send( p_demux->out, tk->p_es, p_init );
1304     }
1305     tk->b_inited = VLC_TRUE;
1306
1307
1308     for( i = 0; i < block->NumberFrames(); i++ )
1309     {
1310         block_t *p_block;
1311         DataBuffer &data = block->GetBuffer(i);
1312
1313         p_block = MemToBlock( p_demux, data.Buffer(), data.Size() );
1314
1315         if( p_block == NULL )
1316         {
1317             break;
1318         }
1319
1320 #if defined(HAVE_ZLIB_H)
1321         if( tk->i_compression_type )
1322         {
1323             p_block = block_zlib_decompress( VLC_OBJECT(p_demux), p_block );
1324         }
1325 #endif
1326
1327         // TODO implement correct timestamping when B frames are used
1328         if( tk->fmt.i_cat != VIDEO_ES )
1329         {
1330             p_block->i_dts = p_block->i_pts = i_pts;
1331         }
1332         else
1333         {
1334             p_block->i_dts = i_pts;
1335             p_block->i_pts = 0;
1336         }
1337
1338         if( tk->fmt.i_cat == SPU_ES && strcmp( tk->psz_codec, "S_VOBSUB" ) )
1339         {
1340             p_block->i_length = i_duration * 1000;
1341         }
1342
1343         es_out_Send( p_demux->out, tk->p_es, p_block );
1344
1345         /* use time stamp only for first block */
1346         i_pts = 0;
1347     }
1348
1349 #undef tk
1350 }
1351
1352 matroska_stream_c *demux_sys_t::AnalyseAllSegmentsFound( EbmlStream *p_estream )
1353 {
1354     int i_upper_lvl = 0;
1355     size_t i;
1356     EbmlElement *p_l0, *p_l1, *p_l2;
1357     bool b_keep_stream = false, b_keep_segment;
1358
1359     // verify the EBML Header
1360     p_l0 = p_estream->FindNextID(EbmlHead::ClassInfos, 0xFFFFFFFFL);
1361     if (p_l0 == NULL)
1362     {
1363         return NULL;
1364     }
1365     p_l0->SkipData(*p_estream, EbmlHead_Context);
1366     delete p_l0;
1367
1368     // find all segments in this file
1369     p_l0 = p_estream->FindNextID(KaxSegment::ClassInfos, 0xFFFFFFFFL);
1370     if (p_l0 == NULL)
1371     {
1372         return NULL;
1373     }
1374
1375     matroska_stream_c *p_stream1 = new matroska_stream_c( *this );
1376
1377     while (p_l0 != 0)
1378     {
1379         if (EbmlId(*p_l0) == KaxSegment::ClassInfos.GlobalId)
1380         {
1381             EbmlParser  *ep;
1382             matroska_segment_c *p_segment1 = new matroska_segment_c( *this, *p_estream );
1383             b_keep_segment = false;
1384
1385             ep = new EbmlParser(p_estream, p_l0, &demuxer );
1386             p_segment1->ep = ep;
1387             p_segment1->segment = (KaxSegment*)p_l0;
1388
1389             while ((p_l1 = ep->Get()))
1390             {
1391                 if (MKV_IS_ID(p_l1, KaxInfo))
1392                 {
1393                     // find the families of this segment
1394                     KaxInfo *p_info = static_cast<KaxInfo*>(p_l1);
1395
1396                     p_info->Read(*p_estream, KaxInfo::ClassInfos.Context, i_upper_lvl, p_l2, true);
1397                     for( i = 0; i < p_info->ListSize(); i++ )
1398                     {
1399                         EbmlElement *l = (*p_info)[i];
1400
1401                         if( MKV_IS_ID( l, KaxSegmentUID ) )
1402                         {
1403                             KaxSegmentUID *p_uid = static_cast<KaxSegmentUID*>(l);
1404                             b_keep_segment = (FindSegment( *p_uid ) == NULL);
1405                             if ( !b_keep_segment )
1406                                 break; // this segment is already known
1407                             opened_segments.push_back( p_segment1 );
1408                             p_segment1->segment_uid = *( new KaxSegmentUID(*p_uid) );
1409                         }
1410                         else if( MKV_IS_ID( l, KaxPrevUID ) )
1411                         {
1412                             p_segment1->prev_segment_uid = *( new KaxPrevUID( *static_cast<KaxPrevUID*>(l) ) );
1413                         }
1414                         else if( MKV_IS_ID( l, KaxNextUID ) )
1415                         {
1416                             p_segment1->next_segment_uid = *( new KaxNextUID( *static_cast<KaxNextUID*>(l) ) );
1417                         }
1418                         else if( MKV_IS_ID( l, KaxSegmentFamily ) )
1419                         {
1420                             KaxSegmentFamily *p_fam = new KaxSegmentFamily( *static_cast<KaxSegmentFamily*>(l) );
1421                             p_segment1->families.push_back( *p_fam );
1422                         }
1423                     }
1424                     break;
1425                 }
1426             }
1427             if ( b_keep_segment )
1428             {
1429                 b_keep_stream = true;
1430                 p_stream1->segments.push_back( p_segment1 );
1431             }
1432             else
1433                 delete p_segment1;
1434         }
1435
1436         p_l0->SkipData(*p_estream, EbmlHead_Context);
1437         p_l0 = p_estream->FindNextID(KaxSegment::ClassInfos, 0xFFFFFFFFL);
1438     }
1439
1440     if ( !b_keep_stream )
1441     {
1442         delete p_stream1;
1443         p_stream1 = NULL;
1444     }
1445
1446     return p_stream1;
1447 }
1448
1449 bool matroska_segment_c::Select( mtime_t i_start_time )
1450 {
1451     size_t i_track;
1452
1453     /* add all es */
1454     msg_Dbg( &sys.demuxer, "found %d es", tracks.size() );
1455     for( i_track = 0; i_track < tracks.size(); i_track++ )
1456     {
1457 #define tk  tracks[i_track]
1458         if( tk->fmt.i_cat == UNKNOWN_ES )
1459         {
1460             msg_Warn( &sys.demuxer, "invalid track[%d, n=%d]", i_track, tk->i_number );
1461             tk->p_es = NULL;
1462             continue;
1463         }
1464
1465         if( !strcmp( tk->psz_codec, "V_MS/VFW/FOURCC" ) )
1466         {
1467             if( tk->i_extra_data < (int)sizeof( BITMAPINFOHEADER ) )
1468             {
1469                 msg_Err( &sys.demuxer, "missing/invalid BITMAPINFOHEADER" );
1470                 tk->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1471             }
1472             else
1473             {
1474                 BITMAPINFOHEADER *p_bih = (BITMAPINFOHEADER*)tk->p_extra_data;
1475
1476                 tk->fmt.video.i_width = GetDWLE( &p_bih->biWidth );
1477                 tk->fmt.video.i_height= GetDWLE( &p_bih->biHeight );
1478                 tk->fmt.i_codec       = GetFOURCC( &p_bih->biCompression );
1479
1480                 tk->fmt.i_extra       = GetDWLE( &p_bih->biSize ) - sizeof( BITMAPINFOHEADER );
1481                 if( tk->fmt.i_extra > 0 )
1482                 {
1483                     tk->fmt.p_extra = malloc( tk->fmt.i_extra );
1484                     memcpy( tk->fmt.p_extra, &p_bih[1], tk->fmt.i_extra );
1485                 }
1486             }
1487         }
1488         else if( !strcmp( tk->psz_codec, "V_MPEG1" ) ||
1489                  !strcmp( tk->psz_codec, "V_MPEG2" ) )
1490         {
1491             tk->fmt.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'v' );
1492         }
1493         else if( !strncmp( tk->psz_codec, "V_MPEG4", 7 ) )
1494         {
1495             if( !strcmp( tk->psz_codec, "V_MPEG4/MS/V3" ) )
1496             {
1497                 tk->fmt.i_codec = VLC_FOURCC( 'D', 'I', 'V', '3' );
1498             }
1499             else if( !strcmp( tk->psz_codec, "V_MPEG4/ISO/AVC" ) )
1500             {
1501                 tk->fmt.i_codec = VLC_FOURCC( 'a', 'v', 'c', '1' );
1502                 tk->fmt.b_packetized = VLC_FALSE;
1503                 tk->fmt.i_extra = tk->i_extra_data;
1504                 tk->fmt.p_extra = malloc( tk->i_extra_data );
1505                 memcpy( tk->fmt.p_extra,tk->p_extra_data, tk->i_extra_data );
1506             }
1507             else
1508             {
1509                 tk->fmt.i_codec = VLC_FOURCC( 'm', 'p', '4', 'v' );
1510             }
1511         }
1512         else if( !strcmp( tk->psz_codec, "V_QUICKTIME" ) )
1513         {
1514             MP4_Box_t *p_box = (MP4_Box_t*)malloc( sizeof( MP4_Box_t ) );
1515 #ifdef VSLHC
1516             stream_t *p_mp4_stream = stream_MemoryNew( VLC_OBJECT(&sys.demuxer),
1517                                                        tk->p_extra_data,
1518                                                        tk->i_extra_data );
1519 #else
1520             stream_t *p_mp4_stream = stream_MemoryNew( VLC_OBJECT(&sys.demuxer),
1521                                                        tk->p_extra_data,
1522                                                        tk->i_extra_data,
1523                                                        VLC_FALSE );
1524 #endif
1525             MP4_ReadBoxCommon( p_mp4_stream, p_box );
1526             MP4_ReadBox_sample_vide( p_mp4_stream, p_box );
1527             tk->fmt.i_codec = p_box->i_type;
1528             tk->fmt.video.i_width = p_box->data.p_sample_vide->i_width;
1529             tk->fmt.video.i_height = p_box->data.p_sample_vide->i_height;
1530             tk->fmt.i_extra = p_box->data.p_sample_vide->i_qt_image_description;
1531             tk->fmt.p_extra = malloc( tk->fmt.i_extra );
1532             memcpy( tk->fmt.p_extra, p_box->data.p_sample_vide->p_qt_image_description, tk->fmt.i_extra );
1533             MP4_FreeBox_sample_vide( p_box );
1534 #ifdef VSLHC
1535             stream_MemoryDelete( p_mp4_stream, VLC_TRUE );
1536 #else
1537             stream_Delete( p_mp4_stream );
1538 #endif        
1539         }
1540         else if( !strcmp( tk->psz_codec, "A_MS/ACM" ) )
1541         {
1542             if( tk->i_extra_data < (int)sizeof( WAVEFORMATEX ) )
1543             {
1544                 msg_Err( &sys.demuxer, "missing/invalid WAVEFORMATEX" );
1545                 tk->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1546             }
1547             else
1548             {
1549                 WAVEFORMATEX *p_wf = (WAVEFORMATEX*)tk->p_extra_data;
1550
1551                 wf_tag_to_fourcc( GetWLE( &p_wf->wFormatTag ), &tk->fmt.i_codec, NULL );
1552
1553                 tk->fmt.audio.i_channels   = GetWLE( &p_wf->nChannels );
1554                 tk->fmt.audio.i_rate = GetDWLE( &p_wf->nSamplesPerSec );
1555                 tk->fmt.i_bitrate    = GetDWLE( &p_wf->nAvgBytesPerSec ) * 8;
1556                 tk->fmt.audio.i_blockalign = GetWLE( &p_wf->nBlockAlign );;
1557                 tk->fmt.audio.i_bitspersample = GetWLE( &p_wf->wBitsPerSample );
1558
1559                 tk->fmt.i_extra            = GetWLE( &p_wf->cbSize );
1560                 if( tk->fmt.i_extra > 0 )
1561                 {
1562                     tk->fmt.p_extra = malloc( tk->fmt.i_extra );
1563                     memcpy( tk->fmt.p_extra, &p_wf[1], tk->fmt.i_extra );
1564                 }
1565             }
1566         }
1567         else if( !strcmp( tk->psz_codec, "A_MPEG/L3" ) ||
1568                  !strcmp( tk->psz_codec, "A_MPEG/L2" ) ||
1569                  !strcmp( tk->psz_codec, "A_MPEG/L1" ) )
1570         {
1571             tk->fmt.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'a' );
1572         }
1573         else if( !strcmp( tk->psz_codec, "A_AC3" ) )
1574         {
1575             tk->fmt.i_codec = VLC_FOURCC( 'a', '5', '2', ' ' );
1576         }
1577         else if( !strcmp( tk->psz_codec, "A_DTS" ) )
1578         {
1579             tk->fmt.i_codec = VLC_FOURCC( 'd', 't', 's', ' ' );
1580         }
1581         else if( !strcmp( tk->psz_codec, "A_FLAC" ) )
1582         {
1583             tk->fmt.i_codec = VLC_FOURCC( 'f', 'l', 'a', 'c' );
1584             tk->fmt.i_extra = tk->i_extra_data;
1585             tk->fmt.p_extra = malloc( tk->i_extra_data );
1586             memcpy( tk->fmt.p_extra,tk->p_extra_data, tk->i_extra_data );
1587         }
1588         else if( !strcmp( tk->psz_codec, "A_VORBIS" ) )
1589         {
1590             int i, i_offset = 1, i_size[3], i_extra;
1591             uint8_t *p_extra;
1592
1593             tk->fmt.i_codec = VLC_FOURCC( 'v', 'o', 'r', 'b' );
1594
1595             /* Split the 3 headers */
1596             if( tk->p_extra_data[0] != 0x02 )
1597                 msg_Err( &sys.demuxer, "invalid vorbis header" );
1598
1599             for( i = 0; i < 2; i++ )
1600             {
1601                 i_size[i] = 0;
1602                 while( i_offset < tk->i_extra_data )
1603                 {
1604                     i_size[i] += tk->p_extra_data[i_offset];
1605                     if( tk->p_extra_data[i_offset++] != 0xff ) break;
1606                 }
1607             }
1608
1609             i_size[0] = __MIN(i_size[0], tk->i_extra_data - i_offset);
1610             i_size[1] = __MIN(i_size[1], tk->i_extra_data -i_offset -i_size[0]);
1611             i_size[2] = tk->i_extra_data - i_offset - i_size[0] - i_size[1];
1612
1613             tk->fmt.i_extra = 3 * 2 + i_size[0] + i_size[1] + i_size[2];
1614             tk->fmt.p_extra = malloc( tk->fmt.i_extra );
1615             p_extra = (uint8_t *)tk->fmt.p_extra; i_extra = 0;
1616             for( i = 0; i < 3; i++ )
1617             {
1618                 *(p_extra++) = i_size[i] >> 8;
1619                 *(p_extra++) = i_size[i] & 0xFF;
1620                 memcpy( p_extra, tk->p_extra_data + i_offset + i_extra,
1621                         i_size[i] );
1622                 p_extra += i_size[i];
1623                 i_extra += i_size[i];
1624             }
1625         }
1626         else if( !strncmp( tk->psz_codec, "A_AAC/MPEG2/", strlen( "A_AAC/MPEG2/" ) ) ||
1627                  !strncmp( tk->psz_codec, "A_AAC/MPEG4/", strlen( "A_AAC/MPEG4/" ) ) )
1628         {
1629             int i_profile, i_srate;
1630             static unsigned int i_sample_rates[] =
1631             {
1632                     96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
1633                         16000, 12000, 11025, 8000,  7350,  0,     0,     0
1634             };
1635
1636             tk->fmt.i_codec = VLC_FOURCC( 'm', 'p', '4', 'a' );
1637             /* create data for faad (MP4DecSpecificDescrTag)*/
1638
1639             if( !strcmp( &tk->psz_codec[12], "MAIN" ) )
1640             {
1641                 i_profile = 0;
1642             }
1643             else if( !strcmp( &tk->psz_codec[12], "LC" ) )
1644             {
1645                 i_profile = 1;
1646             }
1647             else if( !strcmp( &tk->psz_codec[12], "SSR" ) )
1648             {
1649                 i_profile = 2;
1650             }
1651             else
1652             {
1653                 i_profile = 3;
1654             }
1655
1656             for( i_srate = 0; i_srate < 13; i_srate++ )
1657             {
1658                 if( i_sample_rates[i_srate] == tk->fmt.audio.i_rate )
1659                 {
1660                     break;
1661                 }
1662             }
1663             msg_Dbg( &sys.demuxer, "profile=%d srate=%d", i_profile, i_srate );
1664
1665             tk->fmt.i_extra = 2;
1666             tk->fmt.p_extra = malloc( tk->fmt.i_extra );
1667             ((uint8_t*)tk->fmt.p_extra)[0] = ((i_profile + 1) << 3) | ((i_srate&0xe) >> 1);
1668             ((uint8_t*)tk->fmt.p_extra)[1] = ((i_srate & 0x1) << 7) | (tk->fmt.audio.i_channels << 3);
1669         }
1670         else if( !strcmp( tk->psz_codec, "A_PCM/INT/BIG" ) ||
1671                  !strcmp( tk->psz_codec, "A_PCM/INT/LIT" ) ||
1672                  !strcmp( tk->psz_codec, "A_PCM/FLOAT/IEEE" ) )
1673         {
1674             if( !strcmp( tk->psz_codec, "A_PCM/INT/BIG" ) )
1675             {
1676                 tk->fmt.i_codec = VLC_FOURCC( 't', 'w', 'o', 's' );
1677             }
1678             else
1679             {
1680                 tk->fmt.i_codec = VLC_FOURCC( 'a', 'r', 'a', 'w' );
1681             }
1682             tk->fmt.audio.i_blockalign = ( tk->fmt.audio.i_bitspersample + 7 ) / 8 * tk->fmt.audio.i_channels;
1683         }
1684         else if( !strcmp( tk->psz_codec, "A_TTA1" ) )
1685         {
1686             /* FIXME: support this codec */
1687             msg_Err( &sys.demuxer, "TTA not supported yet[%d, n=%d]", i_track, tk->i_number );
1688             tk->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1689         }
1690         else if( !strcmp( tk->psz_codec, "A_WAVPACK4" ) )
1691         {
1692             /* FIXME: support this codec */
1693             msg_Err( &sys.demuxer, "Wavpack not supported yet[%d, n=%d]", i_track, tk->i_number );
1694             tk->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1695         }
1696         else if( !strcmp( tk->psz_codec, "S_TEXT/UTF8" ) )
1697         {
1698             tk->fmt.i_codec = VLC_FOURCC( 's', 'u', 'b', 't' );
1699             tk->fmt.subs.psz_encoding = strdup( "UTF-8" );
1700         }
1701         else if( !strcmp( tk->psz_codec, "S_TEXT/SSA" ) ||
1702                  !strcmp( tk->psz_codec, "S_TEXT/ASS" ) ||
1703                  !strcmp( tk->psz_codec, "S_SSA" ) ||
1704                  !strcmp( tk->psz_codec, "S_ASS" ))
1705         {
1706             tk->fmt.i_codec = VLC_FOURCC( 's', 's', 'a', ' ' );
1707             tk->fmt.subs.psz_encoding = strdup( "UTF-8" );
1708         }
1709         else if( !strcmp( tk->psz_codec, "S_VOBSUB" ) )
1710         {
1711             tk->fmt.i_codec = VLC_FOURCC( 's','p','u',' ' );
1712             if( tk->i_extra_data )
1713             {
1714                 char *p_start;
1715                 char *p_buf = (char *)malloc( tk->i_extra_data + 1);
1716                 memcpy( p_buf, tk->p_extra_data , tk->i_extra_data );
1717                 p_buf[tk->i_extra_data] = '\0';
1718                 
1719                 p_start = strstr( p_buf, "size:" );
1720                 if( sscanf( p_start, "size: %dx%d",
1721                         &tk->fmt.subs.spu.i_original_frame_width, &tk->fmt.subs.spu.i_original_frame_height ) == 2 )
1722                 {
1723                     msg_Dbg( &sys.demuxer, "original frame size vobsubs: %dx%d", tk->fmt.subs.spu.i_original_frame_width, tk->fmt.subs.spu.i_original_frame_height );
1724                 }
1725                 else
1726                 {
1727                     msg_Warn( &sys.demuxer, "reading original frame size for vobsub failed" );
1728                 }
1729                 free( p_buf );
1730             }
1731         }
1732         else if( !strcmp( tk->psz_codec, "B_VOBBTN" ) )
1733         {
1734             /* FIXME: support this codec */
1735             msg_Err( &sys.demuxer, "Vob Buttons not supported yet[%d, n=%d]", i_track, tk->i_number );
1736             tk->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1737         }
1738         else
1739         {
1740             msg_Err( &sys.demuxer, "unknow codec id=`%s'", tk->psz_codec );
1741             tk->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1742         }
1743         if( tk->b_default )
1744         {
1745             tk->fmt.i_priority = 1000;
1746         }
1747
1748         tk->p_es = es_out_Add( sys.demuxer.out, &tk->fmt );
1749
1750         es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, tk->p_es, i_start_time );
1751 #undef tk
1752     }
1753     
1754     sys.i_start_pts = i_start_time;
1755     // reset the stream reading to the first cluster of the segment used
1756     es.I_O().setFilePointer( i_start_pos );
1757
1758     delete ep;
1759     ep = new EbmlParser( &es, segment, &sys.demuxer );
1760
1761     return true;
1762 }
1763
1764 void matroska_segment_c::UnSelect( )
1765 {
1766     size_t i_track;
1767
1768     for( i_track = 0; i_track < tracks.size(); i_track++ )
1769     {
1770 #define tk  tracks[i_track]
1771         if ( tk->p_es != NULL )
1772         {
1773             es_out_Del( sys.demuxer.out, tk->p_es );
1774             tk->p_es = NULL;
1775         }
1776 #undef tk
1777     }
1778     delete ep;
1779     ep = NULL;
1780 }
1781
1782 void virtual_segment_c::PrepareChapters( )
1783 {
1784     if ( linked_segments.size() == 0 )
1785         return;
1786
1787     // !!! should be called only once !!!
1788     matroska_segment_c *p_segment;
1789     size_t i, j;
1790
1791     // copy editions from the first segment
1792     p_segment = linked_segments[0];
1793     p_editions = &p_segment->stored_editions;
1794
1795     for ( i=1 ; i<linked_segments.size(); i++ )
1796     {
1797         p_segment = linked_segments[i];
1798         // FIXME assume we have the same editions in all segments
1799         for (j=0; j<p_segment->stored_editions.size(); j++)
1800             (*p_editions)[j]->Append( *p_segment->stored_editions[j] );
1801     }
1802 }
1803
1804 bool virtual_segment_c::Select( input_title_t & title )
1805 {
1806     if ( Edition() != NULL )
1807         Edition()->PublishChapters( title );
1808
1809     return true;
1810 }
1811
1812 void chapter_edition_c::PublishChapters( input_title_t & title )
1813 {
1814     if ( title.seekpoint != NULL )
1815         free( title.seekpoint );
1816
1817     title.i_seekpoint = 0;
1818     title.seekpoint = NULL;
1819
1820     chapter_item_c::PublishChapters( title, 0 );
1821 }
1822
1823 void chapter_item_c::PublishChapters( input_title_t & title, int i_level )
1824 {
1825     if (b_display_seekpoint)
1826     {
1827         seekpoint_t *sk = vlc_seekpoint_New();
1828
1829         sk->i_level = i_level;
1830         sk->i_time_offset = i_start_time;
1831         sk->psz_name = strdup( psz_name.c_str() );
1832
1833         // A start time of '0' is ok. A missing ChapterTime element is ok, too, because '0' is its default value.
1834         title.i_seekpoint++;
1835         title.seekpoint = (seekpoint_t**)realloc( title.seekpoint, title.i_seekpoint * sizeof( seekpoint_t* ) );
1836         title.seekpoint[title.i_seekpoint-1] = sk;
1837     
1838         i_seekpoint_num = title.i_seekpoint;
1839     }
1840
1841     for ( size_t i=0; i<sub_chapters.size() ; i++)
1842     {
1843         sub_chapters[i]->PublishChapters( title, i_level+1 );
1844     }
1845 }
1846
1847 void virtual_segment_c::UpdateCurrentToChapter( demux_t & demux )
1848 {
1849     demux_sys_t & sys = *demux.p_sys;
1850     chapter_item_c *psz_curr_chapter;
1851
1852     /* update current chapter/seekpoint */
1853     if ( p_editions->size() )
1854     {
1855         /* 1st, we need to know in which chapter we are */
1856         psz_curr_chapter = (*p_editions)[i_current_edition]->FindTimecode( sys.i_pts );
1857
1858         /* we have moved to a new chapter */
1859         if (psz_curr_chapter != NULL && psz_current_chapter != psz_curr_chapter)
1860         {
1861             if ( psz_current_chapter != NULL )
1862                 psz_current_chapter->Leave();
1863
1864             if ( psz_curr_chapter->i_seekpoint_num > 0 )
1865             {
1866                 demux.info.i_update |= INPUT_UPDATE_SEEKPOINT;
1867                 demux.info.i_seekpoint = psz_curr_chapter->i_seekpoint_num - 1;
1868             }
1869
1870             if ( (*p_editions)[i_current_edition]->b_ordered )
1871             {
1872                 psz_curr_chapter->Enter();
1873
1874                 // only seek if necessary
1875                 if ( psz_current_chapter == NULL || (psz_current_chapter->i_end_time != psz_curr_chapter->i_start_time) )
1876                     Seek( demux, sys.i_pts, 0, psz_curr_chapter );
1877             }
1878         }
1879         psz_current_chapter = psz_curr_chapter;
1880     }
1881 }
1882
1883 chapter_item_c *virtual_segment_c::BrowseCodecPrivate( unsigned int codec_id, 
1884                                     bool (*match)(const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ), 
1885                                     const void *p_cookie, 
1886                                     size_t i_cookie_size )
1887 {
1888     // FIXME don't assume it is the first edition
1889     std::vector<chapter_edition_c*>::iterator index = p_editions->begin();
1890     if ( index != p_editions->end() )
1891     {
1892         chapter_item_c *p_result = (*index)->BrowseCodecPrivate( codec_id, match, p_cookie, i_cookie_size );
1893         if ( p_result != NULL )
1894             return p_result;
1895     }
1896     return NULL;
1897 }
1898
1899 chapter_item_c *chapter_item_c::BrowseCodecPrivate( unsigned int codec_id, 
1900                                     bool (*match)(const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ), 
1901                                     const void *p_cookie, 
1902                                     size_t i_cookie_size )
1903 {
1904     // this chapter
1905     std::vector<chapter_codec_cmds_c*>::const_iterator index = codecs.begin();
1906     while ( index != codecs.end() )
1907     {
1908         if ( match( **index ,p_cookie, i_cookie_size ) )
1909             return this;
1910         index++;
1911     }
1912     
1913     // sub-chapters
1914     chapter_item_c *p_result = NULL;
1915     std::vector<chapter_item_c*>::const_iterator index2 = sub_chapters.begin();
1916     while ( index2 != sub_chapters.end() )
1917     {
1918         p_result = (*index2)->BrowseCodecPrivate( codec_id, match, p_cookie, i_cookie_size );
1919         if ( p_result != NULL )
1920             return p_result;
1921         index2++;
1922     }
1923     
1924     return p_result;
1925 }
1926
1927 void chapter_item_c::Append( const chapter_item_c & chapter )
1928 {
1929     // we are appending content for the same chapter UID
1930     size_t i;
1931     chapter_item_c *p_chapter;
1932
1933     for ( i=0; i<chapter.sub_chapters.size(); i++ )
1934     {
1935         p_chapter = FindChapter( *chapter.sub_chapters[i] );
1936         if ( p_chapter != NULL )
1937         {
1938             p_chapter->Append( *chapter.sub_chapters[i] );
1939         }
1940         else
1941         {
1942             sub_chapters.push_back( chapter.sub_chapters[i] );
1943         }
1944     }
1945
1946     i_user_start_time = min( i_user_start_time, chapter.i_user_start_time );
1947     i_user_end_time = max( i_user_end_time, chapter.i_user_end_time );
1948 }
1949
1950 chapter_item_c * chapter_item_c::FindChapter( const chapter_item_c & chapter )
1951 {
1952     size_t i;
1953     for ( i=0; i<sub_chapters.size(); i++)
1954     {
1955         if ( sub_chapters[i]->i_uid == chapter.i_uid )
1956             return sub_chapters[i];
1957     }
1958     return NULL;
1959 }
1960
1961 static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, chapter_item_c *psz_chapter )
1962 {
1963     demux_sys_t        *p_sys = p_demux->p_sys;
1964     virtual_segment_c  *p_vsegment = p_sys->p_current_segment;
1965     matroska_segment_c *p_segment = p_vsegment->Segment();
1966     mtime_t            i_time_offset = 0;
1967
1968     int         i_index;
1969
1970     msg_Dbg( p_demux, "seek request to "I64Fd" (%f%%)", i_date, f_percent );
1971     if( i_date < 0 && f_percent < 0 )
1972     {
1973         msg_Warn( p_demux, "cannot seek nowhere !" );
1974         return;
1975     }
1976     if( f_percent > 1.0 )
1977     {
1978         msg_Warn( p_demux, "cannot seek so far !" );
1979         return;
1980     }
1981
1982     /* seek without index or without date */
1983     if( f_percent >= 0 && (config_GetInt( p_demux, "mkv-seek-percent" ) || !p_segment->b_cues || i_date < 0 ))
1984     {
1985         if (p_sys->f_duration >= 0)
1986         {
1987             i_date = int64_t( f_percent * p_sys->f_duration * 1000.0 );
1988         }
1989         else
1990         {
1991             int64_t i_pos = int64_t( f_percent * stream_Size( p_demux->s ) );
1992
1993             msg_Dbg( p_demux, "inacurate way of seeking" );
1994             for( i_index = 0; i_index < p_segment->i_index; i_index++ )
1995             {
1996                 if( p_segment->index[i_index].i_position >= i_pos)
1997                 {
1998                     break;
1999                 }
2000             }
2001             if( i_index == p_segment->i_index )
2002             {
2003                 i_index--;
2004             }
2005
2006             i_date = p_segment->index[i_index].i_time;
2007
2008 #if 0
2009             if( p_segment->index[i_index].i_position < i_pos )
2010             {
2011                 EbmlElement *el;
2012
2013                 msg_Warn( p_demux, "searching for cluster, could take some time" );
2014
2015                 /* search a cluster */
2016                 while( ( el = p_sys->ep->Get() ) != NULL )
2017                 {
2018                     if( MKV_IS_ID( el, KaxCluster ) )
2019                     {
2020                         KaxCluster *cluster = (KaxCluster*)el;
2021
2022                         /* add it to the index */
2023                         p_segment->IndexAppendCluster( cluster );
2024
2025                         if( (int64_t)cluster->GetElementPosition() >= i_pos )
2026                         {
2027                             p_sys->cluster = cluster;
2028                             p_sys->ep->Down();
2029                             break;
2030                         }
2031                     }
2032                 }
2033             }
2034 #endif
2035         }
2036     }
2037
2038     p_vsegment->Seek( *p_demux, i_date, i_time_offset, psz_chapter );
2039 }
2040
2041 /*****************************************************************************
2042  * Demux: reads and demuxes data packets
2043  *****************************************************************************
2044  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
2045  *****************************************************************************/
2046 static int Demux( demux_t *p_demux)
2047 {
2048     demux_sys_t        *p_sys = p_demux->p_sys;
2049     virtual_segment_c  *p_vsegment = p_sys->p_current_segment;
2050     matroska_segment_c *p_segmet = p_vsegment->Segment();
2051     if ( p_segmet == NULL ) return 0;
2052     int                i_block_count = 0;
2053
2054     KaxBlock *block;
2055     int64_t i_block_duration;
2056     int64_t i_block_ref1;
2057     int64_t i_block_ref2;
2058
2059     for( ;; )
2060     {
2061         if ( p_sys->demuxer.b_die )
2062             return 0;
2063
2064         if( p_sys->i_pts >= p_sys->i_start_pts  )
2065             p_vsegment->UpdateCurrentToChapter( *p_demux );
2066         
2067         if ( p_vsegment->EditionIsOrdered() && p_vsegment->CurrentChapter() == NULL )
2068         {
2069             /* nothing left to read in this ordered edition */
2070             if ( !p_vsegment->SelectNext() )
2071                 return 0;
2072             p_segmet->UnSelect( );
2073             
2074             es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
2075
2076             /* switch to the next segment */
2077             p_segmet = p_vsegment->Segment();
2078             if ( !p_segmet->Select( 0 ) )
2079             {
2080                 msg_Err( p_demux, "Failed to select new segment" );
2081                 return 0;
2082             }
2083             continue;
2084         }
2085
2086
2087         if( p_segmet->BlockGet( &block, &i_block_ref1, &i_block_ref2, &i_block_duration ) )
2088         {
2089             if ( p_vsegment->EditionIsOrdered() )
2090             {
2091                 const chapter_item_c *p_chap = p_vsegment->CurrentChapter();
2092                 // check if there are more chapters to read
2093                 if ( p_chap != NULL )
2094                 {
2095                     /* TODO handle successive chapters with the same user_start_time/user_end_time
2096                     if ( p_chap->i_user_start_time == p_chap->i_user_start_time )
2097                         p_vsegment->SelectNext();
2098                     */
2099                     p_sys->i_pts = p_chap->i_user_end_time;
2100                     p_sys->i_pts++; // trick to avoid staying on segments with no duration and no content
2101
2102                     return 1;
2103                 }
2104
2105                 return 0;
2106             }
2107             msg_Warn( p_demux, "cannot get block EOF?" );
2108             p_segmet->UnSelect( );
2109             
2110             es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
2111
2112             /* switch to the next segment */
2113             if ( !p_vsegment->SelectNext() )
2114                 // no more segments in this stream
2115                 return 0;
2116             p_segmet = p_vsegment->Segment();
2117             if ( !p_segmet->Select( 0 ) )
2118             {
2119                 msg_Err( p_demux, "Failed to select new segment" );
2120                 return 0;
2121             }
2122
2123             continue;
2124         }
2125
2126         p_sys->i_pts = p_sys->i_chapter_time + block->GlobalTimecode() / (mtime_t) 1000;
2127
2128         if( p_sys->i_pts >= p_sys->i_start_pts  )
2129         {
2130             es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pts );
2131         }
2132
2133         BlockDecode( p_demux, block, p_sys->i_pts, i_block_duration );
2134
2135         delete block;
2136         i_block_count++;
2137
2138         // TODO optimize when there is need to leave or when seeking has been called
2139         if( i_block_count > 5 )
2140         {
2141             return 1;
2142         }
2143     }
2144 }
2145
2146
2147
2148 /*****************************************************************************
2149  * Stream managment
2150  *****************************************************************************/
2151 vlc_stream_io_callback::vlc_stream_io_callback( stream_t *s_ )
2152 {
2153     s = s_;
2154     mb_eof = VLC_FALSE;
2155 }
2156
2157 uint32 vlc_stream_io_callback::read( void *p_buffer, size_t i_size )
2158 {
2159     if( i_size <= 0 || mb_eof )
2160     {
2161         return 0;
2162     }
2163
2164     return stream_Read( s, p_buffer, i_size );
2165 }
2166 void vlc_stream_io_callback::setFilePointer(int64_t i_offset, seek_mode mode )
2167 {
2168     int64_t i_pos;
2169
2170     switch( mode )
2171     {
2172         case seek_beginning:
2173             i_pos = i_offset;
2174             break;
2175         case seek_end:
2176             i_pos = stream_Size( s ) - i_offset;
2177             break;
2178         default:
2179             i_pos= stream_Tell( s ) + i_offset;
2180             break;
2181     }
2182
2183     if( i_pos < 0 || i_pos >= stream_Size( s ) )
2184     {
2185         mb_eof = VLC_TRUE;
2186         return;
2187     }
2188
2189     mb_eof = VLC_FALSE;
2190     if( stream_Seek( s, i_pos ) )
2191     {
2192         mb_eof = VLC_TRUE;
2193     }
2194     return;
2195 }
2196 size_t vlc_stream_io_callback::write( const void *p_buffer, size_t i_size )
2197 {
2198     return 0;
2199 }
2200 uint64 vlc_stream_io_callback::getFilePointer( void )
2201 {
2202     return stream_Tell( s );
2203 }
2204 void vlc_stream_io_callback::close( void )
2205 {
2206     return;
2207 }
2208
2209
2210 /*****************************************************************************
2211  * Ebml Stream parser
2212  *****************************************************************************/
2213 EbmlParser::EbmlParser( EbmlStream *es, EbmlElement *el_start, demux_t *p_demux )
2214 {
2215     int i;
2216
2217     m_es = es;
2218     m_got = NULL;
2219     m_el[0] = el_start;
2220     mi_remain_size[0] = el_start->GetSize();
2221
2222     for( i = 1; i < 6; i++ )
2223     {
2224         m_el[i] = NULL;
2225     }
2226     mi_level = 1;
2227     mi_user_level = 1;
2228     mb_keep = VLC_FALSE;
2229     mb_dummy = config_GetInt( p_demux, "mkv-use-dummy" );
2230 }
2231
2232 EbmlParser::~EbmlParser( void )
2233 {
2234     int i;
2235
2236     for( i = 1; i < mi_level; i++ )
2237     {
2238         if( !mb_keep )
2239         {
2240             delete m_el[i];
2241         }
2242         mb_keep = VLC_FALSE;
2243     }
2244 }
2245
2246 void EbmlParser::Up( void )
2247 {
2248     if( mi_user_level == mi_level )
2249     {
2250         fprintf( stderr," arrrrrrrrrrrrrg Up cannot escape itself\n" );
2251     }
2252
2253     mi_user_level--;
2254 }
2255
2256 void EbmlParser::Down( void )
2257 {
2258     mi_user_level++;
2259     mi_level++;
2260 }
2261
2262 void EbmlParser::Keep( void )
2263 {
2264     mb_keep = VLC_TRUE;
2265 }
2266
2267 int EbmlParser::GetLevel( void )
2268 {
2269     return mi_user_level;
2270 }
2271
2272 void EbmlParser::Reset( demux_t *p_demux )
2273 {
2274     while ( mi_level > 0)
2275     {
2276         delete m_el[mi_level];
2277         m_el[mi_level] = NULL;
2278         mi_level--;
2279     }
2280     mi_user_level = mi_level = 1;
2281 #if LIBEBML_VERSION >= 0x000704
2282     // a little faster and cleaner
2283     m_es->I_O().setFilePointer( static_cast<KaxSegment*>(m_el[0])->GetGlobalPosition(0) );
2284 #else
2285     m_es->I_O().setFilePointer( m_el[0]->GetElementPosition() + m_el[0]->ElementSize(true) - m_el[0]->GetSize() );
2286 #endif
2287     mb_dummy = config_GetInt( p_demux, "mkv-use-dummy" );
2288 }
2289
2290 EbmlElement *EbmlParser::Get( void )
2291 {
2292     int i_ulev = 0;
2293
2294     if( mi_user_level != mi_level )
2295     {
2296         return NULL;
2297     }
2298     if( m_got )
2299     {
2300         EbmlElement *ret = m_got;
2301         m_got = NULL;
2302
2303         return ret;
2304     }
2305
2306     if( m_el[mi_level] )
2307     {
2308         m_el[mi_level]->SkipData( *m_es, m_el[mi_level]->Generic().Context );
2309         if( !mb_keep )
2310         {
2311             delete m_el[mi_level];
2312         }
2313         mb_keep = VLC_FALSE;
2314     }
2315
2316     m_el[mi_level] = m_es->FindNextElement( m_el[mi_level - 1]->Generic().Context, i_ulev, 0xFFFFFFFFL, mb_dummy, 1 );
2317 //    mi_remain_size[mi_level] = m_el[mi_level]->GetSize();
2318     if( i_ulev > 0 )
2319     {
2320         while( i_ulev > 0 )
2321         {
2322             if( mi_level == 1 )
2323             {
2324                 mi_level = 0;
2325                 return NULL;
2326             }
2327
2328             delete m_el[mi_level - 1];
2329             m_got = m_el[mi_level -1] = m_el[mi_level];
2330             m_el[mi_level] = NULL;
2331
2332             mi_level--;
2333             i_ulev--;
2334         }
2335         return NULL;
2336     }
2337     else if( m_el[mi_level] == NULL )
2338     {
2339         fprintf( stderr," m_el[mi_level] == NULL\n" );
2340     }
2341
2342     return m_el[mi_level];
2343 }
2344
2345
2346 /*****************************************************************************
2347  * Tools
2348  *  * LoadCues : load the cues element and update index
2349  *
2350  *  * LoadTags : load ... the tags element
2351  *
2352  *  * InformationCreate : create all information, load tags if present
2353  *
2354  *****************************************************************************/
2355 void matroska_segment_c::LoadCues( )
2356 {
2357     int64_t     i_sav_position = es.I_O().getFilePointer();
2358     EbmlParser  *ep;
2359     EbmlElement *el, *cues;
2360
2361     /* *** Load the cue if found *** */
2362     if( i_cues_position < 0 )
2363     {
2364         msg_Warn( &sys.demuxer, "no cues/empty cues found->seek won't be precise" );
2365
2366 //        IndexAppendCluster( cluster );
2367     }
2368
2369     vlc_bool_t b_seekable;
2370
2371     stream_Control( sys.demuxer.s, STREAM_CAN_FASTSEEK, &b_seekable );
2372     if( !b_seekable )
2373         return;
2374
2375     msg_Dbg( &sys.demuxer, "loading cues" );
2376     es.I_O().setFilePointer( i_cues_position, seek_beginning );
2377     cues = es.FindNextID( KaxCues::ClassInfos, 0xFFFFFFFFL);
2378
2379     if( cues == NULL )
2380     {
2381         msg_Err( &sys.demuxer, "cannot load cues (broken seekhead or file)" );
2382         es.I_O().setFilePointer( i_sav_position, seek_beginning );
2383         return;
2384     }
2385
2386     ep = new EbmlParser( &es, cues, &sys.demuxer );
2387     while( ( el = ep->Get() ) != NULL )
2388     {
2389         if( MKV_IS_ID( el, KaxCuePoint ) )
2390         {
2391 #define idx index[i_index]
2392
2393             idx.i_track       = -1;
2394             idx.i_block_number= -1;
2395             idx.i_position    = -1;
2396             idx.i_time        = 0;
2397             idx.b_key         = VLC_TRUE;
2398
2399             ep->Down();
2400             while( ( el = ep->Get() ) != NULL )
2401             {
2402                 if( MKV_IS_ID( el, KaxCueTime ) )
2403                 {
2404                     KaxCueTime &ctime = *(KaxCueTime*)el;
2405
2406                     ctime.ReadData( es.I_O() );
2407
2408                     idx.i_time = uint64( ctime ) * i_timescale / (mtime_t)1000;
2409                 }
2410                 else if( MKV_IS_ID( el, KaxCueTrackPositions ) )
2411                 {
2412                     ep->Down();
2413                     while( ( el = ep->Get() ) != NULL )
2414                     {
2415                         if( MKV_IS_ID( el, KaxCueTrack ) )
2416                         {
2417                             KaxCueTrack &ctrack = *(KaxCueTrack*)el;
2418
2419                             ctrack.ReadData( es.I_O() );
2420                             idx.i_track = uint16( ctrack );
2421                         }
2422                         else if( MKV_IS_ID( el, KaxCueClusterPosition ) )
2423                         {
2424                             KaxCueClusterPosition &ccpos = *(KaxCueClusterPosition*)el;
2425
2426                             ccpos.ReadData( es.I_O() );
2427                             idx.i_position = segment->GetGlobalPosition( uint64( ccpos ) );
2428                         }
2429                         else if( MKV_IS_ID( el, KaxCueBlockNumber ) )
2430                         {
2431                             KaxCueBlockNumber &cbnum = *(KaxCueBlockNumber*)el;
2432
2433                             cbnum.ReadData( es.I_O() );
2434                             idx.i_block_number = uint32( cbnum );
2435                         }
2436                         else
2437                         {
2438                             msg_Dbg( &sys.demuxer, "         * Unknown (%s)", typeid(*el).name() );
2439                         }
2440                     }
2441                     ep->Up();
2442                 }
2443                 else
2444                 {
2445                     msg_Dbg( &sys.demuxer, "     * Unknown (%s)", typeid(*el).name() );
2446                 }
2447             }
2448             ep->Up();
2449
2450 #if 0
2451             msg_Dbg( &sys.demuxer, " * added time="I64Fd" pos="I64Fd
2452                      " track=%d bnum=%d", idx.i_time, idx.i_position,
2453                      idx.i_track, idx.i_block_number );
2454 #endif
2455
2456             i_index++;
2457             if( i_index >= i_index_max )
2458             {
2459                 i_index_max += 1024;
2460                 index = (mkv_index_t*)realloc( index, sizeof( mkv_index_t ) * i_index_max );
2461             }
2462 #undef idx
2463         }
2464         else
2465         {
2466             msg_Dbg( &sys.demuxer, " * Unknown (%s)", typeid(*el).name() );
2467         }
2468     }
2469     delete ep;
2470     delete cues;
2471
2472     b_cues = VLC_TRUE;
2473
2474     msg_Dbg( &sys.demuxer, "loading cues done." );
2475     es.I_O().setFilePointer( i_sav_position, seek_beginning );
2476 }
2477
2478 void matroska_segment_c::LoadTags( )
2479 {
2480     int64_t     i_sav_position = es.I_O().getFilePointer();
2481     EbmlParser  *ep;
2482     EbmlElement *el, *tags;
2483
2484     msg_Dbg( &sys.demuxer, "loading tags" );
2485     es.I_O().setFilePointer( i_tags_position, seek_beginning );
2486     tags = es.FindNextID( KaxTags::ClassInfos, 0xFFFFFFFFL);
2487
2488     if( tags == NULL )
2489     {
2490         msg_Err( &sys.demuxer, "cannot load tags (broken seekhead or file)" );
2491         es.I_O().setFilePointer( i_sav_position, seek_beginning );
2492         return;
2493     }
2494
2495     msg_Dbg( &sys.demuxer, "Tags" );
2496     ep = new EbmlParser( &es, tags, &sys.demuxer );
2497     while( ( el = ep->Get() ) != NULL )
2498     {
2499         if( MKV_IS_ID( el, KaxTag ) )
2500         {
2501             msg_Dbg( &sys.demuxer, "+ Tag" );
2502             ep->Down();
2503             while( ( el = ep->Get() ) != NULL )
2504             {
2505                 if( MKV_IS_ID( el, KaxTagTargets ) )
2506                 {
2507                     msg_Dbg( &sys.demuxer, "|   + Targets" );
2508                     ep->Down();
2509                     while( ( el = ep->Get() ) != NULL )
2510                     {
2511                         msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid( *el ).name() );
2512                     }
2513                     ep->Up();
2514                 }
2515                 else if( MKV_IS_ID( el, KaxTagGeneral ) )
2516                 {
2517                     msg_Dbg( &sys.demuxer, "|   + General" );
2518                     ep->Down();
2519                     while( ( el = ep->Get() ) != NULL )
2520                     {
2521                         msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid( *el ).name() );
2522                     }
2523                     ep->Up();
2524                 }
2525                 else if( MKV_IS_ID( el, KaxTagGenres ) )
2526                 {
2527                     msg_Dbg( &sys.demuxer, "|   + Genres" );
2528                     ep->Down();
2529                     while( ( el = ep->Get() ) != NULL )
2530                     {
2531                         msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid( *el ).name() );
2532                     }
2533                     ep->Up();
2534                 }
2535                 else if( MKV_IS_ID( el, KaxTagAudioSpecific ) )
2536                 {
2537                     msg_Dbg( &sys.demuxer, "|   + Audio Specific" );
2538                     ep->Down();
2539                     while( ( el = ep->Get() ) != NULL )
2540                     {
2541                         msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid( *el ).name() );
2542                     }
2543                     ep->Up();
2544                 }
2545                 else if( MKV_IS_ID( el, KaxTagImageSpecific ) )
2546                 {
2547                     msg_Dbg( &sys.demuxer, "|   + Images Specific" );
2548                     ep->Down();
2549                     while( ( el = ep->Get() ) != NULL )
2550                     {
2551                         msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid( *el ).name() );
2552                     }
2553                     ep->Up();
2554                 }
2555                 else if( MKV_IS_ID( el, KaxTagMultiComment ) )
2556                 {
2557                     msg_Dbg( &sys.demuxer, "|   + Multi Comment" );
2558                 }
2559                 else if( MKV_IS_ID( el, KaxTagMultiCommercial ) )
2560                 {
2561                     msg_Dbg( &sys.demuxer, "|   + Multi Commercial" );
2562                 }
2563                 else if( MKV_IS_ID( el, KaxTagMultiDate ) )
2564                 {
2565                     msg_Dbg( &sys.demuxer, "|   + Multi Date" );
2566                 }
2567                 else if( MKV_IS_ID( el, KaxTagMultiEntity ) )
2568                 {
2569                     msg_Dbg( &sys.demuxer, "|   + Multi Entity" );
2570                 }
2571                 else if( MKV_IS_ID( el, KaxTagMultiIdentifier ) )
2572                 {
2573                     msg_Dbg( &sys.demuxer, "|   + Multi Identifier" );
2574                 }
2575                 else if( MKV_IS_ID( el, KaxTagMultiLegal ) )
2576                 {
2577                     msg_Dbg( &sys.demuxer, "|   + Multi Legal" );
2578                 }
2579                 else if( MKV_IS_ID( el, KaxTagMultiTitle ) )
2580                 {
2581                     msg_Dbg( &sys.demuxer, "|   + Multi Title" );
2582                 }
2583                 else
2584                 {
2585                     msg_Dbg( &sys.demuxer, "|   + Unknown (%s)", typeid( *el ).name() );
2586                 }
2587             }
2588             ep->Up();
2589         }
2590         else
2591         {
2592             msg_Dbg( &sys.demuxer, "+ Unknown (%s)", typeid( *el ).name() );
2593         }
2594     }
2595     delete ep;
2596     delete tags;
2597
2598     msg_Dbg( &sys.demuxer, "loading tags done." );
2599     es.I_O().setFilePointer( i_sav_position, seek_beginning );
2600 }
2601
2602 /*****************************************************************************
2603  * ParseSeekHead:
2604  *****************************************************************************/
2605 void matroska_segment_c::ParseSeekHead( KaxSeekHead *seekhead )
2606 {
2607     EbmlElement *el;
2608     size_t i, j;
2609     int i_upper_level = 0;
2610
2611     msg_Dbg( &sys.demuxer, "|   + Seek head" );
2612
2613     /* Master elements */
2614     seekhead->Read( es, seekhead->Generic().Context, i_upper_level, el, true );
2615
2616     for( i = 0; i < seekhead->ListSize(); i++ )
2617     {
2618         EbmlElement *l = (*seekhead)[i];
2619
2620         if( MKV_IS_ID( l, KaxSeek ) )
2621         {
2622             EbmlMaster *sk = static_cast<EbmlMaster *>(l);
2623             EbmlId id = EbmlVoid::ClassInfos.GlobalId;
2624             int64_t i_pos = -1;
2625
2626             for( j = 0; j < sk->ListSize(); j++ )
2627             {
2628                 EbmlElement *l = (*sk)[j];
2629
2630                 if( MKV_IS_ID( l, KaxSeekID ) )
2631                 {
2632                     KaxSeekID &sid = *(KaxSeekID*)l;
2633                     id = EbmlId( sid.GetBuffer(), sid.GetSize() );
2634                 }
2635                 else if( MKV_IS_ID( l, KaxSeekPosition ) )
2636                 {
2637                     KaxSeekPosition &spos = *(KaxSeekPosition*)l;
2638                     i_pos = uint64( spos );
2639                 }
2640                 else
2641                 {
2642                     msg_Dbg( &sys.demuxer, "|   |   |   + Unknown (%s)", typeid(*l).name() );
2643                 }
2644             }
2645
2646             if( i_pos >= 0 )
2647             {
2648                 if( id == KaxCues::ClassInfos.GlobalId )
2649                 {
2650                     msg_Dbg( &sys.demuxer, "|   |   |   = cues at "I64Fd, i_pos );
2651                     i_cues_position = segment->GetGlobalPosition( i_pos );
2652                 }
2653                 else if( id == KaxChapters::ClassInfos.GlobalId )
2654                 {
2655                     msg_Dbg( &sys.demuxer, "|   |   |   = chapters at "I64Fd, i_pos );
2656                     i_chapters_position = segment->GetGlobalPosition( i_pos );
2657                 }
2658                 else if( id == KaxTags::ClassInfos.GlobalId )
2659                 {
2660                     msg_Dbg( &sys.demuxer, "|   |   |   = tags at "I64Fd, i_pos );
2661                     i_tags_position = segment->GetGlobalPosition( i_pos );
2662                 }
2663             }
2664         }
2665         else
2666         {
2667             msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid(*l).name() );
2668         }
2669     }
2670 }
2671
2672 /*****************************************************************************
2673  * ParseTrackEntry:
2674  *****************************************************************************/
2675 void matroska_segment_c::ParseTrackEntry( KaxTrackEntry *m )
2676 {
2677     size_t i, j, k, n;
2678
2679     mkv_track_t *tk;
2680
2681     msg_Dbg( &sys.demuxer, "|   |   + Track Entry" );
2682
2683     tk = new mkv_track_t();
2684     tracks.push_back( tk );
2685
2686     /* Init the track */
2687     memset( tk, 0, sizeof( mkv_track_t ) );
2688
2689     es_format_Init( &tk->fmt, UNKNOWN_ES, 0 );
2690     tk->fmt.psz_language = strdup("English");
2691     tk->fmt.psz_description = NULL;
2692
2693     tk->b_default = VLC_TRUE;
2694     tk->b_enabled = VLC_TRUE;
2695     tk->b_silent = VLC_FALSE;
2696     tk->i_number = tracks.size() - 1;
2697     tk->i_extra_data = 0;
2698     tk->p_extra_data = NULL;
2699     tk->psz_codec = NULL;
2700     tk->i_default_duration = 0;
2701     tk->f_timecodescale = 1.0;
2702
2703     tk->b_inited = VLC_FALSE;
2704     tk->i_data_init = 0;
2705     tk->p_data_init = NULL;
2706
2707     tk->psz_codec_name = NULL;
2708     tk->psz_codec_settings = NULL;
2709     tk->psz_codec_info_url = NULL;
2710     tk->psz_codec_download_url = NULL;
2711     
2712     tk->i_compression_type = MATROSKA_COMPRESSION_NONE;
2713
2714     for( i = 0; i < m->ListSize(); i++ )
2715     {
2716         EbmlElement *l = (*m)[i];
2717
2718         if( MKV_IS_ID( l, KaxTrackNumber ) )
2719         {
2720             KaxTrackNumber &tnum = *(KaxTrackNumber*)l;
2721
2722             tk->i_number = uint32( tnum );
2723             msg_Dbg( &sys.demuxer, "|   |   |   + Track Number=%u", uint32( tnum ) );
2724         }
2725         else  if( MKV_IS_ID( l, KaxTrackUID ) )
2726         {
2727             KaxTrackUID &tuid = *(KaxTrackUID*)l;
2728
2729             msg_Dbg( &sys.demuxer, "|   |   |   + Track UID=%u",  uint32( tuid ) );
2730         }
2731         else  if( MKV_IS_ID( l, KaxTrackType ) )
2732         {
2733             char *psz_type;
2734             KaxTrackType &ttype = *(KaxTrackType*)l;
2735
2736             switch( uint8(ttype) )
2737             {
2738                 case track_audio:
2739                     psz_type = "audio";
2740                     tk->fmt.i_cat = AUDIO_ES;
2741                     break;
2742                 case track_video:
2743                     psz_type = "video";
2744                     tk->fmt.i_cat = VIDEO_ES;
2745                     break;
2746                 case track_subtitle:
2747                     psz_type = "subtitle";
2748                     tk->fmt.i_cat = SPU_ES;
2749                     break;
2750                 default:
2751                     psz_type = "unknown";
2752                     tk->fmt.i_cat = UNKNOWN_ES;
2753                     break;
2754             }
2755
2756             msg_Dbg( &sys.demuxer, "|   |   |   + Track Type=%s", psz_type );
2757         }
2758 //        else  if( EbmlId( *l ) == KaxTrackFlagEnabled::ClassInfos.GlobalId )
2759 //        {
2760 //            KaxTrackFlagEnabled &fenb = *(KaxTrackFlagEnabled*)l;
2761
2762 //            tk->b_enabled = uint32( fenb );
2763 //            msg_Dbg( &sys.demuxer, "|   |   |   + Track Enabled=%u",
2764 //                     uint32( fenb )  );
2765 //        }
2766         else  if( MKV_IS_ID( l, KaxTrackFlagDefault ) )
2767         {
2768             KaxTrackFlagDefault &fdef = *(KaxTrackFlagDefault*)l;
2769
2770             tk->b_default = uint32( fdef );
2771             msg_Dbg( &sys.demuxer, "|   |   |   + Track Default=%u", uint32( fdef )  );
2772         }
2773         else  if( MKV_IS_ID( l, KaxTrackFlagLacing ) )
2774         {
2775             KaxTrackFlagLacing &lac = *(KaxTrackFlagLacing*)l;
2776
2777             msg_Dbg( &sys.demuxer, "|   |   |   + Track Lacing=%d", uint32( lac ) );
2778         }
2779         else  if( MKV_IS_ID( l, KaxTrackMinCache ) )
2780         {
2781             KaxTrackMinCache &cmin = *(KaxTrackMinCache*)l;
2782
2783             msg_Dbg( &sys.demuxer, "|   |   |   + Track MinCache=%d", uint32( cmin ) );
2784         }
2785         else  if( MKV_IS_ID( l, KaxTrackMaxCache ) )
2786         {
2787             KaxTrackMaxCache &cmax = *(KaxTrackMaxCache*)l;
2788
2789             msg_Dbg( &sys.demuxer, "|   |   |   + Track MaxCache=%d", uint32( cmax ) );
2790         }
2791         else  if( MKV_IS_ID( l, KaxTrackDefaultDuration ) )
2792         {
2793             KaxTrackDefaultDuration &defd = *(KaxTrackDefaultDuration*)l;
2794
2795             tk->i_default_duration = uint64(defd);
2796             msg_Dbg( &sys.demuxer, "|   |   |   + Track Default Duration="I64Fd, uint64(defd) );
2797         }
2798         else  if( MKV_IS_ID( l, KaxTrackTimecodeScale ) )
2799         {
2800             KaxTrackTimecodeScale &ttcs = *(KaxTrackTimecodeScale*)l;
2801
2802             tk->f_timecodescale = float( ttcs );
2803             msg_Dbg( &sys.demuxer, "|   |   |   + Track TimeCodeScale=%f", tk->f_timecodescale );
2804         }
2805         else if( MKV_IS_ID( l, KaxTrackName ) )
2806         {
2807             KaxTrackName &tname = *(KaxTrackName*)l;
2808
2809             tk->fmt.psz_description = UTF8ToStr( UTFstring( tname ) );
2810             msg_Dbg( &sys.demuxer, "|   |   |   + Track Name=%s", tk->fmt.psz_description );
2811         }
2812         else  if( MKV_IS_ID( l, KaxTrackLanguage ) )
2813         {
2814             KaxTrackLanguage &lang = *(KaxTrackLanguage*)l;
2815
2816             tk->fmt.psz_language = strdup( string( lang ).c_str() );
2817             msg_Dbg( &sys.demuxer,
2818                      "|   |   |   + Track Language=`%s'", tk->fmt.psz_language );
2819         }
2820         else  if( MKV_IS_ID( l, KaxCodecID ) )
2821         {
2822             KaxCodecID &codecid = *(KaxCodecID*)l;
2823
2824             tk->psz_codec = strdup( string( codecid ).c_str() );
2825             msg_Dbg( &sys.demuxer, "|   |   |   + Track CodecId=%s", string( codecid ).c_str() );
2826         }
2827         else  if( MKV_IS_ID( l, KaxCodecPrivate ) )
2828         {
2829             KaxCodecPrivate &cpriv = *(KaxCodecPrivate*)l;
2830
2831             tk->i_extra_data = cpriv.GetSize();
2832             if( tk->i_extra_data > 0 )
2833             {
2834                 tk->p_extra_data = (uint8_t*)malloc( tk->i_extra_data );
2835                 memcpy( tk->p_extra_data, cpriv.GetBuffer(), tk->i_extra_data );
2836             }
2837             msg_Dbg( &sys.demuxer, "|   |   |   + Track CodecPrivate size="I64Fd, cpriv.GetSize() );
2838         }
2839         else if( MKV_IS_ID( l, KaxCodecName ) )
2840         {
2841             KaxCodecName &cname = *(KaxCodecName*)l;
2842
2843             tk->psz_codec_name = UTF8ToStr( UTFstring( cname ) );
2844             msg_Dbg( &sys.demuxer, "|   |   |   + Track Codec Name=%s", tk->psz_codec_name );
2845         }
2846         else if( MKV_IS_ID( l, KaxContentEncodings ) )
2847         {
2848             EbmlMaster *cencs = static_cast<EbmlMaster*>(l);
2849             MkvTree( sys.demuxer, 3, "Content Encodings" );
2850             for( j = 0; j < cencs->ListSize(); j++ )
2851             {
2852                 EbmlElement *l2 = (*cencs)[j];
2853                 if( MKV_IS_ID( l2, KaxContentEncoding ) )
2854                 {
2855                     MkvTree( sys.demuxer, 4, "Content Encoding" );
2856                     EbmlMaster *cenc = static_cast<EbmlMaster*>(l2);
2857                     for( k = 0; k < cenc->ListSize(); k++ )
2858                     {
2859                         EbmlElement *l3 = (*cenc)[k];
2860                         if( MKV_IS_ID( l3, KaxContentEncodingOrder ) )
2861                         {
2862                             KaxContentEncodingOrder &encord = *(KaxContentEncodingOrder*)l3;
2863                             MkvTree( sys.demuxer, 5, "Order: %i", uint32( encord ) );
2864                         }
2865                         else if( MKV_IS_ID( l3, KaxContentEncodingScope ) )
2866                         {
2867                             KaxContentEncodingScope &encscope = *(KaxContentEncodingScope*)l3;
2868                             MkvTree( sys.demuxer, 5, "Scope: %i", uint32( encscope ) );
2869                         }
2870                         else if( MKV_IS_ID( l3, KaxContentEncodingType ) )
2871                         {
2872                             KaxContentEncodingType &enctype = *(KaxContentEncodingType*)l3;
2873                             MkvTree( sys.demuxer, 5, "Type: %i", uint32( enctype ) );
2874                         }
2875                         else if( MKV_IS_ID( l3, KaxContentCompression ) )
2876                         {
2877                             EbmlMaster *compr = static_cast<EbmlMaster*>(l3);
2878                             MkvTree( sys.demuxer, 5, "Content Compression" );
2879                             for( n = 0; n < compr->ListSize(); n++ )
2880                             {
2881                                 EbmlElement *l4 = (*compr)[n];
2882                                 if( MKV_IS_ID( l4, KaxContentCompAlgo ) )
2883                                 {
2884                                     KaxContentCompAlgo &compalg = *(KaxContentCompAlgo*)l4;
2885                                     MkvTree( sys.demuxer, 6, "Compression Algorithm: %i", uint32(compalg) );
2886                                     if( uint32( compalg ) == 0 )
2887                                     {
2888                                         tk->i_compression_type = MATROSKA_COMPRESSION_ZLIB;
2889                                     }
2890                                 }
2891                                 else
2892                                 {
2893                                     MkvTree( sys.demuxer, 6, "Unknown (%s)", typeid(*l4).name() );
2894                                 }
2895                             }
2896                         }
2897
2898                         else
2899                         {
2900                             MkvTree( sys.demuxer, 5, "Unknown (%s)", typeid(*l3).name() );
2901                         }
2902                     }
2903                     
2904                 }
2905                 else
2906                 {
2907                     MkvTree( sys.demuxer, 4, "Unknown (%s)", typeid(*l2).name() );
2908                 }
2909             }
2910                 
2911         }
2912 //        else if( EbmlId( *l ) == KaxCodecSettings::ClassInfos.GlobalId )
2913 //        {
2914 //            KaxCodecSettings &cset = *(KaxCodecSettings*)l;
2915
2916 //            tk->psz_codec_settings = UTF8ToStr( UTFstring( cset ) );
2917 //            msg_Dbg( &sys.demuxer, "|   |   |   + Track Codec Settings=%s", tk->psz_codec_settings );
2918 //        }
2919 //        else if( EbmlId( *l ) == KaxCodecInfoURL::ClassInfos.GlobalId )
2920 //        {
2921 //            KaxCodecInfoURL &ciurl = *(KaxCodecInfoURL*)l;
2922
2923 //            tk->psz_codec_info_url = strdup( string( ciurl ).c_str() );
2924 //            msg_Dbg( &sys.demuxer, "|   |   |   + Track Codec Info URL=%s", tk->psz_codec_info_url );
2925 //        }
2926 //        else if( EbmlId( *l ) == KaxCodecDownloadURL::ClassInfos.GlobalId )
2927 //        {
2928 //            KaxCodecDownloadURL &cdurl = *(KaxCodecDownloadURL*)l;
2929
2930 //            tk->psz_codec_download_url = strdup( string( cdurl ).c_str() );
2931 //            msg_Dbg( &sys.demuxer, "|   |   |   + Track Codec Info URL=%s", tk->psz_codec_download_url );
2932 //        }
2933 //        else if( EbmlId( *l ) == KaxCodecDecodeAll::ClassInfos.GlobalId )
2934 //        {
2935 //            KaxCodecDecodeAll &cdall = *(KaxCodecDecodeAll*)l;
2936
2937 //            msg_Dbg( &sys.demuxer, "|   |   |   + Track Codec Decode All=%u <== UNUSED", uint8( cdall ) );
2938 //        }
2939 //        else if( EbmlId( *l ) == KaxTrackOverlay::ClassInfos.GlobalId )
2940 //        {
2941 //            KaxTrackOverlay &tovr = *(KaxTrackOverlay*)l;
2942
2943 //            msg_Dbg( &sys.demuxer, "|   |   |   + Track Overlay=%u <== UNUSED", uint32( tovr ) );
2944 //        }
2945         else  if( MKV_IS_ID( l, KaxTrackVideo ) )
2946         {
2947             EbmlMaster *tkv = static_cast<EbmlMaster*>(l);
2948             unsigned int j;
2949
2950             msg_Dbg( &sys.demuxer, "|   |   |   + Track Video" );
2951             tk->f_fps = 0.0;
2952
2953             for( j = 0; j < tkv->ListSize(); j++ )
2954             {
2955                 EbmlElement *l = (*tkv)[j];
2956 //                if( EbmlId( *el4 ) == KaxVideoFlagInterlaced::ClassInfos.GlobalId )
2957 //                {
2958 //                    KaxVideoFlagInterlaced &fint = *(KaxVideoFlagInterlaced*)el4;
2959
2960 //                    msg_Dbg( &sys.demuxer, "|   |   |   |   + Track Video Interlaced=%u", uint8( fint ) );
2961 //                }
2962 //                else if( EbmlId( *el4 ) == KaxVideoStereoMode::ClassInfos.GlobalId )
2963 //                {
2964 //                    KaxVideoStereoMode &stereo = *(KaxVideoStereoMode*)el4;
2965
2966 //                    msg_Dbg( &sys.demuxer, "|   |   |   |   + Track Video Stereo Mode=%u", uint8( stereo ) );
2967 //                }
2968 //                else
2969                 if( MKV_IS_ID( l, KaxVideoPixelWidth ) )
2970                 {
2971                     KaxVideoPixelWidth &vwidth = *(KaxVideoPixelWidth*)l;
2972
2973                     tk->fmt.video.i_width = uint16( vwidth );
2974                     msg_Dbg( &sys.demuxer, "|   |   |   |   + width=%d", uint16( vwidth ) );
2975                 }
2976                 else if( MKV_IS_ID( l, KaxVideoPixelHeight ) )
2977                 {
2978                     KaxVideoPixelWidth &vheight = *(KaxVideoPixelWidth*)l;
2979
2980                     tk->fmt.video.i_height = uint16( vheight );
2981                     msg_Dbg( &sys.demuxer, "|   |   |   |   + height=%d", uint16( vheight ) );
2982                 }
2983                 else if( MKV_IS_ID( l, KaxVideoDisplayWidth ) )
2984                 {
2985                     KaxVideoDisplayWidth &vwidth = *(KaxVideoDisplayWidth*)l;
2986
2987                     tk->fmt.video.i_visible_width = uint16( vwidth );
2988                     msg_Dbg( &sys.demuxer, "|   |   |   |   + display width=%d", uint16( vwidth ) );
2989                 }
2990                 else if( MKV_IS_ID( l, KaxVideoDisplayHeight ) )
2991                 {
2992                     KaxVideoDisplayWidth &vheight = *(KaxVideoDisplayWidth*)l;
2993
2994                     tk->fmt.video.i_visible_height = uint16( vheight );
2995                     msg_Dbg( &sys.demuxer, "|   |   |   |   + display height=%d", uint16( vheight ) );
2996                 }
2997                 else if( MKV_IS_ID( l, KaxVideoFrameRate ) )
2998                 {
2999                     KaxVideoFrameRate &vfps = *(KaxVideoFrameRate*)l;
3000
3001                     tk->f_fps = float( vfps );
3002                     msg_Dbg( &sys.demuxer, "   |   |   |   + fps=%f", float( vfps ) );
3003                 }
3004 //                else if( EbmlId( *l ) == KaxVideoDisplayUnit::ClassInfos.GlobalId )
3005 //                {
3006 //                     KaxVideoDisplayUnit &vdmode = *(KaxVideoDisplayUnit*)l;
3007
3008 //                    msg_Dbg( &sys.demuxer, "|   |   |   |   + Track Video Display Unit=%s",
3009 //                             uint8( vdmode ) == 0 ? "pixels" : ( uint8( vdmode ) == 1 ? "centimeters": "inches" ) );
3010 //                }
3011 //                else if( EbmlId( *l ) == KaxVideoAspectRatio::ClassInfos.GlobalId )
3012 //                {
3013 //                    KaxVideoAspectRatio &ratio = *(KaxVideoAspectRatio*)l;
3014
3015 //                    msg_Dbg( &sys.demuxer, "   |   |   |   + Track Video Aspect Ratio Type=%u", uint8( ratio ) );
3016 //                }
3017 //                else if( EbmlId( *l ) == KaxVideoGamma::ClassInfos.GlobalId )
3018 //                {
3019 //                    KaxVideoGamma &gamma = *(KaxVideoGamma*)l;
3020
3021 //                    msg_Dbg( &sys.demuxer, "   |   |   |   + fps=%f", float( gamma ) );
3022 //                }
3023                 else
3024                 {
3025                     msg_Dbg( &sys.demuxer, "|   |   |   |   + Unknown (%s)", typeid(*l).name() );
3026                 }
3027             }
3028             if ( tk->fmt.video.i_visible_height && tk->fmt.video.i_visible_width )
3029                 tk->fmt.video.i_aspect = VOUT_ASPECT_FACTOR * tk->fmt.video.i_visible_width / tk->fmt.video.i_visible_height;
3030         }
3031         else  if( MKV_IS_ID( l, KaxTrackAudio ) )
3032         {
3033             EbmlMaster *tka = static_cast<EbmlMaster*>(l);
3034             unsigned int j;
3035
3036             msg_Dbg( &sys.demuxer, "|   |   |   + Track Audio" );
3037
3038             for( j = 0; j < tka->ListSize(); j++ )
3039             {
3040                 EbmlElement *l = (*tka)[j];
3041
3042                 if( MKV_IS_ID( l, KaxAudioSamplingFreq ) )
3043                 {
3044                     KaxAudioSamplingFreq &afreq = *(KaxAudioSamplingFreq*)l;
3045
3046                     tk->fmt.audio.i_rate = (int)float( afreq );
3047                     msg_Dbg( &sys.demuxer, "|   |   |   |   + afreq=%d", tk->fmt.audio.i_rate );
3048                 }
3049                 else if( MKV_IS_ID( l, KaxAudioChannels ) )
3050                 {
3051                     KaxAudioChannels &achan = *(KaxAudioChannels*)l;
3052
3053                     tk->fmt.audio.i_channels = uint8( achan );
3054                     msg_Dbg( &sys.demuxer, "|   |   |   |   + achan=%u", uint8( achan ) );
3055                 }
3056                 else if( MKV_IS_ID( l, KaxAudioBitDepth ) )
3057                 {
3058                     KaxAudioBitDepth &abits = *(KaxAudioBitDepth*)l;
3059
3060                     tk->fmt.audio.i_bitspersample = uint8( abits );
3061                     msg_Dbg( &sys.demuxer, "|   |   |   |   + abits=%u", uint8( abits ) );
3062                 }
3063                 else
3064                 {
3065                     msg_Dbg( &sys.demuxer, "|   |   |   |   + Unknown (%s)", typeid(*l).name() );
3066                 }
3067             }
3068         }
3069         else
3070         {
3071             msg_Dbg( &sys.demuxer, "|   |   |   + Unknown (%s)",
3072                      typeid(*l).name() );
3073         }
3074     }
3075 }
3076
3077 /*****************************************************************************
3078  * ParseTracks:
3079  *****************************************************************************/
3080 void matroska_segment_c::ParseTracks( KaxTracks *tracks )
3081 {
3082     EbmlElement *el;
3083     unsigned int i;
3084     int i_upper_level = 0;
3085
3086     msg_Dbg( &sys.demuxer, "|   + Tracks" );
3087
3088     /* Master elements */
3089     tracks->Read( es, tracks->Generic().Context, i_upper_level, el, true );
3090
3091     for( i = 0; i < tracks->ListSize(); i++ )
3092     {
3093         EbmlElement *l = (*tracks)[i];
3094
3095         if( MKV_IS_ID( l, KaxTrackEntry ) )
3096         {
3097             ParseTrackEntry( static_cast<KaxTrackEntry *>(l) );
3098         }
3099         else
3100         {
3101             msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid(*l).name() );
3102         }
3103     }
3104 }
3105
3106 /*****************************************************************************
3107  * ParseInfo:
3108  *****************************************************************************/
3109 void matroska_segment_c::ParseInfo( KaxInfo *info )
3110 {
3111     EbmlElement *el;
3112     EbmlMaster  *m;
3113     size_t i, j;
3114     int i_upper_level = 0;
3115
3116     msg_Dbg( &sys.demuxer, "|   + Information" );
3117
3118     /* Master elements */
3119     m = static_cast<EbmlMaster *>(info);
3120     m->Read( es, info->Generic().Context, i_upper_level, el, true );
3121
3122     for( i = 0; i < m->ListSize(); i++ )
3123     {
3124         EbmlElement *l = (*m)[i];
3125
3126         if( MKV_IS_ID( l, KaxSegmentUID ) )
3127         {
3128             segment_uid = *(new KaxSegmentUID(*static_cast<KaxSegmentUID*>(l)));
3129
3130             msg_Dbg( &sys.demuxer, "|   |   + UID=%d", *(uint32*)segment_uid.GetBuffer() );
3131         }
3132         else if( MKV_IS_ID( l, KaxPrevUID ) )
3133         {
3134             prev_segment_uid = *(new KaxPrevUID(*static_cast<KaxPrevUID*>(l)));
3135
3136             msg_Dbg( &sys.demuxer, "|   |   + PrevUID=%d", *(uint32*)prev_segment_uid.GetBuffer() );
3137         }
3138         else if( MKV_IS_ID( l, KaxNextUID ) )
3139         {
3140             next_segment_uid = *(new KaxNextUID(*static_cast<KaxNextUID*>(l)));
3141
3142             msg_Dbg( &sys.demuxer, "|   |   + NextUID=%d", *(uint32*)next_segment_uid.GetBuffer() );
3143         }
3144         else if( MKV_IS_ID( l, KaxTimecodeScale ) )
3145         {
3146             KaxTimecodeScale &tcs = *(KaxTimecodeScale*)l;
3147
3148             i_timescale = uint64(tcs);
3149
3150             msg_Dbg( &sys.demuxer, "|   |   + TimecodeScale="I64Fd,
3151                      i_timescale );
3152         }
3153         else if( MKV_IS_ID( l, KaxDuration ) )
3154         {
3155             KaxDuration &dur = *(KaxDuration*)l;
3156
3157             i_duration = mtime_t( double( dur ) );
3158
3159             msg_Dbg( &sys.demuxer, "|   |   + Duration="I64Fd,
3160                      i_duration );
3161         }
3162         else if( MKV_IS_ID( l, KaxMuxingApp ) )
3163         {
3164             KaxMuxingApp &mapp = *(KaxMuxingApp*)l;
3165
3166             psz_muxing_application = UTF8ToStr( UTFstring( mapp ) );
3167
3168             msg_Dbg( &sys.demuxer, "|   |   + Muxing Application=%s",
3169                      psz_muxing_application );
3170         }
3171         else if( MKV_IS_ID( l, KaxWritingApp ) )
3172         {
3173             KaxWritingApp &wapp = *(KaxWritingApp*)l;
3174
3175             psz_writing_application = UTF8ToStr( UTFstring( wapp ) );
3176
3177             msg_Dbg( &sys.demuxer, "|   |   + Writing Application=%s",
3178                      psz_writing_application );
3179         }
3180         else if( MKV_IS_ID( l, KaxSegmentFilename ) )
3181         {
3182             KaxSegmentFilename &sfn = *(KaxSegmentFilename*)l;
3183
3184             psz_segment_filename = UTF8ToStr( UTFstring( sfn ) );
3185
3186             msg_Dbg( &sys.demuxer, "|   |   + Segment Filename=%s",
3187                      psz_segment_filename );
3188         }
3189         else if( MKV_IS_ID( l, KaxTitle ) )
3190         {
3191             KaxTitle &title = *(KaxTitle*)l;
3192
3193             psz_title = UTF8ToStr( UTFstring( title ) );
3194
3195             msg_Dbg( &sys.demuxer, "|   |   + Title=%s", psz_title );
3196         }
3197         else if( MKV_IS_ID( l, KaxSegmentFamily ) )
3198         {
3199             KaxSegmentFamily *uid = static_cast<KaxSegmentFamily*>(l);
3200
3201             families.push_back(*uid);
3202
3203             msg_Dbg( &sys.demuxer, "|   |   + family=%d", *(uint32*)uid->GetBuffer() );
3204         }
3205 #if defined( HAVE_GMTIME_R ) && !defined( SYS_DARWIN )
3206         else if( MKV_IS_ID( l, KaxDateUTC ) )
3207         {
3208             KaxDateUTC &date = *(KaxDateUTC*)l;
3209             time_t i_date;
3210             struct tm tmres;
3211             char   buffer[256];
3212
3213             i_date = date.GetEpochDate();
3214             memset( buffer, 0, 256 );
3215             if( gmtime_r( &i_date, &tmres ) &&
3216                 asctime_r( &tmres, buffer ) )
3217             {
3218                 buffer[strlen( buffer)-1]= '\0';
3219                 psz_date_utc = strdup( buffer );
3220                 msg_Dbg( &sys.demuxer, "|   |   + Date=%s", psz_date_utc );
3221             }
3222         }
3223 #endif
3224 #if LIBMATROSKA_VERSION >= 0x000704
3225         else if( MKV_IS_ID( l, KaxChapterTranslate ) )
3226         {
3227             KaxChapterTranslate *p_trans = static_cast<KaxChapterTranslate*>( l );
3228             chapter_translation_c translated;
3229
3230             p_trans->Read( es, p_trans->Generic().Context, i_upper_level, el, true );
3231             for( j = 0; j < p_trans->ListSize(); j++ )
3232             {
3233                 EbmlElement *l = (*p_trans)[j];
3234
3235                 if( MKV_IS_ID( l, KaxChapterTranslateEditionUID ) )
3236                 {
3237                     translated.editions.push_back( uint64( *static_cast<KaxChapterTranslateEditionUID*>( l ) ) );
3238                 }
3239                 else if( MKV_IS_ID( l, KaxChapterTranslateCodec ) )
3240                 {
3241                     translated.codec_id = uint32( *static_cast<KaxChapterTranslateCodec*>( l ) );
3242                 }
3243                 else if( MKV_IS_ID( l, KaxChapterTranslateID ) )
3244                 {
3245                     translated.translated = *( new KaxChapterTranslateID( *static_cast<KaxChapterTranslateID*>( l ) ) );
3246                 }
3247             }
3248
3249             translations.push_back( translated );
3250         }
3251 #endif
3252         else
3253         {
3254             msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid(*l).name() );
3255         }
3256     }
3257
3258     double f_dur = double(i_duration) * double(i_timescale) / 1000000.0;
3259     i_duration = mtime_t(f_dur);
3260 }
3261
3262
3263 /*****************************************************************************
3264  * ParseChapterAtom
3265  *****************************************************************************/
3266 void matroska_segment_c::ParseChapterAtom( int i_level, KaxChapterAtom *ca, chapter_item_c & chapters )
3267 {
3268     size_t i, j;
3269
3270     if( sys.title == NULL )
3271     {
3272         sys.title = vlc_input_title_New();
3273     }
3274
3275     msg_Dbg( &sys.demuxer, "|   |   |   + ChapterAtom (level=%d)", i_level );
3276     for( i = 0; i < ca->ListSize(); i++ )
3277     {
3278         EbmlElement *l = (*ca)[i];
3279
3280         if( MKV_IS_ID( l, KaxChapterUID ) )
3281         {
3282             chapters.i_uid = uint64_t(*(KaxChapterUID*)l);
3283             msg_Dbg( &sys.demuxer, "|   |   |   |   + ChapterUID: %lld", chapters.i_uid );
3284         }
3285         else if( MKV_IS_ID( l, KaxChapterFlagHidden ) )
3286         {
3287             KaxChapterFlagHidden &flag =*(KaxChapterFlagHidden*)l;
3288             chapters.b_display_seekpoint = uint8( flag ) == 0;
3289
3290             msg_Dbg( &sys.demuxer, "|   |   |   |   + ChapterFlagHidden: %s", chapters.b_display_seekpoint ? "no":"yes" );
3291         }
3292         else if( MKV_IS_ID( l, KaxChapterTimeStart ) )
3293         {
3294             KaxChapterTimeStart &start =*(KaxChapterTimeStart*)l;
3295             chapters.i_start_time = uint64( start ) / I64C(1000);
3296
3297             msg_Dbg( &sys.demuxer, "|   |   |   |   + ChapterTimeStart: %lld", chapters.i_start_time );
3298         }
3299         else if( MKV_IS_ID( l, KaxChapterTimeEnd ) )
3300         {
3301             KaxChapterTimeEnd &end =*(KaxChapterTimeEnd*)l;
3302             chapters.i_end_time = uint64( end ) / I64C(1000);
3303
3304             msg_Dbg( &sys.demuxer, "|   |   |   |   + ChapterTimeEnd: %lld", chapters.i_end_time );
3305         }
3306         else if( MKV_IS_ID( l, KaxChapterDisplay ) )
3307         {
3308             EbmlMaster *cd = static_cast<EbmlMaster *>(l);
3309
3310             msg_Dbg( &sys.demuxer, "|   |   |   |   + ChapterDisplay" );
3311             for( j = 0; j < cd->ListSize(); j++ )
3312             {
3313                 EbmlElement *l= (*cd)[j];
3314
3315                 if( MKV_IS_ID( l, KaxChapterString ) )
3316                 {
3317                     int k;
3318
3319                     KaxChapterString &name =*(KaxChapterString*)l;
3320                     for (k = 0; k < i_level; k++)
3321                         chapters.psz_name += '+';
3322                     chapters.psz_name += ' ';
3323                     chapters.psz_name += UTF8ToStr( UTFstring( name ) );
3324
3325                     msg_Dbg( &sys.demuxer, "|   |   |   |   |    + ChapterString '%s'", UTF8ToStr(UTFstring(name)) );
3326                 }
3327                 else if( MKV_IS_ID( l, KaxChapterLanguage ) )
3328                 {
3329                     KaxChapterLanguage &lang =*(KaxChapterLanguage*)l;
3330                     const char *psz = string( lang ).c_str();
3331
3332                     msg_Dbg( &sys.demuxer, "|   |   |   |   |    + ChapterLanguage '%s'", psz );
3333                 }
3334                 else if( MKV_IS_ID( l, KaxChapterCountry ) )
3335                 {
3336                     KaxChapterCountry &ct =*(KaxChapterCountry*)l;
3337                     const char *psz = string( ct ).c_str();
3338
3339                     msg_Dbg( &sys.demuxer, "|   |   |   |   |    + ChapterCountry '%s'", psz );
3340                 }
3341             }
3342         }
3343         else if( MKV_IS_ID( l, KaxChapterProcess ) )
3344         {
3345             msg_Dbg( &sys.demuxer, "|   |   |   |   + ChapterProcess" );
3346
3347             KaxChapterProcess *cp = static_cast<KaxChapterProcess *>(l);
3348             chapter_codec_cmds_c *p_ccodec = NULL;
3349
3350             for( j = 0; j < cp->ListSize(); j++ )
3351             {
3352                 EbmlElement *k= (*cp)[j];
3353
3354                 if( MKV_IS_ID( k, KaxChapterProcessCodecID ) )
3355                 {
3356                     KaxChapterProcessCodecID *p_codec_id = static_cast<KaxChapterProcessCodecID*>( k );
3357                     if ( uint32(*p_codec_id) == 0 )
3358                         p_ccodec = new matroska_script_codec_c();
3359                     else if ( uint32(*p_codec_id) == 1 )
3360                         p_ccodec = new dvd_chapter_codec_c( sys );
3361                     break;
3362                 }
3363             }
3364
3365             if ( p_ccodec != NULL )
3366             {
3367                 for( j = 0; j < cp->ListSize(); j++ )
3368                 {
3369                     EbmlElement *k= (*cp)[j];
3370
3371                     if( MKV_IS_ID( k, KaxChapterProcessPrivate ) )
3372                     {
3373                         KaxChapterProcessPrivate * p_private = static_cast<KaxChapterProcessPrivate*>( k );
3374                         p_ccodec->SetPrivate( *p_private );
3375                     }
3376                     else if( MKV_IS_ID( k, KaxChapterProcessCommand ) )
3377                     {
3378                         p_ccodec->AddCommand( *static_cast<KaxChapterProcessCommand*>( k ) );
3379                     }
3380                 }
3381                 chapters.codecs.push_back( p_ccodec );
3382             }
3383         }
3384         else if( MKV_IS_ID( l, KaxChapterAtom ) )
3385         {
3386             chapter_item_c *new_sub_chapter = new chapter_item_c();
3387             ParseChapterAtom( i_level+1, static_cast<KaxChapterAtom *>(l), *new_sub_chapter );
3388             new_sub_chapter->psz_parent = &chapters;
3389             chapters.sub_chapters.push_back( new_sub_chapter );
3390         }
3391     }
3392 }
3393
3394 /*****************************************************************************
3395  * ParseChapters:
3396  *****************************************************************************/
3397 void matroska_segment_c::ParseChapters( KaxChapters *chapters )
3398 {
3399     EbmlElement *el;
3400     size_t i;
3401     int i_upper_level = 0;
3402     mtime_t i_dur;
3403
3404     /* Master elements */
3405     chapters->Read( es, chapters->Generic().Context, i_upper_level, el, true );
3406
3407     for( i = 0; i < chapters->ListSize(); i++ )
3408     {
3409         EbmlElement *l = (*chapters)[i];
3410
3411         if( MKV_IS_ID( l, KaxEditionEntry ) )
3412         {
3413             chapter_edition_c *p_edition = new chapter_edition_c();
3414             
3415             EbmlMaster *E = static_cast<EbmlMaster *>(l );
3416             size_t j;
3417             msg_Dbg( &sys.demuxer, "|   |   + EditionEntry" );
3418             for( j = 0; j < E->ListSize(); j++ )
3419             {
3420                 EbmlElement *l = (*E)[j];
3421
3422                 if( MKV_IS_ID( l, KaxChapterAtom ) )
3423                 {
3424                     chapter_item_c *new_sub_chapter = new chapter_item_c();
3425                     ParseChapterAtom( 0, static_cast<KaxChapterAtom *>(l), *new_sub_chapter );
3426                     p_edition->sub_chapters.push_back( new_sub_chapter );
3427                 }
3428                 else if( MKV_IS_ID( l, KaxEditionUID ) )
3429                 {
3430                     p_edition->i_uid = uint64(*static_cast<KaxEditionUID *>( l ));
3431                 }
3432                 else if( MKV_IS_ID( l, KaxEditionFlagOrdered ) )
3433                 {
3434                     p_edition->b_ordered = config_GetInt( &sys.demuxer, "mkv-use-ordered-chapters" ) ? (uint8(*static_cast<KaxEditionFlagOrdered *>( l )) != 0) : 0;
3435                 }
3436                 else if( MKV_IS_ID( l, KaxEditionFlagDefault ) )
3437                 {
3438                     if (uint8(*static_cast<KaxEditionFlagDefault *>( l )) != 0)
3439                         i_default_edition = stored_editions.size();
3440                 }
3441                 else
3442                 {
3443                     msg_Dbg( &sys.demuxer, "|   |   |   + Unknown (%s)", typeid(*l).name() );
3444                 }
3445             }
3446             stored_editions.push_back( p_edition );
3447         }
3448         else
3449         {
3450             msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid(*l).name() );
3451         }
3452     }
3453
3454     for( i = 0; i < stored_editions.size(); i++ )
3455     {
3456         stored_editions[i]->RefreshChapters( );
3457     }
3458     
3459     if ( stored_editions[i_default_edition]->b_ordered )
3460     {
3461         /* update the duration of the segment according to the sum of all sub chapters */
3462         i_dur = stored_editions[i_default_edition]->Duration() / I64C(1000);
3463         if (i_dur > 0)
3464             i_duration = i_dur;
3465     }
3466 }
3467
3468 void matroska_segment_c::ParseCluster( )
3469 {
3470     EbmlElement *el;
3471     EbmlMaster  *m;
3472     unsigned int i;
3473     int i_upper_level = 0;
3474
3475     /* Master elements */
3476     m = static_cast<EbmlMaster *>( cluster );
3477     m->Read( es, cluster->Generic().Context, i_upper_level, el, true );
3478
3479     for( i = 0; i < m->ListSize(); i++ )
3480     {
3481         EbmlElement *l = (*m)[i];
3482
3483         if( MKV_IS_ID( l, KaxClusterTimecode ) )
3484         {
3485             KaxClusterTimecode &ctc = *(KaxClusterTimecode*)l;
3486
3487             cluster->InitTimecode( uint64( ctc ), i_timescale );
3488             break;
3489         }
3490     }
3491
3492     i_start_time = cluster->GlobalTimecode() / 1000;
3493 }
3494
3495 /*****************************************************************************
3496  * InformationCreate:
3497  *****************************************************************************/
3498 void matroska_segment_c::InformationCreate( )
3499 {
3500     size_t      i_track;
3501
3502     sys.meta = vlc_meta_New();
3503
3504     if( psz_title )
3505     {
3506         vlc_meta_Add( sys.meta, VLC_META_TITLE, psz_title );
3507     }
3508     if( psz_date_utc )
3509     {
3510         vlc_meta_Add( sys.meta, VLC_META_DATE, psz_date_utc );
3511     }
3512     if( psz_segment_filename )
3513     {
3514         vlc_meta_Add( sys.meta, _("Segment filename"), psz_segment_filename );
3515     }
3516     if( psz_muxing_application )
3517     {
3518         vlc_meta_Add( sys.meta, _("Muxing application"), psz_muxing_application );
3519     }
3520     if( psz_writing_application )
3521     {
3522         vlc_meta_Add( sys.meta, _("Writing application"), psz_writing_application );
3523     }
3524
3525     for( i_track = 0; i_track < tracks.size(); i_track++ )
3526     {
3527         mkv_track_t *tk = tracks[i_track];
3528         vlc_meta_t *mtk = vlc_meta_New();
3529
3530         sys.meta->track = (vlc_meta_t**)realloc( sys.meta->track,
3531                                                     sizeof( vlc_meta_t * ) * ( sys.meta->i_track + 1 ) );
3532         sys.meta->track[sys.meta->i_track++] = mtk;
3533
3534         if( tk->fmt.psz_description )
3535         {
3536             vlc_meta_Add( sys.meta, VLC_META_DESCRIPTION, tk->fmt.psz_description );
3537         }
3538         if( tk->psz_codec_name )
3539         {
3540             vlc_meta_Add( sys.meta, VLC_META_CODEC_NAME, tk->psz_codec_name );
3541         }
3542         if( tk->psz_codec_settings )
3543         {
3544             vlc_meta_Add( sys.meta, VLC_META_SETTING, tk->psz_codec_settings );
3545         }
3546         if( tk->psz_codec_info_url )
3547         {
3548             vlc_meta_Add( sys.meta, VLC_META_CODEC_DESCRIPTION, tk->psz_codec_info_url );
3549         }
3550         if( tk->psz_codec_download_url )
3551         {
3552             vlc_meta_Add( sys.meta, VLC_META_URL, tk->psz_codec_download_url );
3553         }
3554     }
3555
3556     if( i_tags_position >= 0 )
3557     {
3558         vlc_bool_t b_seekable;
3559
3560         stream_Control( sys.demuxer.s, STREAM_CAN_FASTSEEK, &b_seekable );
3561         if( b_seekable )
3562         {
3563             LoadTags( );
3564         }
3565     }
3566 }
3567
3568
3569 /*****************************************************************************
3570  * Divers
3571  *****************************************************************************/
3572
3573 void matroska_segment_c::IndexAppendCluster( KaxCluster *cluster )
3574 {
3575 #define idx index[i_index]
3576     idx.i_track       = -1;
3577     idx.i_block_number= -1;
3578     idx.i_position    = cluster->GetElementPosition();
3579     idx.i_time        = -1;
3580     idx.b_key         = VLC_TRUE;
3581
3582     i_index++;
3583     if( i_index >= i_index_max )
3584     {
3585         i_index_max += 1024;
3586         index = (mkv_index_t*)realloc( index, sizeof( mkv_index_t ) * i_index_max );
3587     }
3588 #undef idx
3589 }
3590
3591 static char * UTF8ToStr( const UTFstring &u )
3592 {
3593     int     i_src;
3594     const wchar_t *src;
3595     char *dst, *p;
3596
3597     i_src = u.length();
3598     src   = u.c_str();
3599
3600     p = dst = (char*)malloc( i_src + 1);
3601     while( i_src > 0 )
3602     {
3603         if( *src < 255 )
3604         {
3605             *p++ = (char)*src;
3606         }
3607         else
3608         {
3609             *p++ = '?';
3610         }
3611         src++;
3612         i_src--;
3613     }
3614     *p++= '\0';
3615
3616     return dst;
3617 }
3618
3619 void chapter_edition_c::RefreshChapters( )
3620 {
3621     chapter_item_c::RefreshChapters( b_ordered, -1 );
3622     b_display_seekpoint = false;
3623 }
3624
3625 int64_t chapter_item_c::RefreshChapters( bool b_ordered, int64_t i_prev_user_time )
3626 {
3627     int64_t i_user_time = i_prev_user_time;
3628     
3629     // first the sub-chapters, and then ourself
3630     std::vector<chapter_item_c*>::iterator index = sub_chapters.begin();
3631     while ( index != sub_chapters.end() )
3632     {
3633         i_user_time = (*index)->RefreshChapters( b_ordered, i_user_time );
3634         index++;
3635     }
3636
3637     if ( b_ordered )
3638     {
3639         // the ordered chapters always start at zero
3640         if ( i_prev_user_time == -1 )
3641         {
3642             if ( i_user_time == -1 )
3643                 i_user_time = 0;
3644             i_prev_user_time = 0;
3645         }
3646
3647         i_user_start_time = i_prev_user_time;
3648         if ( i_end_time != -1 && i_user_time == i_prev_user_time )
3649         {
3650             i_user_end_time = i_user_start_time - i_start_time + i_end_time;
3651         }
3652         else
3653         {
3654             i_user_end_time = i_user_time;
3655         }
3656     }
3657     else
3658     {
3659         std::sort( sub_chapters.begin(), sub_chapters.end() );
3660         i_user_start_time = i_start_time;
3661         if ( i_end_time != -1 )
3662             i_user_end_time = i_end_time;
3663         else if ( i_user_time != -1 )
3664             i_user_end_time = i_user_time;
3665         else
3666             i_user_end_time = i_user_start_time;
3667     }
3668
3669     return i_user_end_time;
3670 }
3671
3672 mtime_t chapter_edition_c::Duration() const
3673 {
3674     mtime_t i_result = 0;
3675     
3676     if ( sub_chapters.size() )
3677     {
3678         std::vector<chapter_item_c*>::const_iterator index = sub_chapters.end();
3679         index--;
3680         i_result = (*index)->i_user_end_time;
3681     }
3682     
3683     return i_result;
3684 }
3685
3686 chapter_item_c *chapter_item_c::FindTimecode( mtime_t i_user_timecode )
3687 {
3688     chapter_item_c *psz_result = NULL;
3689
3690     if ( i_user_timecode >= i_user_start_time && 
3691         ( i_user_timecode < i_user_end_time || 
3692           ( i_user_start_time == i_user_end_time && i_user_timecode == i_user_end_time )))
3693     {
3694         std::vector<chapter_item_c*>::iterator index = sub_chapters.begin();
3695         while ( index != sub_chapters.end() && psz_result == NULL )
3696         {
3697             psz_result = (*index)->FindTimecode( i_user_timecode );
3698             index++;
3699         }
3700         
3701         if ( psz_result == NULL )
3702             psz_result = this;
3703     }
3704
3705     return psz_result;
3706 }
3707
3708 void demux_sys_t::PreloadFamily( const matroska_segment_c & of_segment )
3709 {
3710     for (size_t i=0; i<opened_segments.size(); i++)
3711     {
3712         opened_segments[i]->PreloadFamily( of_segment );
3713     }
3714 }
3715 bool matroska_segment_c::PreloadFamily( const matroska_segment_c & of_segment )
3716 {
3717     if ( b_preloaded )
3718         return false;
3719
3720     for (size_t i=0; i<families.size(); i++)
3721     {
3722         for (size_t j=0; j<of_segment.families.size(); j++)
3723         {
3724             if ( families[i] == of_segment.families[j] )
3725                 return Preload( );
3726         }
3727     }
3728
3729     return false;
3730 }
3731
3732 // preload all the linked segments for all preloaded segments
3733 void demux_sys_t::PreloadLinked( matroska_segment_c *p_segment )
3734 {
3735     size_t i_preloaded, i;
3736     virtual_segment_c *p_seg;
3737
3738     p_current_segment = VirtualFromSegments( p_segment );
3739     
3740     used_segments.push_back( p_current_segment );
3741
3742     // create all the other virtual segments of the family
3743     do {
3744         i_preloaded = 0;
3745         for ( i=0; i< opened_segments.size(); i++ )
3746         {
3747             if ( opened_segments[i]->b_preloaded && !IsUsedSegment( *opened_segments[i] ) )
3748             {
3749                 p_seg = VirtualFromSegments( opened_segments[i] );
3750                 used_segments.push_back( p_seg );
3751                 i_preloaded++;
3752             }
3753         }
3754     } while ( i_preloaded ); // worst case: will stop when all segments are found as family related
3755 }
3756
3757 bool demux_sys_t::IsUsedSegment( matroska_segment_c &segment ) const
3758 {
3759     for ( size_t i=0; i< used_segments.size(); i++ )
3760     {
3761         if ( used_segments[i]->FindUID( segment.segment_uid ) )
3762             return true;
3763     }
3764     return false;
3765 }
3766
3767 virtual_segment_c *demux_sys_t::VirtualFromSegments( matroska_segment_c *p_segment ) const
3768 {
3769     size_t i_preloaded, i;
3770
3771     virtual_segment_c *p_result = new virtual_segment_c( p_segment );
3772
3773     // fill our current virtual segment with all hard linked segments
3774     do {
3775         i_preloaded = 0;
3776         for ( i=0; i< opened_segments.size(); i++ )
3777         {
3778             i_preloaded += p_result->AddSegment( opened_segments[i] );
3779         }
3780     } while ( i_preloaded ); // worst case: will stop when all segments are found as linked
3781
3782     p_result->Sort( );
3783
3784     p_result->PreloadLinked( );
3785
3786     p_result->PrepareChapters( );
3787
3788     return p_result;
3789 }
3790
3791 bool demux_sys_t::PreparePlayback( )
3792 {
3793     p_current_segment->LoadCues();
3794     f_duration = p_current_segment->Duration();
3795
3796     /* add information */
3797     p_current_segment->Segment()->InformationCreate( );
3798
3799     p_current_segment->Segment()->Select( 0 );
3800
3801     return p_current_segment->Select( *title );
3802 }
3803
3804 bool matroska_segment_c::CompareSegmentUIDs( const matroska_segment_c * p_item_a, const matroska_segment_c * p_item_b )
3805 {
3806     EbmlBinary * p_itema = (EbmlBinary *)(&p_item_a->segment_uid);
3807     if ( *p_itema == p_item_b->prev_segment_uid )
3808         return true;
3809
3810     p_itema = (EbmlBinary *)(&p_item_a->next_segment_uid);
3811     if ( *p_itema == p_item_b->segment_uid )
3812         return true;
3813
3814     if ( *p_itema == p_item_b->prev_segment_uid )
3815         return true;
3816
3817     return false;
3818 }
3819
3820 bool matroska_segment_c::Preload( )
3821 {
3822     if ( b_preloaded )
3823         return false;
3824
3825     EbmlElement *el = NULL;
3826
3827     ep->Reset( &sys.demuxer );
3828
3829     while( ( el = ep->Get() ) != NULL )
3830     {
3831         if( MKV_IS_ID( el, KaxInfo ) )
3832         {
3833             ParseInfo( static_cast<KaxInfo*>( el ) );
3834         }
3835         else if( MKV_IS_ID( el, KaxTracks ) )
3836         {
3837             ParseTracks( static_cast<KaxTracks*>( el ) );
3838         }
3839         else if( MKV_IS_ID( el, KaxSeekHead ) )
3840         {
3841             ParseSeekHead( static_cast<KaxSeekHead*>( el ) );
3842         }
3843         else if( MKV_IS_ID( el, KaxCues ) )
3844         {
3845             msg_Dbg( &sys.demuxer, "|   + Cues" );
3846         }
3847         else if( MKV_IS_ID( el, KaxCluster ) )
3848         {
3849             msg_Dbg( &sys.demuxer, "|   + Cluster" );
3850
3851             cluster = (KaxCluster*)el;
3852
3853             i_start_pos = cluster->GetElementPosition();
3854             ParseCluster( );
3855
3856             ep->Down();
3857             /* stop parsing the stream */
3858             break;
3859         }
3860         else if( MKV_IS_ID( el, KaxAttachments ) )
3861         {
3862             msg_Dbg( &sys.demuxer, "|   + Attachments FIXME (but probably never supported)" );
3863         }
3864         else if( MKV_IS_ID( el, KaxChapters ) )
3865         {
3866             msg_Dbg( &sys.demuxer, "|   + Chapters" );
3867             ParseChapters( static_cast<KaxChapters*>( el ) );
3868         }
3869         else if( MKV_IS_ID( el, KaxTag ) )
3870         {
3871             msg_Dbg( &sys.demuxer, "|   + Tags FIXME TODO" );
3872         }
3873         else
3874         {
3875             msg_Dbg( &sys.demuxer, "|   + Unknown (%s)", typeid(*el).name() );
3876         }
3877     }
3878
3879     b_preloaded = true;
3880
3881     return true;
3882 }
3883
3884 matroska_segment_c *demux_sys_t::FindSegment( const EbmlBinary & uid ) const
3885 {
3886     for (size_t i=0; i<opened_segments.size(); i++)
3887     {
3888         if ( opened_segments[i]->segment_uid == uid )
3889             return opened_segments[i];
3890     }
3891     return NULL;
3892 }
3893
3894 chapter_item_c *demux_sys_t::BrowseCodecPrivate( unsigned int codec_id, 
3895                                         bool (*match)(const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ), 
3896                                         const void *p_cookie, 
3897                                         size_t i_cookie_size, 
3898                                         virtual_segment_c * &p_segment_found )
3899 {
3900     chapter_item_c *p_result = NULL;
3901     for (size_t i=0; i<opened_segments.size(); i++)
3902     {
3903         p_result = used_segments[i]->BrowseCodecPrivate( codec_id, match, p_cookie, i_cookie_size );
3904         if ( p_result != NULL )
3905         {
3906             p_segment_found = used_segments[i];
3907             break;
3908         }
3909     }
3910     return p_result;
3911 }
3912
3913 void virtual_segment_c::Sort()
3914 {
3915     // keep the current segment index
3916     matroska_segment_c *p_segment = linked_segments[i_current_segment];
3917
3918     std::sort( linked_segments.begin(), linked_segments.end(), matroska_segment_c::CompareSegmentUIDs );
3919
3920     for ( i_current_segment=0; i_current_segment<linked_segments.size(); i_current_segment++)
3921         if ( linked_segments[i_current_segment] == p_segment )
3922             break;
3923 }
3924
3925 size_t virtual_segment_c::AddSegment( matroska_segment_c *p_segment )
3926 {
3927     size_t i;
3928     // check if it's not already in here
3929     for ( i=0; i<linked_segments.size(); i++ )
3930     {
3931         if ( p_segment->segment_uid == linked_segments[i]->segment_uid )
3932             return 0;
3933     }
3934
3935     // find possible mates
3936     for ( i=0; i<linked_uids.size(); i++ )
3937     {
3938         if (   p_segment->segment_uid == linked_uids[i] 
3939             || p_segment->prev_segment_uid == linked_uids[i] 
3940             || p_segment->next_segment_uid == linked_uids[i] )
3941         {
3942             linked_segments.push_back( p_segment );
3943
3944             AppendUID( p_segment->prev_segment_uid );
3945             AppendUID( p_segment->next_segment_uid );
3946
3947             return 1;
3948         }
3949     }
3950     return 0;
3951 }
3952
3953 void virtual_segment_c::PreloadLinked( )
3954 {
3955     for ( size_t i=0; i<linked_segments.size(); i++ )
3956     {
3957         linked_segments[i]->Preload( );
3958     }
3959     i_current_edition = linked_segments[0]->i_default_edition;
3960 }
3961
3962 mtime_t virtual_segment_c::Duration() const
3963 {
3964     mtime_t i_duration;
3965     if ( linked_segments.size() == 0 )
3966         i_duration = 0;
3967     else {
3968         matroska_segment_c *p_last_segment = linked_segments[linked_segments.size()-1];
3969 //        p_last_segment->ParseCluster( );
3970
3971         i_duration = p_last_segment->i_start_time / 1000 + p_last_segment->i_duration;
3972     }
3973     return i_duration;
3974 }
3975
3976 void virtual_segment_c::LoadCues( )
3977 {
3978     for ( size_t i=0; i<linked_segments.size(); i++ )
3979     {
3980         linked_segments[i]->LoadCues();
3981     }
3982 }
3983
3984 void virtual_segment_c::AppendUID( const EbmlBinary & UID )
3985 {
3986     if ( UID.GetBuffer() == NULL )
3987         return;
3988
3989     for (size_t i=0; i<linked_uids.size(); i++)
3990     {
3991         if ( UID == linked_uids[i] )
3992             return;
3993     }
3994     linked_uids.push_back( *(KaxSegmentUID*)(&UID) );
3995 }
3996
3997 void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset )
3998 {
3999     KaxBlock    *block;
4000     int         i_track_skipping;
4001     int64_t     i_block_duration;
4002     int64_t     i_block_ref1;
4003     int64_t     i_block_ref2;
4004     size_t      i_track;
4005     int64_t     i_seek_position = i_start_pos;
4006     int64_t     i_seek_time = i_start_time;
4007
4008     if ( i_index > 0 )
4009     {
4010         int i_idx = 0;
4011
4012         for( ; i_idx < i_index; i_idx++ )
4013         {
4014             if( index[i_idx].i_time + i_time_offset > i_date )
4015             {
4016                 break;
4017             }
4018         }
4019
4020         if( i_idx > 0 )
4021         {
4022             i_idx--;
4023         }
4024
4025         i_seek_position = index[i_idx].i_position;
4026         i_seek_time = index[i_idx].i_time;
4027     }
4028
4029     msg_Dbg( &sys.demuxer, "seek got "I64Fd" (%d%%)",
4030                 i_seek_time, (int)( 100 * i_seek_position / stream_Size( sys.demuxer.s ) ) );
4031
4032     es.I_O().setFilePointer( i_seek_position, seek_beginning );
4033
4034     delete ep;
4035     ep = new EbmlParser( &es, segment, &sys.demuxer );
4036     cluster = NULL;
4037
4038     sys.i_start_pts = i_date;
4039
4040     es_out_Control( sys.demuxer.out, ES_OUT_RESET_PCR );
4041
4042     /* now parse until key frame */
4043 #define tk  tracks[i_track]
4044     i_track_skipping = 0;
4045     for( i_track = 0; i_track < tracks.size(); i_track++ )
4046     {
4047         if( tk->fmt.i_cat == VIDEO_ES )
4048         {
4049             tk->b_search_keyframe = VLC_TRUE;
4050             i_track_skipping++;
4051         }
4052         es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, tk->p_es, i_date );
4053     }
4054
4055
4056     while( i_track_skipping > 0 )
4057     {
4058         if( BlockGet( &block, &i_block_ref1, &i_block_ref2, &i_block_duration ) )
4059         {
4060             msg_Warn( &sys.demuxer, "cannot get block EOF?" );
4061
4062             return;
4063         }
4064
4065         for( i_track = 0; i_track < tracks.size(); i_track++ )
4066         {
4067             if( tk->i_number == block->TrackNum() )
4068             {
4069                 break;
4070             }
4071         }
4072
4073         sys.i_pts = sys.i_chapter_time + block->GlobalTimecode() / (mtime_t) 1000;
4074
4075         if( i_track < tracks.size() )
4076         {
4077             if( sys.i_pts >= sys.i_start_pts )
4078             {
4079                 BlockDecode( &sys.demuxer, block, sys.i_pts, 0 );
4080                 i_track_skipping = 0;
4081             }
4082             else if( tk->fmt.i_cat == VIDEO_ES )
4083             {
4084                 if( i_block_ref1 == -1 && tk->b_search_keyframe )
4085                 {
4086                     tk->b_search_keyframe = VLC_FALSE;
4087                     i_track_skipping--;
4088                 }
4089                 if( !tk->b_search_keyframe )
4090                 {
4091                     BlockDecode( &sys.demuxer, block, sys.i_pts, 0 );
4092                 }
4093             } 
4094         }
4095
4096         delete block;
4097     }
4098 #undef tk
4099 }
4100
4101 void virtual_segment_c::Seek( demux_t & demuxer, mtime_t i_date, mtime_t i_time_offset, chapter_item_c *psz_chapter )
4102 {
4103     demux_sys_t *p_sys = demuxer.p_sys;
4104     size_t i;
4105
4106     // find the actual time for an ordered edition
4107     if ( psz_chapter == NULL )
4108     {
4109         if ( EditionIsOrdered() )
4110         {
4111             /* 1st, we need to know in which chapter we are */
4112             psz_chapter = (*p_editions)[i_current_edition]->FindTimecode( i_date );
4113         }
4114     }
4115
4116     if ( psz_chapter != NULL )
4117     {
4118         psz_current_chapter = psz_chapter;
4119         p_sys->i_chapter_time = i_time_offset = psz_chapter->i_user_start_time - psz_chapter->i_start_time;
4120         demuxer.info.i_update |= INPUT_UPDATE_SEEKPOINT;
4121         demuxer.info.i_seekpoint = psz_chapter->i_seekpoint_num - 1;
4122     }
4123
4124     // find the best matching segment
4125     for ( i=0; i<linked_segments.size(); i++ )
4126     {
4127         if ( i_date < linked_segments[i]->i_start_time )
4128             break;
4129     }
4130
4131     if ( i > 0 )
4132         i--;
4133
4134     if ( i_current_segment != i  )
4135     {
4136         linked_segments[i_current_segment]->UnSelect();
4137         linked_segments[i]->Select( i_date );
4138         i_current_segment = i;
4139     }
4140
4141     linked_segments[i]->Seek( i_date, i_time_offset );
4142 }
4143
4144 void chapter_codec_cmds_c::AddCommand( const KaxChapterProcessCommand & command )
4145 {
4146     size_t i;
4147
4148     uint32 codec_time = uint32(-1);
4149     for( i = 0; i < command.ListSize(); i++ )
4150     {
4151         const EbmlElement *k = command[i];
4152
4153         if( MKV_IS_ID( k, KaxChapterProcessTime ) )
4154         {
4155             codec_time = uint32( *static_cast<const KaxChapterProcessTime*>( k ) );
4156             break;
4157         }
4158     }
4159
4160     for( i = 0; i < command.ListSize(); i++ )
4161     {
4162         const EbmlElement *k = command[i];
4163
4164         if( MKV_IS_ID( k, KaxChapterProcessData ) )
4165         {
4166             KaxChapterProcessData *p_data =  new KaxChapterProcessData( *static_cast<const KaxChapterProcessData*>( k ) );
4167             switch ( codec_time )
4168             {
4169             case 0:
4170                 during_cmds.push_back( *p_data );
4171                 break;
4172             case 1:
4173                 enter_cmds.push_back( *p_data );
4174                 break;
4175             case 2:
4176                 leave_cmds.push_back( *p_data );
4177                 break;
4178             default:
4179                 delete p_data;
4180             }
4181         }
4182     }
4183 }
4184
4185 bool chapter_item_c::Enter()
4186 {
4187     std::vector<chapter_codec_cmds_c*>::iterator index = codecs.begin();
4188     while ( index != codecs.end() )
4189     {
4190         (*index)->Enter();
4191         index++;
4192     }
4193     std::vector<chapter_item_c*>::iterator index_ = sub_chapters.begin();
4194     while ( index_ != sub_chapters.end() )
4195     {
4196         (*index_)->Enter();
4197         index_++;
4198     }
4199     return true;
4200 }
4201
4202 bool chapter_item_c::Leave()
4203 {
4204     std::vector<chapter_codec_cmds_c*>::iterator index = codecs.begin();
4205     while ( index != codecs.end() )
4206     {
4207         (*index)->Leave();
4208         index++;
4209     }
4210     std::vector<chapter_item_c*>::iterator index_ = sub_chapters.begin();
4211     while ( index_ != sub_chapters.end() )
4212     {
4213         (*index_)->Leave();
4214         index_++;
4215     }
4216     return true;
4217 }
4218
4219 bool dvd_chapter_codec_c::Enter()
4220 {
4221     std::vector<KaxChapterProcessData>::iterator index = enter_cmds.begin();
4222     while ( index != enter_cmds.end() )
4223     {
4224         if ( (*index).GetSize() )
4225         {
4226             binary *p_data = (*index).GetBuffer();
4227             size_t i_size = *p_data++;
4228             // avoid reading too much from the buffer
4229             i_size = min( i_size, ((*index).GetSize() - 1) >> 3 );
4230             for ( ; i_size > 0; i_size--, p_data += 8 )
4231             {
4232                 interpretor.Interpret( p_data );
4233             }
4234         }
4235         index++;
4236     }
4237     return true;
4238 }
4239
4240 bool dvd_chapter_codec_c::Leave()
4241 {
4242     std::vector<KaxChapterProcessData>::iterator index = leave_cmds.begin();
4243     while ( index != leave_cmds.end() )
4244     {
4245         if ( (*index).GetSize() )
4246         {
4247             binary *p_data = (*index).GetBuffer();
4248             size_t i_size = *p_data++;
4249             // avoid reading too much from the buffer
4250             i_size = min( i_size, ((*index).GetSize() - 1) >> 3 );
4251             for ( ; i_size > 0; i_size--, p_data += 8 )
4252             {
4253                 interpretor.Interpret( p_data );
4254             }
4255         }
4256         index++;
4257     }
4258     return true;
4259 }
4260
4261 bool dvd_command_interpretor_c::Interpret( const binary * p_command, size_t i_size )
4262 {
4263     if ( i_size != 8 )
4264         return false;
4265
4266     uint16 i_command = ( p_command[0] << 8 ) + p_command[1];
4267
4268     switch ( i_command )
4269     {
4270     case CMD_JUMP_TT:
4271         {
4272             uint8 i_title = p_command[5];
4273             msg_Dbg( &sys.demuxer, "DVD command: JumpTT %d", i_title );
4274
4275             // find in the ChapProcessPrivate matching this Title level
4276             virtual_segment_c *p_segment;
4277             chapter_item_c *p_chapter;
4278             p_chapter = sys.BrowseCodecPrivate( 1, MatchTitleNumber, &i_title, sizeof(i_title), p_segment );
4279             if ( p_chapter != NULL )
4280             {
4281                 // if the segment is not part of the current segment, select the new one
4282                 if ( p_segment != sys.p_current_segment )
4283                 {
4284                     sys.p_current_segment = p_segment;
4285                     sys.PreparePlayback();
4286                 }
4287     
4288                 p_chapter->Enter();
4289                 
4290                 // jump to the location in the found segment
4291                 p_segment->Seek( sys.demuxer, p_chapter->i_user_start_time, -1, p_chapter );
4292             }
4293
4294             break;
4295         }
4296     case CMD_CALLSS_VTSM:
4297         {
4298             msg_Dbg( &sys.demuxer, "DVD command: CallSS VTSM" );
4299             break;
4300         }
4301     default:
4302         {
4303             msg_Dbg( &sys.demuxer, "DVD command: unsupported %02X %02X %02X %02X %02X %02X %02X %02X"
4304                      ,p_command[0]
4305                      ,p_command[1]
4306                      ,p_command[2]
4307                      ,p_command[3]
4308                      ,p_command[4]
4309                      ,p_command[5]
4310                      ,p_command[6]
4311                      ,p_command[7]);
4312             break;
4313         }
4314     }
4315
4316     return true;
4317 }
4318
4319 bool dvd_command_interpretor_c::MatchTitleNumber( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size )
4320 {
4321     if ( i_cookie_size != 1 || data.m_private_data.GetSize() < 4 )
4322         return false;
4323     
4324     if ( data.m_private_data.GetBuffer()[0] != 0x28 )
4325         return false;
4326
4327     uint16 i_gtitle = (data.m_private_data.GetBuffer()[1] << 8 ) + data.m_private_data.GetBuffer()[2];
4328     uint8 i_title = *(uint8*)p_cookie;
4329
4330     return (i_gtitle == i_title);
4331 }