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