]> git.sesse.net Git - vlc/blob - modules/demux/mkv/matroska_segment.cpp
Fix the subtitles loss at MKV segment changes
[vlc] / modules / demux / mkv / matroska_segment.cpp
1 /*****************************************************************************
2  * matroska_segment.cpp : matroska demuxer
3  *****************************************************************************
4  * Copyright (C) 2003-2010 the VideoLAN team
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #include "matroska_segment.hpp"
26
27 #include "chapters.hpp"
28
29 #include "demux.hpp"
30
31 #include "Ebml_parser.hpp"
32
33 extern "C" {
34 #include "../vobsub.h"
35 }
36
37 #include <vlc_codecs.h>
38
39 /* GetFourCC helper */
40 #define GetFOURCC( p )  __GetFOURCC( (uint8_t*)p )
41 static vlc_fourcc_t __GetFOURCC( uint8_t *p )
42 {
43     return VLC_FOURCC( p[0], p[1], p[2], p[3] );
44 }
45
46 matroska_segment_c::matroska_segment_c( demux_sys_t & demuxer, EbmlStream & estream )
47     :segment(NULL)
48     ,es(estream)
49     ,i_timescale(MKVD_TIMECODESCALE)
50     ,i_duration(-1)
51     ,i_start_time(0)
52     ,i_seekhead_count(0)
53     ,i_seekhead_position(-1)
54     ,i_cues_position(-1)
55     ,i_tracks_position(-1)
56     ,i_info_position(-1)
57     ,i_chapters_position(-1)
58     ,i_tags_position(-1)
59     ,i_attachments_position(-1)
60     ,cluster(NULL)
61     ,i_block_pos(0)
62     ,i_cluster_pos(0)
63     ,i_start_pos(0)
64     ,p_segment_uid(NULL)
65     ,p_prev_segment_uid(NULL)
66     ,p_next_segment_uid(NULL)
67     ,b_cues(false)
68     ,i_index(0)
69     ,i_index_max(1024)
70     ,psz_muxing_application(NULL)
71     ,psz_writing_application(NULL)
72     ,psz_segment_filename(NULL)
73     ,psz_title(NULL)
74     ,psz_date_utc(NULL)
75     ,i_default_edition(0)
76     ,sys(demuxer)
77     ,ep(NULL)
78     ,b_preloaded(false)
79 {
80     p_indexes = (mkv_index_t*)malloc( sizeof( mkv_index_t ) * i_index_max );
81 }
82
83 matroska_segment_c::~matroska_segment_c()
84 {
85     for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
86     {
87         delete tracks[i_track]->p_compression_data;
88         es_format_Clean( &tracks[i_track]->fmt );
89         free( tracks[i_track]->p_extra_data );
90         free( tracks[i_track]->psz_codec );
91         delete tracks[i_track];
92     }
93
94     free( psz_writing_application );
95     free( psz_muxing_application );
96     free( psz_segment_filename );
97     free( psz_title );
98     free( psz_date_utc );
99     free( p_indexes );
100
101     delete ep;
102     delete segment;
103     delete p_segment_uid;
104     delete p_prev_segment_uid;
105     delete p_next_segment_uid;
106
107     vlc_delete_all( stored_editions );
108     vlc_delete_all( translations );
109     vlc_delete_all( families );
110 }
111
112
113 /*****************************************************************************
114  * Tools                                                                     *
115  *****************************************************************************
116  *  * LoadCues : load the cues element and update index
117  *  * LoadTags : load ... the tags element
118  *  * InformationCreate : create all information, load tags if present
119  *****************************************************************************/
120 void matroska_segment_c::LoadCues( KaxCues *cues )
121 {
122     EbmlParser  *ep;
123     EbmlElement *el;
124
125     if( b_cues )
126     {
127         msg_Err( &sys.demuxer, "There can be only 1 Cues per section." );
128         return;
129     }
130
131     ep = new EbmlParser( &es, cues, &sys.demuxer );
132     while( ( el = ep->Get() ) != NULL )
133     {
134         if( MKV_IS_ID( el, KaxCuePoint ) )
135         {
136 #define idx p_indexes[i_index]
137
138             idx.i_track       = -1;
139             idx.i_block_number= -1;
140             idx.i_position    = -1;
141             idx.i_time        = 0;
142             idx.b_key         = true;
143
144             ep->Down();
145             while( ( el = ep->Get() ) != NULL )
146             {
147                 if( MKV_IS_ID( el, KaxCueTime ) )
148                 {
149                     KaxCueTime &ctime = *(KaxCueTime*)el;
150
151                     ctime.ReadData( es.I_O() );
152
153                     idx.i_time = uint64( ctime ) * i_timescale / (mtime_t)1000;
154                 }
155                 else if( MKV_IS_ID( el, KaxCueTrackPositions ) )
156                 {
157                     ep->Down();
158                     while( ( el = ep->Get() ) != NULL )
159                     {
160                         if( MKV_IS_ID( el, KaxCueTrack ) )
161                         {
162                             KaxCueTrack &ctrack = *(KaxCueTrack*)el;
163
164                             ctrack.ReadData( es.I_O() );
165                             idx.i_track = uint16( ctrack );
166                         }
167                         else if( MKV_IS_ID( el, KaxCueClusterPosition ) )
168                         {
169                             KaxCueClusterPosition &ccpos = *(KaxCueClusterPosition*)el;
170
171                             ccpos.ReadData( es.I_O() );
172                             idx.i_position = segment->GetGlobalPosition( uint64( ccpos ) );
173                         }
174                         else if( MKV_IS_ID( el, KaxCueBlockNumber ) )
175                         {
176                             KaxCueBlockNumber &cbnum = *(KaxCueBlockNumber*)el;
177
178                             cbnum.ReadData( es.I_O() );
179                             idx.i_block_number = uint32( cbnum );
180                         }
181                         else
182                         {
183                             msg_Dbg( &sys.demuxer, "         * Unknown (%s)", typeid(*el).name() );
184                         }
185                     }
186                     ep->Up();
187                 }
188                 else
189                 {
190                     msg_Dbg( &sys.demuxer, "     * Unknown (%s)", typeid(*el).name() );
191                 }
192             }
193             ep->Up();
194
195 #if 0
196             msg_Dbg( &sys.demuxer, " * added time=%"PRId64" pos=%"PRId64
197                      " track=%d bnum=%d", idx.i_time, idx.i_position,
198                      idx.i_track, idx.i_block_number );
199 #endif
200
201             i_index++;
202             if( i_index >= i_index_max )
203             {
204                 i_index_max += 1024;
205                 p_indexes = (mkv_index_t*)xrealloc( p_indexes,
206                                         sizeof( mkv_index_t ) * i_index_max );
207             }
208 #undef idx
209         }
210         else
211         {
212             msg_Dbg( &sys.demuxer, " * Unknown (%s)", typeid(*el).name() );
213         }
214     }
215     delete ep;
216     b_cues = true;
217     msg_Dbg( &sys.demuxer, "|   - loading cues done." );
218 }
219
220
221 #define PARSE_TAG( type ) \
222     do { \
223     msg_Dbg( &sys.demuxer, "|   + " type ); \
224     ep->Down();                             \
225     while( ( el = ep->Get() ) != NULL )     \
226     {                                       \
227         msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid( *el ).name() ); \
228     }                                      \
229     ep->Up(); } while( 0 )
230
231 static const struct {
232     vlc_meta_type_t type;
233     const char *key;
234 } metadata_map[] = { {vlc_meta_Title,       "TITLE"},
235                      {vlc_meta_Artist,      "ARTIST"},
236                      {vlc_meta_Genre,       "GENRE"},
237                      {vlc_meta_Copyright,   "COPYRIGHT"},
238                      {vlc_meta_Description, "DESCRIPTION"},
239                      {vlc_meta_Publisher,   "PUBLISHER"},
240                      {vlc_meta_URL,         "URL"},
241                      {vlc_meta_TrackNumber, "PART_NUMBER"},
242                      {vlc_meta_Date,        "DATE_RELEASE"},
243                      {vlc_meta_Title,       NULL},
244 };
245
246 void matroska_segment_c::ParseSimpleTags( KaxTagSimple *tag )
247 {
248     EbmlElement *el;
249     EbmlParser *ep = new EbmlParser( &es, tag, &sys.demuxer );
250     char *k = NULL, *v = NULL;
251
252     if( !sys.meta )
253         sys.meta = vlc_meta_New();
254
255     msg_Dbg( &sys.demuxer, "|   + Simple Tag ");
256     while( ( el = ep->Get() ) != NULL )
257     {
258         if( MKV_IS_ID( el, KaxTagName ) )
259         {
260             KaxTagName &key = *(KaxTagName*)el;
261             key.ReadData( es.I_O(), SCOPE_ALL_DATA );
262             k = strdup( UTFstring( key ).GetUTF8().c_str() );
263         }
264         if( MKV_IS_ID( el, KaxTagString ) )
265         {
266             KaxTagString &value = *(KaxTagString*)el;
267             value.ReadData( es.I_O(), SCOPE_ALL_DATA );
268             v = strdup( UTFstring( value ).GetUTF8().c_str() );
269         }
270     }
271     delete ep;
272
273     if( !k || !v )
274     {
275         msg_Warn( &sys.demuxer, "Invalid MKV SimpleTag found.");
276         return;
277     }
278
279     for( int i = 0; metadata_map[i].key; i++ )
280     {
281         if( !strcmp( k, metadata_map[i].key ) )
282         {
283             vlc_meta_Set( sys.meta, metadata_map[i].type, v );
284             goto done;
285         }
286     }
287     vlc_meta_AddExtra( sys.meta, k, v );
288 done:
289     free( k );
290     free( v );
291     return;
292 }
293
294 void matroska_segment_c::LoadTags( KaxTags *tags )
295 {
296     /* Master elements */
297     EbmlParser *ep = new EbmlParser( &es, tags, &sys.demuxer );
298     EbmlElement *el;
299
300     while( ( el = ep->Get() ) != NULL )
301     {
302         if( MKV_IS_ID( el, KaxTag ) )
303         {
304             msg_Dbg( &sys.demuxer, "+ Tag" );
305             ep->Down();
306             while( ( el = ep->Get() ) != NULL )
307             {
308                 if( MKV_IS_ID( el, KaxTagTargets ) )
309                     PARSE_TAG( "Targets" );
310 #if 0 // not valid anymore
311                 else if( MKV_IS_ID( el, KaxTagGeneral ) )
312                     PARSE_TAG( "General" );
313                 else if( MKV_IS_ID( el, KaxTagGenres ) )
314                     PARSE_TAG( "Genres" );
315                 else if( MKV_IS_ID( el, KaxTagAudioSpecific ) )
316                     PARSE_TAG( "Audio Specific" );
317                 else if( MKV_IS_ID( el, KaxTagImageSpecific ) )
318                     PARSE_TAG( "Images Specific" );
319                 else if( MKV_IS_ID( el, KaxTagMultiComment ) )
320                 {
321                     msg_Dbg( &sys.demuxer, "|   + Multi Comment" );
322                 }
323                 else if( MKV_IS_ID( el, KaxTagMultiCommercial ) )
324                 {
325                     msg_Dbg( &sys.demuxer, "|   + Multi Commercial" );
326                 }
327                 else if( MKV_IS_ID( el, KaxTagMultiDate ) )
328                 {
329                     msg_Dbg( &sys.demuxer, "|   + Multi Date" );
330                 }
331                 else if( MKV_IS_ID( el, KaxTagMultiEntity ) )
332                 {
333                     msg_Dbg( &sys.demuxer, "|   + Multi Entity" );
334                 }
335                 else if( MKV_IS_ID( el, KaxTagMultiIdentifier ) )
336                 {
337                     msg_Dbg( &sys.demuxer, "|   + Multi Identifier" );
338                 }
339                 else if( MKV_IS_ID( el, KaxTagMultiLegal ) )
340                 {
341                     msg_Dbg( &sys.demuxer, "|   + Multi Legal" );
342                 }
343                 else if( MKV_IS_ID( el, KaxTagMultiTitle ) )
344                 {
345                     msg_Dbg( &sys.demuxer, "|   + Multi Title" );
346                 }
347 #endif
348                 else if( MKV_IS_ID( el, KaxTagSimple ) )
349                     ParseSimpleTags( static_cast<KaxTagSimple*>( el ) );
350                 else
351                 {
352                     msg_Dbg( &sys.demuxer, "|   + LoadTag Unknown (%s)", typeid( *el ).name() );
353                 }
354             }
355             ep->Up();
356         }
357         else
358         {
359             msg_Dbg( &sys.demuxer, "+ Unknown (%s)", typeid( *el ).name() );
360         }
361     }
362     delete ep;
363
364     msg_Dbg( &sys.demuxer, "loading tags done." );
365 }
366 #undef PARSE_TAG
367
368 /*****************************************************************************
369  * InformationCreate:
370  *****************************************************************************/
371 void matroska_segment_c::InformationCreate( )
372 {
373 #if 0
374     sys.meta = vlc_meta_New();
375
376     if( psz_title )
377     {
378         vlc_meta_SetTitle( sys.meta, psz_title );
379     }
380     if( psz_date_utc )
381     {
382         vlc_meta_SetDate( sys.meta, psz_date_utc );
383     }
384
385     if( psz_segment_filename )
386     {
387         fprintf( stderr, "***** WARNING: Unhandled meta - Use custom\n" );
388     }
389     if( psz_muxing_application )
390     {
391         fprintf( stderr, "***** WARNING: Unhandled meta - Use custom\n" );
392     }
393     if( psz_writing_application )
394     {
395         fprintf( stderr, "***** WARNING: Unhandled meta - Use custom\n" );
396     }
397
398     for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
399     {
400 //        mkv_track_t *tk = tracks[i_track];
401 //        vlc_meta_t *mtk = vlc_meta_New();
402         fprintf( stderr, "***** WARNING: Unhandled child meta\n");
403     }
404 #endif
405 #if 0
406     if( i_tags_position >= 0 )
407     {
408         bool b_seekable;
409
410         stream_Control( sys.demuxer.s, STREAM_CAN_FASTSEEK, &b_seekable );
411         if( b_seekable )
412         {
413             LoadTags( );
414         }
415     }
416 #endif
417 }
418
419
420 /*****************************************************************************
421  * Misc
422  *****************************************************************************/
423
424 void matroska_segment_c::IndexAppendCluster( KaxCluster *cluster )
425 {
426 #define idx p_indexes[i_index]
427     idx.i_track       = -1;
428     idx.i_block_number= -1;
429     idx.i_position    = cluster->GetElementPosition();
430     idx.i_time        = cluster->GlobalTimecode()/ (mtime_t) 1000;
431     idx.b_key         = true;
432
433     i_index++;
434     if( i_index >= i_index_max )
435     {
436         i_index_max += 1024;
437         p_indexes = (mkv_index_t*)xrealloc( p_indexes,
438                                         sizeof( mkv_index_t ) * i_index_max );
439     }
440 #undef idx
441 }
442
443 bool matroska_segment_c::PreloadFamily( const matroska_segment_c & of_segment )
444 {
445     if ( b_preloaded )
446         return false;
447
448     for (size_t i=0; i<families.size(); i++)
449     {
450         for (size_t j=0; j<of_segment.families.size(); j++)
451         {
452             if ( *(families[i]) == *(of_segment.families[j]) )
453                 return Preload( );
454         }
455     }
456
457     return false;
458 }
459
460 bool matroska_segment_c::CompareSegmentUIDs( const matroska_segment_c * p_item_a, const matroska_segment_c * p_item_b )
461 {
462     EbmlBinary *p_tmp;
463
464     if ( p_item_a == NULL || p_item_b == NULL )
465         return false;
466
467     p_tmp = (EbmlBinary *)p_item_a->p_segment_uid;
468     if ( p_item_b->p_prev_segment_uid != NULL
469           && *p_tmp == *p_item_b->p_prev_segment_uid )
470         return true;
471
472     p_tmp = (EbmlBinary *)p_item_a->p_next_segment_uid;
473     if ( !p_tmp )
474         return false;
475
476     if ( p_item_b->p_segment_uid != NULL
477           && *p_tmp == *p_item_b->p_segment_uid )
478         return true;
479
480     if ( p_item_b->p_prev_segment_uid != NULL
481           && *p_tmp == *p_item_b->p_prev_segment_uid )
482         return true;
483
484     return false;
485 }
486
487 bool matroska_segment_c::Preload( )
488 {
489     if ( b_preloaded )
490         return false;
491
492     EbmlElement *el = NULL;
493
494     ep->Reset( &sys.demuxer );
495
496     while( ( el = ep->Get() ) != NULL )
497     {
498         if( MKV_IS_ID( el, KaxSeekHead ) )
499         {
500             /* Multiple allowed */
501             /* We bail at 10, to prevent possible recursion */
502             msg_Dbg(  &sys.demuxer, "|   + Seek head" );
503             if( i_seekhead_count < 10 )
504             {
505                 i_seekhead_position = (int64_t) es.I_O().getFilePointer();
506                 ParseSeekHead( static_cast<KaxSeekHead*>( el ) );
507             }
508         }
509         else if( MKV_IS_ID( el, KaxInfo ) )
510         {
511             /* Multiple allowed, mandatory */
512             msg_Dbg(  &sys.demuxer, "|   + Information" );
513             if( i_info_position < 0 ) // FIXME
514                 ParseInfo( static_cast<KaxInfo*>( el ) );
515             i_info_position = (int64_t) es.I_O().getFilePointer();
516         }
517         else if( MKV_IS_ID( el, KaxTracks ) )
518         {
519             /* Multiple allowed */
520             msg_Dbg(  &sys.demuxer, "|   + Tracks" );
521             if( i_tracks_position < 0 ) // FIXME
522                 ParseTracks( static_cast<KaxTracks*>( el ) );
523             if ( tracks.size() == 0 )
524             {
525                 msg_Err( &sys.demuxer, "No tracks supported" );
526                 return false;
527             }
528             i_tracks_position = (int64_t) es.I_O().getFilePointer();
529         }
530         else if( MKV_IS_ID( el, KaxCues ) )
531         {
532             msg_Dbg(  &sys.demuxer, "|   + Cues" );
533             if( i_cues_position < 0 )
534                 LoadCues( static_cast<KaxCues*>( el ) );
535             i_cues_position = (int64_t) es.I_O().getFilePointer();
536         }
537         else if( MKV_IS_ID( el, KaxCluster ) )
538         {
539             msg_Dbg( &sys.demuxer, "|   + Cluster" );
540
541             cluster = (KaxCluster*)el;
542
543             i_cluster_pos = i_start_pos = cluster->GetElementPosition();
544             ParseCluster( );
545
546             ep->Down();
547             /* stop pre-parsing the stream */
548             break;
549         }
550         else if( MKV_IS_ID( el, KaxAttachments ) )
551         {
552             msg_Dbg( &sys.demuxer, "|   + Attachments" );
553             if( i_attachments_position < 0 )
554                 ParseAttachments( static_cast<KaxAttachments*>( el ) );
555             i_attachments_position = (int64_t) es.I_O().getFilePointer();
556         }
557         else if( MKV_IS_ID( el, KaxChapters ) )
558         {
559             msg_Dbg( &sys.demuxer, "|   + Chapters" );
560             if( i_chapters_position < 0 )
561                 ParseChapters( static_cast<KaxChapters*>( el ) );
562             i_chapters_position = (int64_t) es.I_O().getFilePointer();
563         }
564         else if( MKV_IS_ID( el, KaxTag ) )
565         {
566             msg_Dbg( &sys.demuxer, "|   + Tags" );
567             /*FIXME if( i_tags_position < 0)
568                 LoadTags( static_cast<KaxTags*>( el ) );*/
569             i_tags_position = (int64_t) es.I_O().getFilePointer();
570         }
571         else if( MKV_IS_ID( el, EbmlVoid ) )
572             msg_Dbg( &sys.demuxer, "|   + Void" );
573         else
574             msg_Dbg( &sys.demuxer, "|   + Preload Unknown (%s)", typeid(*el).name() );
575     }
576
577     b_preloaded = true;
578
579     return true;
580 }
581
582 /* Here we try to load elements that were found in Seek Heads, but not yet parsed */
583 bool matroska_segment_c::LoadSeekHeadItem( const EbmlCallbacks & ClassInfos, int64_t i_element_position )
584 {
585     int64_t     i_sav_position = (int64_t)es.I_O().getFilePointer();
586     EbmlElement *el;
587
588     es.I_O().setFilePointer( i_element_position, seek_beginning );
589     el = es.FindNextID( ClassInfos, 0xFFFFFFFFL);
590
591     if( el == NULL )
592     {
593         msg_Err( &sys.demuxer, "cannot load some cues/chapters/tags etc. (broken seekhead or file)" );
594         es.I_O().setFilePointer( i_sav_position, seek_beginning );
595         return false;
596     }
597
598     if( MKV_IS_ID( el, KaxSeekHead ) )
599     {
600         /* Multiple allowed */
601         msg_Dbg( &sys.demuxer, "|   + Seek head" );
602         if( i_seekhead_count < 10 )
603         {
604             i_seekhead_position = i_element_position;
605             ParseSeekHead( static_cast<KaxSeekHead*>( el ) );
606         }
607     }
608     else if( MKV_IS_ID( el, KaxInfo ) ) // FIXME
609     {
610         /* Multiple allowed, mandatory */
611         msg_Dbg( &sys.demuxer, "|   + Information" );
612         if( i_info_position < 0 )
613             ParseInfo( static_cast<KaxInfo*>( el ) );
614         i_info_position = i_element_position;
615     }
616     else if( MKV_IS_ID( el, KaxTracks ) ) // FIXME
617     {
618         /* Multiple allowed */
619         msg_Dbg( &sys.demuxer, "|   + Tracks" );
620         if( i_tracks_position < 0 )
621             ParseTracks( static_cast<KaxTracks*>( el ) );
622         if ( tracks.size() == 0 )
623         {
624             msg_Err( &sys.demuxer, "No tracks supported" );
625             delete el;
626             es.I_O().setFilePointer( i_sav_position, seek_beginning );
627             return false;
628         }
629         i_tracks_position = i_element_position;
630     }
631     else if( MKV_IS_ID( el, KaxCues ) )
632     {
633         msg_Dbg( &sys.demuxer, "|   + Cues" );
634         if( i_cues_position < 0 )
635             LoadCues( static_cast<KaxCues*>( el ) );
636         i_cues_position = i_element_position;
637     }
638     else if( MKV_IS_ID( el, KaxAttachments ) )
639     {
640         msg_Dbg( &sys.demuxer, "|   + Attachments" );
641         if( i_attachments_position < 0 )
642             ParseAttachments( static_cast<KaxAttachments*>( el ) );
643         i_attachments_position = i_element_position;
644     }
645     else if( MKV_IS_ID( el, KaxChapters ) )
646     {
647         msg_Dbg( &sys.demuxer, "|   + Chapters" );
648         if( i_chapters_position < 0 )
649             ParseChapters( static_cast<KaxChapters*>( el ) );
650         i_chapters_position = i_element_position;
651     }
652     else if( MKV_IS_ID( el, KaxTags ) )
653     {
654         msg_Dbg( &sys.demuxer, "|   + Tags" );
655         if( i_tags_position < 0 )
656             LoadTags( static_cast<KaxTags*>( el ) );
657         i_tags_position = i_element_position;
658     }
659     else
660     {
661         msg_Dbg( &sys.demuxer, "|   + LoadSeekHeadItem Unknown (%s)", typeid(*el).name() );
662     }
663     delete el;
664
665     es.I_O().setFilePointer( i_sav_position, seek_beginning );
666     return true;
667 }
668
669 struct spoint
670 {
671     spoint(unsigned int tk, mtime_t date, int64_t pos, int64_t cpos):
672         i_track(tk),i_date(date), i_seek_pos(pos),
673         i_cluster_pos(cpos), p_next(NULL){}
674     unsigned int     i_track;
675     mtime_t i_date;
676     int64_t i_seek_pos;
677     int64_t i_cluster_pos;
678     spoint * p_next;
679 };
680
681 void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_global_position )
682 {
683     KaxBlock    *block;
684     KaxSimpleBlock *simpleblock;
685     int64_t     i_block_duration;
686     size_t      i_track;
687     int64_t     i_seek_position = i_start_pos;
688     int64_t     i_seek_time = i_start_time;
689     mtime_t     i_pts = 0;
690     spoint *p_first = NULL;
691     spoint *p_last = NULL;
692
693     if( i_global_position >= 0 )
694     {
695         /* Special case for seeking in files with no cues */
696         EbmlElement *el = NULL;
697
698         /* Start from the last known index instead of the beginning eachtime */
699         if( i_index == 0)
700             es.I_O().setFilePointer( i_start_pos, seek_beginning );
701         else
702             es.I_O().setFilePointer( p_indexes[ i_index - 1 ].i_position,
703                                      seek_beginning );
704         delete ep;
705         ep = new EbmlParser( &es, segment, &sys.demuxer );
706         cluster = NULL;
707
708         while( ( el = ep->Get() ) != NULL )
709         {
710             if( MKV_IS_ID( el, KaxCluster ) )
711             {
712                 cluster = (KaxCluster *)el;
713                 i_cluster_pos = cluster->GetElementPosition();
714                 if( i_index == 0 ||
715                     ( i_index > 0 &&
716                       p_indexes[i_index - 1].i_position < (int64_t)cluster->GetElementPosition() ) )
717                 {
718                     ParseCluster();
719                     IndexAppendCluster( cluster );
720                 }
721                 if( es.I_O().getFilePointer() >= (unsigned) i_global_position )
722                     break;
723             }
724         }
725     }
726
727     /* Don't try complex seek if we seek to 0 */
728     if( i_date == 0 )
729     {
730         es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, 0 );
731         es.I_O().setFilePointer( i_start_pos );
732
733         delete ep;
734         ep = new EbmlParser( &es, segment, &sys.demuxer );
735         cluster = NULL;
736         return;       
737     }
738
739     if ( i_index > 0 )
740     {
741         int i_idx = 0;
742
743         for( ; i_idx < i_index; i_idx++ )
744             if( p_indexes[i_idx].i_time + i_time_offset > i_date )
745                 break;
746
747         if( i_idx > 0 )
748             i_idx--;
749
750         i_seek_position = p_indexes[i_idx].i_position;
751         i_seek_time = p_indexes[i_idx].i_time;
752     }
753
754     msg_Dbg( &sys.demuxer, "seek got %"PRId64" (%d%%)",
755                 i_seek_time, (int)( 100 * i_seek_position / stream_Size( sys.demuxer.s ) ) );
756
757     es.I_O().setFilePointer( i_seek_position, seek_beginning );
758
759     delete ep;
760     ep = new EbmlParser( &es, segment, &sys.demuxer );
761     cluster = NULL;
762
763     sys.i_start_pts = i_date;
764
765     es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_date );
766
767     /* now parse until key frame */
768     for( i_track = 0; i_track < tracks.size(); i_track++ )
769     {
770         if( tracks[i_track]->fmt.i_cat == VIDEO_ES )
771         {
772             spoint * seekpoint = new spoint(i_track, i_seek_time, i_seek_position, i_seek_position);
773             if( unlikely( !seekpoint ) )
774             {
775                 for( spoint * sp = p_first; sp; )
776                 {
777                     spoint * tmp = sp;
778                     sp = sp->p_next;
779                     delete tmp;                    
780                 }
781                 return;
782             }
783             if( unlikely( !p_first ) )
784             {
785                 p_first = seekpoint;
786                 p_last = seekpoint;
787             }
788             else
789             {
790                 p_last->p_next = seekpoint;
791                 p_last = seekpoint;
792             }
793         }
794     }
795
796     while( i_pts < i_date )
797     {
798         bool b_key_picture;
799         bool b_discardable_picture;
800         if( BlockGet( block, simpleblock, &b_key_picture, &b_discardable_picture, &i_block_duration ) )
801         {
802             msg_Warn( &sys.demuxer, "cannot get block EOF?" );
803
804             return;
805         }
806
807         /* check if block's track is in our list */
808         for( i_track = 0; i_track < tracks.size(); i_track++ )
809         {
810             if( (simpleblock && tracks[i_track]->i_number == simpleblock->TrackNum()) ||
811                 (block && tracks[i_track]->i_number == block->TrackNum()) )
812                 break;
813         }
814
815         if( simpleblock )
816             i_pts = sys.i_chapter_time + simpleblock->GlobalTimecode() / (mtime_t) 1000;
817         else
818             i_pts = sys.i_chapter_time + block->GlobalTimecode() / (mtime_t) 1000;
819         if( i_track < tracks.size() )
820         {
821             if( tracks[i_track]->fmt.i_cat == VIDEO_ES && b_key_picture )
822             {
823                 /* get the seekpoint */
824                 spoint * sp;
825                 for( sp =  p_first; sp; sp = sp->p_next )
826                     if( sp->i_track == i_track )
827                         break;
828
829                 sp->i_date = i_pts;
830                 if( simpleblock )
831                     sp->i_seek_pos = simpleblock->GetElementPosition();
832                 else
833                     sp->i_seek_pos = i_block_pos;
834                 sp->i_cluster_pos = i_cluster_pos;
835             }
836         }
837
838         delete block;
839     }
840
841     /* rewind to the last I img */
842     spoint * p_min;
843     for( p_min  = p_first, p_last = p_first; p_last; p_last = p_last->p_next )
844         if( p_last->i_date < p_min->i_date )
845             p_min = p_last;
846
847     sys.i_pts = p_min->i_date;
848     cluster = (KaxCluster *) ep->UnGet( p_min->i_seek_pos, p_min->i_cluster_pos );
849
850     /* hack use BlockGet to get the cluster then goto the wanted block */
851     if ( !cluster )
852     {
853         bool b_key_picture;
854         bool b_discardable_picture;
855         BlockGet( block, simpleblock, &b_key_picture, &b_discardable_picture, &i_block_duration );
856         delete block;
857         cluster = (KaxCluster *) ep->UnGet( p_min->i_seek_pos, p_min->i_cluster_pos );
858     }
859
860     while( p_first )
861     {
862         p_min = p_first;
863         p_first = p_first->p_next;
864         delete p_min;
865     }
866 }
867
868 int matroska_segment_c::BlockFindTrackIndex( size_t *pi_track,
869                                              const KaxBlock *p_block, const KaxSimpleBlock *p_simpleblock )
870 {
871     size_t i_track;
872     for( i_track = 0; i_track < tracks.size(); i_track++ )
873     {
874         const mkv_track_t *tk = tracks[i_track];
875
876         if( ( p_block != NULL && tk->i_number == p_block->TrackNum() ) ||
877             ( p_simpleblock != NULL && tk->i_number == p_simpleblock->TrackNum() ) )
878         {
879             break;
880         }
881     }
882
883     if( i_track >= tracks.size() )
884         return VLC_EGENERIC;
885
886     if( pi_track )
887         *pi_track = i_track;
888     return VLC_SUCCESS;
889 }
890
891 static inline void fill_extra_data( mkv_track_t *p_tk, unsigned int offset )
892 {
893     if(p_tk->i_extra_data <= offset) return;
894     p_tk->fmt.i_extra = p_tk->i_extra_data - offset;
895     p_tk->fmt.p_extra = xmalloc( p_tk->fmt.i_extra );
896     if(!p_tk->fmt.p_extra) { p_tk->fmt.i_extra = 0; return; };
897     memcpy( p_tk->fmt.p_extra, p_tk->p_extra_data + offset, p_tk->fmt.i_extra );
898 }
899
900 bool matroska_segment_c::Select( mtime_t i_start_time )
901 {
902     /* add all es */
903     msg_Dbg( &sys.demuxer, "found %d es", (int)tracks.size() );
904
905     for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
906     {
907         mkv_track_t *p_tk = tracks[i_track];
908         es_format_t *p_fmt = &p_tk->fmt;
909
910         if( p_fmt->i_cat == UNKNOWN_ES || !p_tk->psz_codec )
911         {
912             msg_Warn( &sys.demuxer, "invalid track[%d, n=%d]", (int)i_track, p_tk->i_number );
913             p_tk->p_es = NULL;
914             continue;
915         }
916
917         if( !strcmp( p_tk->psz_codec, "V_MS/VFW/FOURCC" ) )
918         {
919             if( p_tk->i_extra_data < (int)sizeof( BITMAPINFOHEADER ) )
920             {
921                 msg_Err( &sys.demuxer, "missing/invalid BITMAPINFOHEADER" );
922                 p_tk->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
923             }
924             else
925             {
926                 BITMAPINFOHEADER *p_bih = (BITMAPINFOHEADER*)p_tk->p_extra_data;
927
928                 p_tk->fmt.video.i_width = GetDWLE( &p_bih->biWidth );
929                 p_tk->fmt.video.i_height= GetDWLE( &p_bih->biHeight );
930                 p_tk->fmt.i_codec       = GetFOURCC( &p_bih->biCompression );
931
932                 p_tk->fmt.i_extra       = GetDWLE( &p_bih->biSize ) - sizeof( BITMAPINFOHEADER );
933                 if( p_tk->fmt.i_extra > 0 )
934                 {
935                     /* Very unlikely yet possible: bug #5659*/
936                     size_t maxlen = p_tk->i_extra_data - sizeof( BITMAPINFOHEADER );
937                     p_tk->fmt.i_extra = ( p_tk->fmt.i_extra < maxlen )?
938                         p_tk->fmt.i_extra : maxlen;
939
940                     p_tk->fmt.p_extra = xmalloc( p_tk->fmt.i_extra );
941                     memcpy( p_tk->fmt.p_extra, &p_bih[1], p_tk->fmt.i_extra );
942                 }
943             }
944             p_tk->b_dts_only = true;
945         }
946         else if( !strcmp( p_tk->psz_codec, "V_MPEG1" ) ||
947                  !strcmp( p_tk->psz_codec, "V_MPEG2" ) )
948         {
949             p_tk->fmt.i_codec = VLC_CODEC_MPGV;
950             if( p_tk->i_extra_data )
951                 fill_extra_data( p_tk, 0 );
952         }
953         else if( !strncmp( p_tk->psz_codec, "V_THEORA", 8 ) )
954         {
955             p_tk->fmt.i_codec = VLC_CODEC_THEORA;
956             fill_extra_data( p_tk, 0 );
957             p_tk->b_pts_only = true;
958         }
959         else if( !strncmp( p_tk->psz_codec, "V_REAL/RV", 9 ) )
960         {
961             uint8_t *p = p_tk->p_extra_data;
962
963             if( !strcmp( p_tk->psz_codec, "V_REAL/RV10" ) )
964                 p_fmt->i_codec = VLC_CODEC_RV10;
965             else if( !strcmp( p_tk->psz_codec, "V_REAL/RV20" ) )
966                 p_fmt->i_codec = VLC_CODEC_RV20;
967             else if( !strcmp( p_tk->psz_codec, "V_REAL/RV30" ) )
968                 p_fmt->i_codec = VLC_CODEC_RV30;
969             else if( !strcmp( p_tk->psz_codec, "V_REAL/RV40" ) )
970                 p_fmt->i_codec = VLC_CODEC_RV40;
971
972             /* Extract the framerate from the header */
973             if( p_tk->i_extra_data >= 26 &&
974                 p[4] == 'V' && p[5] == 'I' && p[6] == 'D' && p[7] == 'O' &&
975                 p[8] == 'R' && p[9] == 'V' &&
976                 (p[10] == '3' || p[10] == '4') && p[11] == '0' )
977             {
978                 p_tk->fmt.video.i_frame_rate =
979                     p[22] << 24 | p[23] << 16 | p[24] << 8 | p[25] << 0;
980                 p_tk->fmt.video.i_frame_rate_base = 65536;
981             }
982
983             fill_extra_data( p_tk, 26 );
984             p_tk->b_dts_only = true;
985         }
986         else if( !strncmp( p_tk->psz_codec, "V_DIRAC", 7 ) )
987         {
988             p_tk->fmt.i_codec = VLC_CODEC_DIRAC;
989         }
990         else if( !strncmp( p_tk->psz_codec, "V_VP8", 5 ) )
991         {
992             p_tk->fmt.i_codec = VLC_CODEC_VP8;
993             p_tk->b_pts_only = true;
994         }
995         else if( !strncmp( p_tk->psz_codec, "V_MPEG4", 7 ) )
996         {
997             if( !strcmp( p_tk->psz_codec, "V_MPEG4/MS/V3" ) )
998             {
999                 p_tk->fmt.i_codec = VLC_CODEC_DIV3;
1000             }
1001             else if( !strncmp( p_tk->psz_codec, "V_MPEG4/ISO", 11 ) )
1002             {
1003                 /* A MPEG 4 codec, SP, ASP, AP or AVC */
1004                 if( !strcmp( p_tk->psz_codec, "V_MPEG4/ISO/AVC" ) )
1005                     p_tk->fmt.i_codec = VLC_FOURCC( 'a', 'v', 'c', '1' );
1006                 else
1007                     p_tk->fmt.i_codec = VLC_CODEC_MP4V;
1008                 fill_extra_data( p_tk, 0 );
1009             }
1010         }
1011         else if( !strcmp( p_tk->psz_codec, "V_QUICKTIME" ) )
1012         {
1013             MP4_Box_t *p_box = (MP4_Box_t*)xmalloc( sizeof( MP4_Box_t ) );
1014             stream_t *p_mp4_stream = stream_MemoryNew( VLC_OBJECT(&sys.demuxer),
1015                                                        p_tk->p_extra_data,
1016                                                        p_tk->i_extra_data,
1017                                                        true );
1018             if( MP4_ReadBoxCommon( p_mp4_stream, p_box ) &&
1019                 MP4_ReadBox_sample_vide( p_mp4_stream, p_box ) )
1020             {
1021                 p_tk->fmt.i_codec = p_box->i_type;
1022                 p_tk->fmt.video.i_width = p_box->data.p_sample_vide->i_width;
1023                 p_tk->fmt.video.i_height = p_box->data.p_sample_vide->i_height;
1024                 p_tk->fmt.i_extra = p_box->data.p_sample_vide->i_qt_image_description;
1025                 p_tk->fmt.p_extra = xmalloc( p_tk->fmt.i_extra );
1026                 memcpy( p_tk->fmt.p_extra, p_box->data.p_sample_vide->p_qt_image_description, p_tk->fmt.i_extra );
1027                 MP4_FreeBox_sample_vide( p_box );
1028             }
1029             else
1030             {
1031                 free( p_box );
1032             }
1033             stream_Delete( p_mp4_stream );
1034         }
1035         else if( !strcmp( p_tk->psz_codec, "V_MJPEG" ) )
1036         {
1037             p_tk->fmt.i_codec = VLC_CODEC_MJPG;
1038         }
1039         else if( !strcmp( p_tk->psz_codec, "A_MS/ACM" ) )
1040         {
1041             if( p_tk->i_extra_data < (int)sizeof( WAVEFORMATEX ) )
1042             {
1043                 msg_Err( &sys.demuxer, "missing/invalid WAVEFORMATEX" );
1044                 p_tk->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1045             }
1046             else
1047             {
1048                 WAVEFORMATEX *p_wf = (WAVEFORMATEX*)p_tk->p_extra_data;
1049
1050                 wf_tag_to_fourcc( GetWLE( &p_wf->wFormatTag ), &p_tk->fmt.i_codec, NULL );
1051
1052                 p_tk->fmt.audio.i_channels   = GetWLE( &p_wf->nChannels );
1053                 p_tk->fmt.audio.i_rate = GetDWLE( &p_wf->nSamplesPerSec );
1054                 p_tk->fmt.i_bitrate    = GetDWLE( &p_wf->nAvgBytesPerSec ) * 8;
1055                 p_tk->fmt.audio.i_blockalign = GetWLE( &p_wf->nBlockAlign );;
1056                 p_tk->fmt.audio.i_bitspersample = GetWLE( &p_wf->wBitsPerSample );
1057
1058                 p_tk->fmt.i_extra            = GetWLE( &p_wf->cbSize );
1059                 if( p_tk->fmt.i_extra > 0 )
1060                 {
1061                     p_tk->fmt.p_extra = xmalloc( p_tk->fmt.i_extra );
1062                     memcpy( p_tk->fmt.p_extra, &p_wf[1], p_tk->fmt.i_extra );
1063                 }
1064             }
1065         }
1066         else if( !strcmp( p_tk->psz_codec, "A_MPEG/L3" ) ||
1067                  !strcmp( p_tk->psz_codec, "A_MPEG/L2" ) ||
1068                  !strcmp( p_tk->psz_codec, "A_MPEG/L1" ) )
1069         {
1070             p_tk->fmt.i_codec = VLC_CODEC_MPGA;
1071         }
1072         else if( !strcmp( p_tk->psz_codec, "A_AC3" ) )
1073         {
1074             p_tk->fmt.i_codec = VLC_CODEC_A52;
1075         }
1076         else if( !strcmp( p_tk->psz_codec, "A_EAC3" ) )
1077         {
1078             p_tk->fmt.i_codec = VLC_CODEC_EAC3;
1079         }
1080         else if( !strcmp( p_tk->psz_codec, "A_DTS" ) )
1081         {
1082             p_tk->fmt.i_codec = VLC_CODEC_DTS;
1083         }
1084         else if( !strcmp( p_tk->psz_codec, "A_MLP" ) )
1085         {
1086             p_tk->fmt.i_codec = VLC_CODEC_MLP;
1087         }
1088         else if( !strcmp( p_tk->psz_codec, "A_TRUEHD" ) )
1089         {
1090             /* FIXME when more samples arrive */
1091             p_tk->fmt.i_codec = VLC_CODEC_TRUEHD;
1092             p_fmt->b_packetized = false;
1093         }
1094         else if( !strcmp( p_tk->psz_codec, "A_FLAC" ) )
1095         {
1096             p_tk->fmt.i_codec = VLC_CODEC_FLAC;
1097             fill_extra_data( p_tk, 0 );
1098         }
1099         else if( !strcmp( p_tk->psz_codec, "A_VORBIS" ) )
1100         {
1101             p_tk->fmt.i_codec = VLC_CODEC_VORBIS;
1102             fill_extra_data( p_tk, 0 );
1103         }
1104         else if( !strncmp( p_tk->psz_codec, "A_AAC/MPEG2/", strlen( "A_AAC/MPEG2/" ) ) ||
1105                  !strncmp( p_tk->psz_codec, "A_AAC/MPEG4/", strlen( "A_AAC/MPEG4/" ) ) )
1106         {
1107             int i_profile, i_srate, sbr = 0;
1108             static const unsigned int i_sample_rates[] =
1109             {
1110                     96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
1111                     16000, 12000, 11025,  8000,  7350,     0,     0,     0
1112             };
1113
1114             p_tk->fmt.i_codec = VLC_CODEC_MP4A;
1115             /* create data for faad (MP4DecSpecificDescrTag)*/
1116
1117             if( !strcmp( &p_tk->psz_codec[12], "MAIN" ) )
1118             {
1119                 i_profile = 0;
1120             }
1121             else if( !strcmp( &p_tk->psz_codec[12], "LC" ) )
1122             {
1123                 i_profile = 1;
1124             }
1125             else if( !strcmp( &p_tk->psz_codec[12], "SSR" ) )
1126             {
1127                 i_profile = 2;
1128             }
1129             else if( !strcmp( &p_tk->psz_codec[12], "LC/SBR" ) )
1130             {
1131                 i_profile = 1;
1132                 sbr = 1;
1133             }
1134             else
1135             {
1136                 i_profile = 3;
1137             }
1138
1139             for( i_srate = 0; i_srate < 13; i_srate++ )
1140             {
1141                 if( i_sample_rates[i_srate] == p_tk->i_original_rate )
1142                 {
1143                     break;
1144                 }
1145             }
1146             msg_Dbg( &sys.demuxer, "profile=%d srate=%d", i_profile, i_srate );
1147
1148             p_tk->fmt.i_extra = sbr ? 5 : 2;
1149             p_tk->fmt.p_extra = xmalloc( p_tk->fmt.i_extra );
1150             ((uint8_t*)p_tk->fmt.p_extra)[0] = ((i_profile + 1) << 3) | ((i_srate&0xe) >> 1);
1151             ((uint8_t*)p_tk->fmt.p_extra)[1] = ((i_srate & 0x1) << 7) | (p_tk->fmt.audio.i_channels << 3);
1152             if (sbr != 0)
1153             {
1154                 int syncExtensionType = 0x2B7;
1155                 int iDSRI;
1156                 for (iDSRI=0; iDSRI<13; iDSRI++)
1157                     if( i_sample_rates[iDSRI] == p_tk->fmt.audio.i_rate )
1158                         break;
1159                 ((uint8_t*)p_tk->fmt.p_extra)[2] = (syncExtensionType >> 3) & 0xFF;
1160                 ((uint8_t*)p_tk->fmt.p_extra)[3] = ((syncExtensionType & 0x7) << 5) | 5;
1161                 ((uint8_t*)p_tk->fmt.p_extra)[4] = ((1 & 0x1) << 7) | (iDSRI << 3);
1162             }
1163         }
1164         else if( !strcmp( p_tk->psz_codec, "A_AAC" ) )
1165         {
1166             p_tk->fmt.i_codec = VLC_CODEC_MP4A;
1167             fill_extra_data( p_tk, 0 );
1168         }
1169         else if( !strcmp( p_tk->psz_codec, "A_WAVPACK4" ) )
1170         {
1171             p_tk->fmt.i_codec = VLC_CODEC_WAVPACK;
1172             fill_extra_data( p_tk, 0 );
1173         }
1174         else if( !strcmp( p_tk->psz_codec, "A_TTA1" ) )
1175         {
1176             p_fmt->i_codec = VLC_CODEC_TTA;
1177             if( p_tk->i_extra_data > 0 )
1178             {
1179               fill_extra_data( p_tk, 0 );
1180             }
1181             else
1182             {
1183                 p_fmt->i_extra = 30;
1184                 p_fmt->p_extra = xmalloc( p_fmt->i_extra );
1185                 uint8_t *p_extra = (uint8_t*)p_fmt->p_extra;
1186                 memcpy( &p_extra[ 0], "TTA1", 4 );
1187                 SetWLE( &p_extra[ 4], 1 );
1188                 SetWLE( &p_extra[ 6], p_fmt->audio.i_channels );
1189                 SetWLE( &p_extra[ 8], p_fmt->audio.i_bitspersample );
1190                 SetDWLE( &p_extra[10], p_fmt->audio.i_rate );
1191                 SetDWLE( &p_extra[14], 0xffffffff );
1192                 memset( &p_extra[18], 0, 30  - 18 );
1193             }
1194         }
1195         else if( !strcmp( p_tk->psz_codec, "A_PCM/INT/BIG" ) ||
1196                  !strcmp( p_tk->psz_codec, "A_PCM/INT/LIT" ) ||
1197                  !strcmp( p_tk->psz_codec, "A_PCM/FLOAT/IEEE" ) )
1198         {
1199             if( !strcmp( p_tk->psz_codec, "A_PCM/INT/BIG" ) )
1200             {
1201                 p_tk->fmt.i_codec = VLC_FOURCC( 't', 'w', 'o', 's' );
1202             }
1203             else
1204             {
1205                 p_tk->fmt.i_codec = VLC_FOURCC( 'a', 'r', 'a', 'w' );
1206             }
1207             p_tk->fmt.audio.i_blockalign = ( p_tk->fmt.audio.i_bitspersample + 7 ) / 8 * p_tk->fmt.audio.i_channels;
1208         }
1209         else if( !strncmp( p_tk->psz_codec, "A_REAL/", 7 ) )
1210         {
1211             if( !strcmp( p_tk->psz_codec, "A_REAL/COOK" ) )
1212                 p_tk->fmt.i_codec = VLC_CODEC_COOK;
1213             else if( !strcmp( p_tk->psz_codec, "A_REAL/ATRC" ) )
1214                 p_tk->fmt.i_codec = VLC_CODEC_ATRAC3;
1215             else if( !strcmp( p_tk->psz_codec, "A_REAL/28_8" ) )
1216                 p_tk->fmt.i_codec = VLC_CODEC_RA_288;
1217             /* FIXME 14_4, RALF and SIPR */
1218             fill_extra_data( p_tk, p_tk->fmt.i_codec == VLC_CODEC_RA_288 ? 0 : 0 /*78 - FIXME need to implement reading support for cook */ );
1219         }
1220         else if( !strcmp( p_tk->psz_codec, "A_REAL/14_4" ) )
1221         {
1222             p_fmt->i_codec = VLC_CODEC_RA_144;
1223             p_fmt->audio.i_channels = 1;
1224             p_fmt->audio.i_rate = 8000;
1225             p_fmt->audio.i_blockalign = 0x14;
1226         }
1227         else if( !strcmp( p_tk->psz_codec, "S_KATE" ) )
1228         {
1229             p_tk->fmt.i_codec = VLC_CODEC_KATE;
1230             p_tk->fmt.subs.psz_encoding = strdup( "UTF-8" );
1231
1232             fill_extra_data( p_tk, 0 );
1233         }
1234         else if( !strcmp( p_tk->psz_codec, "S_TEXT/ASCII" ) )
1235         {
1236             p_fmt->i_codec = VLC_CODEC_SUBT;
1237             p_fmt->subs.psz_encoding = strdup( "ASCII" );
1238         }
1239         else if( !strcmp( p_tk->psz_codec, "S_TEXT/UTF8" ) )
1240         {
1241             p_tk->fmt.i_codec = VLC_CODEC_SUBT;
1242             p_tk->fmt.subs.psz_encoding = strdup( "UTF-8" );
1243         }
1244         else if( !strcmp( p_tk->psz_codec, "S_TEXT/USF" ) )
1245         {
1246             p_tk->fmt.i_codec = VLC_FOURCC( 'u', 's', 'f', ' ' );
1247             p_tk->fmt.subs.psz_encoding = strdup( "UTF-8" );
1248             if( p_tk->i_extra_data )
1249                 fill_extra_data( p_tk, 0 );
1250         }
1251         else if( !strcmp( p_tk->psz_codec, "S_TEXT/SSA" ) ||
1252                  !strcmp( p_tk->psz_codec, "S_TEXT/ASS" ) ||
1253                  !strcmp( p_tk->psz_codec, "S_SSA" ) ||
1254                  !strcmp( p_tk->psz_codec, "S_ASS" ))
1255         {
1256             p_tk->fmt.i_codec = VLC_CODEC_SSA;
1257             p_tk->fmt.subs.psz_encoding = strdup( "UTF-8" );
1258             if( p_tk->i_extra_data )
1259                 fill_extra_data( p_tk, 0 );
1260         }
1261         else if( !strcmp( p_tk->psz_codec, "S_VOBSUB" ) )
1262         {
1263             p_tk->fmt.i_codec = VLC_CODEC_SPU;
1264             if( p_tk->i_extra_data )
1265             {
1266                 char *psz_start;
1267                 char *psz_buf = (char *)malloc( p_tk->i_extra_data + 1);
1268                 if( psz_buf != NULL )
1269                 {
1270                     memcpy( psz_buf, p_tk->p_extra_data , p_tk->i_extra_data );
1271                     psz_buf[p_tk->i_extra_data] = '\0';
1272
1273                     psz_start = strstr( psz_buf, "size:" );
1274                     if( psz_start &&
1275                         vobsub_size_parse( psz_start,
1276                                            &p_tk->fmt.subs.spu.i_original_frame_width,
1277                                            &p_tk->fmt.subs.spu.i_original_frame_height ) == VLC_SUCCESS )
1278                     {
1279                         msg_Dbg( &sys.demuxer, "original frame size vobsubs: %dx%d",
1280                                  p_tk->fmt.subs.spu.i_original_frame_width,
1281                                  p_tk->fmt.subs.spu.i_original_frame_height );
1282                     }
1283                     else
1284                     {
1285                         msg_Warn( &sys.demuxer, "reading original frame size for vobsub failed" );
1286                     }
1287
1288                     psz_start = strstr( psz_buf, "palette:" );
1289                     if( psz_start &&
1290                         vobsub_palette_parse( psz_start, &p_tk->fmt.subs.spu.palette[1] ) == VLC_SUCCESS )
1291                     {
1292                         p_tk->fmt.subs.spu.palette[0] =  0xBeef;
1293                         msg_Dbg( &sys.demuxer, "vobsub palette read" );
1294                     }
1295                     else
1296                     {
1297                         msg_Warn( &sys.demuxer, "reading original palette failed" );
1298                     }
1299                     free( psz_buf );
1300                 }
1301             }
1302         }
1303         else if( !strcmp( p_tk->psz_codec, "S_HDMV/PGS" ) )
1304         {
1305             p_tk->fmt.i_codec = VLC_CODEC_BD_PG;
1306         }
1307         else if( !strcmp( p_tk->psz_codec, "B_VOBBTN" ) )
1308         {
1309             p_tk->fmt.i_cat = NAV_ES;
1310             continue;
1311         }
1312         else
1313         {
1314             msg_Err( &sys.demuxer, "unknown codec id=`%s'", p_tk->psz_codec );
1315             p_tk->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1316         }
1317         if( p_tk->b_default )
1318         {
1319             p_tk->fmt.i_priority = 1000;
1320         }
1321
1322         p_tk->p_es = es_out_Add( sys.demuxer.out, &p_tk->fmt );
1323
1324         /* Turn on a subtitles track if it has been flagged as default -
1325          * but only do this if no subtitles track has already been engaged,
1326          * either by an earlier 'default track' (??) or by default
1327          * language choice behaviour.
1328          */
1329         if( p_tk->b_default )
1330         {
1331             es_out_Control( sys.demuxer.out,
1332                             ES_OUT_SET_ES_DEFAULT,
1333                             p_tk->p_es );
1334         }
1335     }
1336     es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_start_time );
1337
1338     sys.i_start_pts = i_start_time;
1339     // reset the stream reading to the first cluster of the segment used
1340     es.I_O().setFilePointer( i_start_pos );
1341
1342     delete ep;
1343     ep = new EbmlParser( &es, segment, &sys.demuxer );
1344
1345     return true;
1346 }
1347
1348 void matroska_segment_c::UnSelect( )
1349 {
1350     sys.p_ev->ResetPci();
1351     for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
1352     {
1353         if ( tracks[i_track]->p_es != NULL )
1354         {
1355 //            es_format_Clean( &tracks[i_track]->fmt );
1356             es_out_Del( sys.demuxer.out, tracks[i_track]->p_es );
1357             tracks[i_track]->p_es = NULL;
1358         }
1359     }
1360     delete ep;
1361     ep = NULL;
1362 }
1363
1364 int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_simpleblock, bool *pb_key_picture, bool *pb_discardable_picture, int64_t *pi_duration )
1365 {
1366     pp_simpleblock = NULL;
1367     pp_block = NULL;
1368
1369     *pb_key_picture         = true;
1370     *pb_discardable_picture = false;
1371
1372     for( ;; )
1373     {
1374         EbmlElement *el = NULL;
1375         int         i_level;
1376
1377         if ( ep == NULL )
1378             return VLC_EGENERIC;
1379
1380         if( pp_simpleblock != NULL || ((el = ep->Get()) == NULL && pp_block != NULL) )
1381         {
1382             /* Check blocks validity to protect againts broken files */
1383             if( BlockFindTrackIndex( NULL, pp_block , pp_simpleblock ) )
1384             {
1385                 delete pp_block;
1386                 pp_simpleblock = NULL;
1387                 pp_block = NULL;
1388                 continue;
1389             }
1390             if( pp_simpleblock != NULL )
1391             {
1392                 *pb_key_picture         = pp_simpleblock->IsKeyframe();
1393                 *pb_discardable_picture = pp_simpleblock->IsDiscardable();
1394             }
1395
1396             /* update the index */
1397 #define idx p_indexes[i_index - 1]
1398             if( i_index > 0 && idx.i_time == -1 )
1399             {
1400                 if ( pp_simpleblock != NULL )
1401                     idx.i_time        = pp_simpleblock->GlobalTimecode() / (mtime_t)1000;
1402                 else
1403                     idx.i_time        = (*pp_block).GlobalTimecode() / (mtime_t)1000;
1404                 idx.b_key         = *pb_key_picture;
1405             }
1406 #undef idx
1407             return VLC_SUCCESS;
1408         }
1409
1410         i_level = ep->GetLevel();
1411
1412         if( el == NULL )
1413         {
1414             if( i_level > 1 )
1415             {
1416                 ep->Up();
1417                 continue;
1418             }
1419             msg_Warn( &sys.demuxer, "EOF" );
1420             return VLC_EGENERIC;
1421         }
1422
1423         /* Verify that we are still inside our cluster
1424          * It can happens whith broken files and when seeking
1425          * without index */
1426         if( i_level > 1 )
1427         {
1428             if( cluster && !ep->IsTopPresent( cluster ) )
1429             {
1430                 msg_Warn( &sys.demuxer, "Unexpected escape from current cluster" );
1431                 cluster = NULL;
1432             }
1433             if( !cluster )
1434                 continue;
1435         }
1436
1437         /* do parsing */
1438         switch ( i_level )
1439         {
1440         case 1:
1441             if( MKV_IS_ID( el, KaxCluster ) )
1442             {
1443                 cluster = (KaxCluster*)el;
1444                 i_cluster_pos = cluster->GetElementPosition();
1445
1446                 // reset silent tracks
1447                 for (size_t i=0; i<tracks.size(); i++)
1448                 {
1449                     tracks[i]->b_silent = false;
1450                 }
1451
1452                 ep->Down();
1453             }
1454             else if( MKV_IS_ID( el, KaxCues ) )
1455             {
1456                 msg_Warn( &sys.demuxer, "find KaxCues FIXME" );
1457                 return VLC_EGENERIC;
1458             }
1459             else
1460             {
1461                 msg_Dbg( &sys.demuxer, "unknown (%s)", typeid( el ).name() );
1462             }
1463             break;
1464         case 2:
1465             if( MKV_IS_ID( el, KaxClusterTimecode ) )
1466             {
1467                 KaxClusterTimecode &ctc = *(KaxClusterTimecode*)el;
1468
1469                 ctc.ReadData( es.I_O(), SCOPE_ALL_DATA );
1470                 cluster->InitTimecode( uint64( ctc ), i_timescale );
1471  
1472                 /* add it to the index */
1473                 if( i_index == 0 ||
1474                     ( i_index > 0 &&
1475                       p_indexes[i_index - 1].i_position < (int64_t)cluster->GetElementPosition() ) )
1476                     IndexAppendCluster( cluster );
1477             }
1478             else if( MKV_IS_ID( el, KaxClusterSilentTracks ) )
1479             {
1480                 ep->Down();
1481             }
1482             else if( MKV_IS_ID( el, KaxBlockGroup ) )
1483             {
1484                 i_block_pos = el->GetElementPosition();
1485                 ep->Down();
1486             }
1487             else if( MKV_IS_ID( el, KaxSimpleBlock ) )
1488             {
1489                 pp_simpleblock = (KaxSimpleBlock*)el;
1490
1491                 pp_simpleblock->ReadData( es.I_O() );
1492                 pp_simpleblock->SetParent( *cluster );
1493             }
1494             break;
1495         case 3:
1496             if( MKV_IS_ID( el, KaxBlock ) )
1497             {
1498                 pp_block = (KaxBlock*)el;
1499
1500                 pp_block->ReadData( es.I_O() );
1501                 pp_block->SetParent( *cluster );
1502
1503                 ep->Keep();
1504             }
1505             else if( MKV_IS_ID( el, KaxBlockDuration ) )
1506             {
1507                 KaxBlockDuration &dur = *(KaxBlockDuration*)el;
1508
1509                 dur.ReadData( es.I_O() );
1510                 *pi_duration = uint64( dur );
1511             }
1512             else if( MKV_IS_ID( el, KaxReferenceBlock ) )
1513             {
1514                 KaxReferenceBlock &ref = *(KaxReferenceBlock*)el;
1515
1516                 ref.ReadData( es.I_O() );
1517
1518                 if( *pb_key_picture )
1519                     *pb_key_picture = false;
1520                 else if( int64( ref ) > 0 )
1521                     *pb_discardable_picture = true;
1522             }
1523             else if( MKV_IS_ID( el, KaxClusterSilentTrackNumber ) )
1524             {
1525                 KaxClusterSilentTrackNumber &track_num = *(KaxClusterSilentTrackNumber*)el;
1526                 track_num.ReadData( es.I_O() );
1527                 // find the track
1528                 for (size_t i=0; i<tracks.size(); i++)
1529                 {
1530                     if ( tracks[i]->i_number == uint32(track_num))
1531                     {
1532                         tracks[i]->b_silent = true;
1533                         break;
1534                     }
1535                 }
1536             }
1537             break;
1538         default:
1539             msg_Err( &sys.demuxer, "invalid level = %d", i_level );
1540             return VLC_EGENERIC;
1541         }
1542     }
1543 }
1544