]> git.sesse.net Git - vlc/blob - modules/demux/mkv/matroska_segment.cpp
Regression fix for non-SPU tracks in MKV containers.
[vlc] / modules / demux / mkv / matroska_segment.cpp
1 /*****************************************************************************
2  * matroska_segment.cpp : matroska demuxer
3  *****************************************************************************
4  * Copyright (C) 2003-2010 VLC authors and VideoLAN
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Steve Lhomme <steve.lhomme@free.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program; if not, write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #include "matroska_segment.hpp"
26 #include "chapters.hpp"
27 #include "demux.hpp"
28 #include "util.hpp"
29 #include "Ebml_parser.hpp"
30
31 matroska_segment_c::matroska_segment_c( demux_sys_t & demuxer, EbmlStream & estream )
32     :segment(NULL)
33     ,es(estream)
34     ,i_timescale(MKVD_TIMECODESCALE)
35     ,i_duration(-1)
36     ,i_start_time(0)
37     ,i_seekhead_count(0)
38     ,i_seekhead_position(-1)
39     ,i_cues_position(-1)
40     ,i_tracks_position(-1)
41     ,i_info_position(-1)
42     ,i_chapters_position(-1)
43     ,i_tags_position(-1)
44     ,i_attachments_position(-1)
45     ,cluster(NULL)
46     ,i_block_pos(0)
47     ,i_cluster_pos(0)
48     ,i_start_pos(0)
49     ,p_segment_uid(NULL)
50     ,p_prev_segment_uid(NULL)
51     ,p_next_segment_uid(NULL)
52     ,b_cues(false)
53     ,i_index(0)
54     ,i_index_max(1024)
55     ,psz_muxing_application(NULL)
56     ,psz_writing_application(NULL)
57     ,psz_segment_filename(NULL)
58     ,psz_title(NULL)
59     ,psz_date_utc(NULL)
60     ,i_default_edition(0)
61     ,sys(demuxer)
62     ,ep(NULL)
63     ,b_preloaded(false)
64     ,b_ref_external_segments(false)
65 {
66     p_indexes = (mkv_index_t*)malloc( sizeof( mkv_index_t ) * i_index_max );
67 }
68
69 matroska_segment_c::~matroska_segment_c()
70 {
71     for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
72     {
73         delete tracks[i_track]->p_compression_data;
74         es_format_Clean( &tracks[i_track]->fmt );
75         delete tracks[i_track]->p_sys;
76         free( tracks[i_track]->p_extra_data );
77         free( tracks[i_track]->psz_codec );
78         delete tracks[i_track];
79     }
80
81     free( psz_writing_application );
82     free( psz_muxing_application );
83     free( psz_segment_filename );
84     free( psz_title );
85     free( psz_date_utc );
86     free( p_indexes );
87
88     delete ep;
89     delete segment;
90     delete p_segment_uid;
91     delete p_prev_segment_uid;
92     delete p_next_segment_uid;
93
94     vlc_delete_all( stored_editions );
95     vlc_delete_all( translations );
96     vlc_delete_all( families );
97 }
98
99
100 /*****************************************************************************
101  * Tools                                                                     *
102  *****************************************************************************
103  *  * LoadCues : load the cues element and update index
104  *  * LoadTags : load ... the tags element
105  *  * InformationCreate : create all information, load tags if present
106  *****************************************************************************/
107 void matroska_segment_c::LoadCues( KaxCues *cues )
108 {
109     bool b_invalid_cue;
110     EbmlParser  *ep;
111     EbmlElement *el;
112
113     if( b_cues )
114     {
115         msg_Err( &sys.demuxer, "There can be only 1 Cues per section." );
116         return;
117     }
118
119     ep = new EbmlParser( &es, cues, &sys.demuxer );
120     while( ( el = ep->Get() ) != NULL )
121     {
122         if( MKV_IS_ID( el, KaxCuePoint ) )
123         {
124             b_invalid_cue = false;
125 #define idx p_indexes[i_index]
126
127             idx.i_track       = -1;
128             idx.i_block_number= -1;
129             idx.i_position    = -1;
130             idx.i_time        = 0;
131             idx.b_key         = true;
132
133             ep->Down();
134             while( ( el = ep->Get() ) != NULL )
135             {
136                 if( MKV_IS_ID( el, KaxCueTime ) )
137                 {
138                     KaxCueTime &ctime = *(KaxCueTime*)el;
139                     try
140                     {
141                         if( unlikely( ctime.GetSize() >= SIZE_MAX ) )
142                         {
143                             msg_Err( &sys.demuxer, "CueTime size too big");
144                             b_invalid_cue = true;
145                             break;
146                         }
147                         ctime.ReadData( es.I_O() );
148                     }
149                     catch(...)
150                     {
151                         msg_Err( &sys.demuxer, "Error while reading CueTime" );
152                         b_invalid_cue = true;
153                         break;
154                     }
155                     idx.i_time = uint64( ctime ) * i_timescale / (mtime_t)1000;
156                 }
157                 else if( MKV_IS_ID( el, KaxCueTrackPositions ) )
158                 {
159                     ep->Down();
160                     try
161                     {
162                         while( ( el = ep->Get() ) != NULL )
163                         {
164                             if( unlikely( el->GetSize() >= SIZE_MAX ) )
165                             {
166                                 ep->Up();
167                                 msg_Err( &sys.demuxer, "Error %s too big, aborting", typeid(*el).name() );
168                                 b_invalid_cue = true;
169                                 break;
170                             }
171
172                             if( MKV_IS_ID( el, KaxCueTrack ) )
173                             {
174                                 KaxCueTrack &ctrack = *(KaxCueTrack*)el;
175                                 ctrack.ReadData( es.I_O() );
176                                 idx.i_track = uint16( ctrack );
177                             }
178                             else if( MKV_IS_ID( el, KaxCueClusterPosition ) )
179                             {
180                                 KaxCueClusterPosition &ccpos = *(KaxCueClusterPosition*)el;
181
182                                 ccpos.ReadData( es.I_O() );
183                                 idx.i_position = segment->GetGlobalPosition( uint64( ccpos ) );
184                             }
185                             else if( MKV_IS_ID( el, KaxCueBlockNumber ) )
186                             {
187                                 KaxCueBlockNumber &cbnum = *(KaxCueBlockNumber*)el;
188
189                                 cbnum.ReadData( es.I_O() );
190                                 idx.i_block_number = uint32( cbnum );
191                             }
192                             else
193                             {
194                                 msg_Dbg( &sys.demuxer, "         * Unknown (%s)", typeid(*el).name() );
195                             }
196                         }
197                     }
198                     catch(...)
199                     {
200                         ep->Up();   
201                         msg_Err( &sys.demuxer, "Error while reading %s", typeid(*el).name() );
202                         b_invalid_cue = true;
203                         break;
204                     }
205                     ep->Up();
206                 }
207                 else
208                 {
209                     msg_Dbg( &sys.demuxer, "     * Unknown (%s)", typeid(*el).name() );
210                 }
211             }
212             ep->Up();
213
214 #if 0
215             msg_Dbg( &sys.demuxer, " * added time=%"PRId64" pos=%"PRId64
216                      " track=%d bnum=%d", idx.i_time, idx.i_position,
217                      idx.i_track, idx.i_block_number );
218 #endif
219             if( likely( !b_invalid_cue ) )
220             {
221                 i_index++;
222                 if( i_index >= i_index_max )
223                 {
224                     i_index_max += 1024;
225                     p_indexes = (mkv_index_t*)xrealloc( p_indexes,
226                                                         sizeof( mkv_index_t ) * i_index_max );
227                 }
228             }
229 #undef idx
230         }
231         else
232         {
233             msg_Dbg( &sys.demuxer, " * Unknown (%s)", typeid(*el).name() );
234         }
235     }
236     delete ep;
237     b_cues = true;
238     msg_Dbg( &sys.demuxer, "|   - loading cues done." );
239 }
240
241
242 static const struct {
243     vlc_meta_type_t type;
244     const char *key;
245     int target_type; /* 0 is valid for all target_type */
246 } metadata_map[] = {
247                      {vlc_meta_Album,       "TITLE",         50},
248                      {vlc_meta_Title,       "TITLE",         0},
249                      {vlc_meta_Artist,      "ARTIST",        0},
250                      {vlc_meta_Genre,       "GENRE",         0},
251                      {vlc_meta_Copyright,   "COPYRIGHT",     0},
252                      {vlc_meta_TrackNumber, "PART_NUMBER",   0},
253                      {vlc_meta_Description, "DESCRIPTION",   0},
254                      {vlc_meta_Description, "COMMENT",       0},
255                      {vlc_meta_Rating,      "RATING",        0},
256                      {vlc_meta_Date,        "DATE_RELEASED", 0},
257                      {vlc_meta_Date,        "DATE_RELEASE",  0},
258                      {vlc_meta_Date,        "DATE_RECORDED", 0},
259                      {vlc_meta_URL,         "URL",           0},
260                      {vlc_meta_Publisher,   "PUBLISHER",     0},
261                      {vlc_meta_EncodedBy,   "ENCODED_BY",    0},
262                      {vlc_meta_TrackTotal,  "TOTAL_PARTS",   0},
263                      {vlc_meta_Title,       NULL,            0},
264 };
265
266 SimpleTag * matroska_segment_c::ParseSimpleTags( KaxTagSimple *tag, int target_type )
267 {
268     EbmlElement *el;
269     EbmlParser *ep = new EbmlParser( &es, tag, &sys.demuxer );
270     SimpleTag * p_simple = new SimpleTag;
271
272     if( !p_simple )
273     {
274         msg_Err( &sys.demuxer, "Couldn't allocate memory for Simple Tag... ignoring it");
275         return NULL;
276     }
277
278     if( !sys.meta )
279         sys.meta = vlc_meta_New();
280
281     msg_Dbg( &sys.demuxer, "|   + Simple Tag ");
282     try
283     {
284         while( ( el = ep->Get() ) != NULL )
285         {
286             if( unlikely( el->GetSize() >= SIZE_MAX ) )
287             {
288                 msg_Err( &sys.demuxer, "Error %s too big ignoring the tag", typeid(*el).name() );
289                 delete ep;
290                 delete p_simple;
291                 return NULL;
292             }
293             if( MKV_IS_ID( el, KaxTagName ) )
294             {
295                 KaxTagName &key = *(KaxTagName*)el;
296                 key.ReadData( es.I_O(), SCOPE_ALL_DATA );
297                 p_simple->psz_tag_name = strdup( UTFstring( key ).GetUTF8().c_str() );
298             }
299             else if( MKV_IS_ID( el, KaxTagString ) )
300             {
301                 KaxTagString &value = *(KaxTagString*)el;
302                 value.ReadData( es.I_O(), SCOPE_ALL_DATA );
303                 p_simple->p_value = strdup( UTFstring( value ).GetUTF8().c_str() );
304             }
305             else if(  MKV_IS_ID( el, KaxTagLangue ) )
306             {
307                 KaxTagLangue &language = *(KaxTagLangue*) el;
308                 language.ReadData( es.I_O(), SCOPE_ALL_DATA );
309                 p_simple->psz_lang = strdup( string( language ).c_str());
310             }
311             else if(  MKV_IS_ID( el, KaxTagDefault ) )
312             {
313                 KaxTagDefault & dft = *(KaxTagDefault*) el;
314                 dft.ReadData( es.I_O(), SCOPE_ALL_DATA );
315                 p_simple->b_default = (bool) uint8( dft );
316             }
317             /*Tags can be nested*/
318             else if( MKV_IS_ID( el, KaxTagSimple) )
319             {
320                 SimpleTag * p_st = ParseSimpleTags( (KaxTagSimple*)el, target_type );
321                 if( p_st )
322                     p_simple->sub_tags.push_back( p_st );
323             }
324             /*TODO Handle binary tags*/
325         }
326     }
327     catch(...)
328     {
329         msg_Err( &sys.demuxer, "Error while reading Tag ");
330         delete ep;
331         delete p_simple;
332         return NULL;
333     }
334     delete ep;
335
336     if( !p_simple->psz_tag_name || !p_simple->p_value )
337     {
338         msg_Warn( &sys.demuxer, "Invalid MKV SimpleTag found.");
339         delete p_simple;
340         return NULL;
341     }
342
343     for( int i = 0; metadata_map[i].key; i++ )
344     {
345         if( !strcmp( p_simple->psz_tag_name, metadata_map[i].key ) &&
346             (metadata_map[i].target_type == 0 || target_type == metadata_map[i].target_type ) )
347         {
348             vlc_meta_Set( sys.meta, metadata_map[i].type, p_simple->p_value );
349             msg_Dbg( &sys.demuxer, "|   |   + Meta %s: %s", p_simple->psz_tag_name, p_simple->p_value);
350             goto done;
351         }
352     }
353     msg_Dbg( &sys.demuxer, "|   |   + Meta %s: %s", p_simple->psz_tag_name, p_simple->p_value);
354     vlc_meta_AddExtra( sys.meta, p_simple->psz_tag_name, p_simple->p_value);
355 done:
356     return p_simple;
357 }
358
359 #define PARSE_TAG( type ) \
360     do { \
361         msg_Dbg( &sys.demuxer, "|   + " type ); \
362         ep->Down();                             \
363         while( ( el = ep->Get() ) != NULL )     \
364         {                                       \
365             msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid( *el ).name() ); \
366         }                                      \
367         ep->Up(); } while( 0 )
368
369
370 void matroska_segment_c::LoadTags( KaxTags *tags )
371 {
372     /* Master elements */
373     EbmlParser *ep = new EbmlParser( &es, tags, &sys.demuxer );
374     EbmlElement *el;
375
376     while( ( el = ep->Get() ) != NULL )
377     {
378         if( MKV_IS_ID( el, KaxTag ) )
379         {
380             Tag * p_tag = new Tag;
381             if(!p_tag)
382             {
383                 msg_Err( &sys.demuxer,"Couldn't allocate memory for tag... ignoring it");
384                 continue;
385             }
386             msg_Dbg( &sys.demuxer, "+ Tag" );
387             ep->Down();
388             int target_type = 50;
389             while( ( el = ep->Get() ) != NULL )
390             {
391                 if( MKV_IS_ID( el, KaxTagTargets ) )
392                 {
393                     msg_Dbg( &sys.demuxer, "|   + Targets" );
394                     ep->Down();
395                     while( ( el = ep->Get() ) != NULL )
396                     {
397                         try
398                         {
399                             if( unlikely( el->GetSize() >= SIZE_MAX ) )
400                             {
401                                 msg_Err( &sys.demuxer, "Invalid size while reading tag");
402                                 break;
403                             }
404                             if( MKV_IS_ID( el, KaxTagTargetTypeValue ) )
405                             {
406                                 KaxTagTargetTypeValue &value = *(KaxTagTargetTypeValue*)el;
407                                 value.ReadData( es.I_O() );
408
409                                 msg_Dbg( &sys.demuxer, "|   |   + TargetTypeValue: %u", uint32(value));
410                                 target_type = uint32(value);
411                             }
412                             if( MKV_IS_ID( el, KaxTagTrackUID ) )
413                             {
414                                 p_tag->i_tag_type = TRACK_UID;
415                                 KaxTagTrackUID &uid = *(KaxTagTrackUID*) el;
416                                 uid.ReadData( es.I_O() );
417                                 p_tag->i_uid = uint64( uid );
418                                 msg_Dbg( &sys.demuxer, "|   |   + TrackUID: %"PRIu64, p_tag->i_uid);
419
420                             }
421                             if( MKV_IS_ID( el, KaxTagEditionUID ) )
422                             {
423                                 p_tag->i_tag_type = EDITION_UID;
424                                 KaxTagEditionUID &uid = *(KaxTagEditionUID*) el;
425                                 uid.ReadData( es.I_O() );
426                                 p_tag->i_uid = uint64( uid );
427                                 msg_Dbg( &sys.demuxer, "|   |   + EditionUID: %"PRIu64, p_tag->i_uid);
428                             }
429                             if( MKV_IS_ID( el, KaxTagChapterUID ) )
430                             {
431                                 p_tag->i_tag_type = CHAPTER_UID;
432                                 KaxTagChapterUID &uid = *(KaxTagChapterUID*) el;
433                                 uid.ReadData( es.I_O() );
434                                 p_tag->i_uid = uint64( uid );
435                                 msg_Dbg( &sys.demuxer, "|   |   + ChapterUID: %"PRIu64, p_tag->i_uid);
436                             }
437                             if( MKV_IS_ID( el, KaxTagAttachmentUID ) )
438                             {
439                                 p_tag->i_tag_type = ATTACHMENT_UID;
440                                 KaxTagAttachmentUID &uid = *(KaxTagAttachmentUID*) el;
441                                 uid.ReadData( es.I_O() );
442                                 p_tag->i_uid = uint64( uid );
443                                 msg_Dbg( &sys.demuxer, "|   |   + AttachmentUID: %"PRIu64, p_tag->i_uid);
444                             }
445                         }
446                         catch(...)
447                         {
448                             msg_Err( &sys.demuxer, "Error while reading tag");
449                             break;
450                         }
451                     }
452                     ep->Up();
453                 }
454                 else if( MKV_IS_ID( el, KaxTagSimple ) )
455                 {
456                     SimpleTag * p_simple =
457                         ParseSimpleTags( static_cast<KaxTagSimple*>( el ),
458                                          target_type );
459                     if( p_simple )
460                         p_tag->simple_tags.push_back( p_simple );
461                 }
462 #if 0 // not valid anymore
463                 else if( MKV_IS_ID( el, KaxTagGeneral ) )
464                     PARSE_TAG( "General" );
465                 else if( MKV_IS_ID( el, KaxTagGenres ) )
466                     PARSE_TAG( "Genres" );
467                 else if( MKV_IS_ID( el, KaxTagAudioSpecific ) )
468                     PARSE_TAG( "Audio Specific" );
469                 else if( MKV_IS_ID( el, KaxTagImageSpecific ) )
470                     PARSE_TAG( "Images Specific" );
471                 else if( MKV_IS_ID( el, KaxTagMultiComment ) )
472                 {
473                     msg_Dbg( &sys.demuxer, "|   + Multi Comment" );
474                 }
475                 else if( MKV_IS_ID( el, KaxTagMultiCommercial ) )
476                 {
477                     msg_Dbg( &sys.demuxer, "|   + Multi Commercial" );
478                 }
479                 else if( MKV_IS_ID( el, KaxTagMultiDate ) )
480                 {
481                     msg_Dbg( &sys.demuxer, "|   + Multi Date" );
482                 }
483                 else if( MKV_IS_ID( el, KaxTagMultiEntity ) )
484                 {
485                     msg_Dbg( &sys.demuxer, "|   + Multi Entity" );
486                 }
487                 else if( MKV_IS_ID( el, KaxTagMultiIdentifier ) )
488                 {
489                     msg_Dbg( &sys.demuxer, "|   + Multi Identifier" );
490                 }
491                 else if( MKV_IS_ID( el, KaxTagMultiLegal ) )
492                 {
493                     msg_Dbg( &sys.demuxer, "|   + Multi Legal" );
494                 }
495                 else if( MKV_IS_ID( el, KaxTagMultiTitle ) )
496                 {
497                     msg_Dbg( &sys.demuxer, "|   + Multi Title" );
498                 }
499 #endif
500                 else
501                 {
502                     msg_Dbg( &sys.demuxer, "|   + LoadTag Unknown (%s)", typeid( *el ).name() );
503                 }
504             }
505             ep->Up();
506             this->tags.push_back(p_tag);
507         }
508         else
509         {
510             msg_Dbg( &sys.demuxer, "+ Unknown (%s)", typeid( *el ).name() );
511         }
512     }
513     delete ep;
514
515     msg_Dbg( &sys.demuxer, "loading tags done." );
516 }
517 #undef PARSE_TAG
518
519 /*****************************************************************************
520  * InformationCreate:
521  *****************************************************************************/
522 void matroska_segment_c::InformationCreate( )
523 {
524     if( !sys.meta )
525         sys.meta = vlc_meta_New();
526
527     if( psz_title )
528     {
529         vlc_meta_SetTitle( sys.meta, psz_title );
530     }
531 #if 0
532     if( psz_date_utc )
533     {
534         vlc_meta_SetDate( sys.meta, psz_date_utc );
535     }
536
537     if( psz_segment_filename )
538     {
539         fprintf( stderr, "***** WARNING: Unhandled meta - Use custom\n" );
540     }
541     if( psz_muxing_application )
542     {
543         fprintf( stderr, "***** WARNING: Unhandled meta - Use custom\n" );
544     }
545     if( psz_writing_application )
546     {
547         fprintf( stderr, "***** WARNING: Unhandled meta - Use custom\n" );
548     }
549
550     for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
551     {
552 //        mkv_track_t *tk = tracks[i_track];
553 //        vlc_meta_t *mtk = vlc_meta_New();
554         fprintf( stderr, "***** WARNING: Unhandled child meta\n");
555     }
556 #endif
557 #if 0
558     if( i_tags_position >= 0 )
559     {
560         bool b_seekable;
561
562         stream_Control( sys.demuxer.s, STREAM_CAN_FASTSEEK, &b_seekable );
563         if( b_seekable )
564         {
565             LoadTags( );
566         }
567     }
568 #endif
569 }
570
571
572 /*****************************************************************************
573  * Misc
574  *****************************************************************************/
575
576 void matroska_segment_c::IndexAppendCluster( KaxCluster *cluster )
577 {
578 #define idx p_indexes[i_index]
579     idx.i_track       = -1;
580     idx.i_block_number= -1;
581     idx.i_position    = cluster->GetElementPosition();
582     idx.i_time        = cluster->GlobalTimecode()/ (mtime_t) 1000;
583     idx.b_key         = true;
584
585     i_index++;
586     if( i_index >= i_index_max )
587     {
588         i_index_max += 1024;
589         p_indexes = (mkv_index_t*)xrealloc( p_indexes,
590                                         sizeof( mkv_index_t ) * i_index_max );
591     }
592 #undef idx
593 }
594
595 bool matroska_segment_c::PreloadFamily( const matroska_segment_c & of_segment )
596 {
597     if ( b_preloaded )
598         return false;
599
600     for (size_t i=0; i<families.size(); i++)
601     {
602         for (size_t j=0; j<of_segment.families.size(); j++)
603         {
604             if ( *(families[i]) == *(of_segment.families[j]) )
605                 return Preload( );
606         }
607     }
608
609     return false;
610 }
611
612 bool matroska_segment_c::CompareSegmentUIDs( const matroska_segment_c * p_item_a, const matroska_segment_c * p_item_b )
613 {
614     EbmlBinary *p_tmp;
615
616     if ( p_item_a == NULL || p_item_b == NULL )
617         return false;
618
619     p_tmp = (EbmlBinary *)p_item_a->p_segment_uid;
620     if ( p_item_b->p_prev_segment_uid != NULL
621           && *p_tmp == *p_item_b->p_prev_segment_uid )
622         return true;
623
624     p_tmp = (EbmlBinary *)p_item_a->p_next_segment_uid;
625     if ( !p_tmp )
626         return false;
627
628     if ( p_item_b->p_segment_uid != NULL
629           && *p_tmp == *p_item_b->p_segment_uid )
630         return true;
631
632     if ( p_item_b->p_prev_segment_uid != NULL
633           && *p_tmp == *p_item_b->p_prev_segment_uid )
634         return true;
635
636     return false;
637 }
638
639 bool matroska_segment_c::Preload( )
640 {
641     if ( b_preloaded )
642         return false;
643
644     EbmlElement *el = NULL;
645
646     ep->Reset( &sys.demuxer );
647
648     while( ( el = ep->Get() ) != NULL )
649     {
650         if( MKV_IS_ID( el, KaxSeekHead ) )
651         {
652             /* Multiple allowed */
653             /* We bail at 10, to prevent possible recursion */
654             msg_Dbg(  &sys.demuxer, "|   + Seek head" );
655             if( i_seekhead_count < 10 )
656             {
657                 i_seekhead_position = (int64_t) es.I_O().getFilePointer();
658                 ParseSeekHead( static_cast<KaxSeekHead*>( el ) );
659             }
660         }
661         else if( MKV_IS_ID( el, KaxInfo ) )
662         {
663             /* Multiple allowed, mandatory */
664             msg_Dbg(  &sys.demuxer, "|   + Information" );
665             if( i_info_position < 0 ) // FIXME
666                 ParseInfo( static_cast<KaxInfo*>( el ) );
667             i_info_position = (int64_t) es.I_O().getFilePointer();
668         }
669         else if( MKV_IS_ID( el, KaxTracks ) )
670         {
671             /* Multiple allowed */
672             msg_Dbg(  &sys.demuxer, "|   + Tracks" );
673             if( i_tracks_position < 0 ) // FIXME
674                 ParseTracks( static_cast<KaxTracks*>( el ) );
675             if ( tracks.size() == 0 )
676             {
677                 msg_Err( &sys.demuxer, "No tracks supported" );
678                 return false;
679             }
680             i_tracks_position = (int64_t) es.I_O().getFilePointer();
681         }
682         else if( MKV_IS_ID( el, KaxCues ) )
683         {
684             msg_Dbg(  &sys.demuxer, "|   + Cues" );
685             if( i_cues_position < 0 )
686                 LoadCues( static_cast<KaxCues*>( el ) );
687             i_cues_position = (int64_t) es.I_O().getFilePointer();
688         }
689         else if( MKV_IS_ID( el, KaxCluster ) )
690         {
691             msg_Dbg( &sys.demuxer, "|   + Cluster" );
692
693             cluster = (KaxCluster*)el;
694
695             i_cluster_pos = i_start_pos = cluster->GetElementPosition();
696             ParseCluster( );
697
698             ep->Down();
699             /* stop pre-parsing the stream */
700             break;
701         }
702         else if( MKV_IS_ID( el, KaxAttachments ) )
703         {
704             msg_Dbg( &sys.demuxer, "|   + Attachments" );
705             if( i_attachments_position < 0 )
706                 ParseAttachments( static_cast<KaxAttachments*>( el ) );
707             i_attachments_position = (int64_t) es.I_O().getFilePointer();
708         }
709         else if( MKV_IS_ID( el, KaxChapters ) )
710         {
711             msg_Dbg( &sys.demuxer, "|   + Chapters" );
712             if( i_chapters_position < 0 )
713                 ParseChapters( static_cast<KaxChapters*>( el ) );
714             i_chapters_position = (int64_t) es.I_O().getFilePointer();
715         }
716         else if( MKV_IS_ID( el, KaxTag ) )
717         {
718             msg_Dbg( &sys.demuxer, "|   + Tags" );
719             /*FIXME if( i_tags_position < 0)
720                 LoadTags( static_cast<KaxTags*>( el ) );*/
721             i_tags_position = (int64_t) es.I_O().getFilePointer();
722         }
723         else if( MKV_IS_ID( el, EbmlVoid ) )
724             msg_Dbg( &sys.demuxer, "|   + Void" );
725         else
726             msg_Dbg( &sys.demuxer, "|   + Preload Unknown (%s)", typeid(*el).name() );
727     }
728
729     ComputeTrackPriority();
730
731     b_preloaded = true;
732
733     return true;
734 }
735
736 /* Here we try to load elements that were found in Seek Heads, but not yet parsed */
737 bool matroska_segment_c::LoadSeekHeadItem( const EbmlCallbacks & ClassInfos, int64_t i_element_position )
738 {
739     int64_t     i_sav_position = (int64_t)es.I_O().getFilePointer();
740     EbmlElement *el;
741
742     es.I_O().setFilePointer( i_element_position, seek_beginning );
743     el = es.FindNextID( ClassInfos, 0xFFFFFFFFL);
744
745     if( el == NULL )
746     {
747         msg_Err( &sys.demuxer, "cannot load some cues/chapters/tags etc. (broken seekhead or file)" );
748         es.I_O().setFilePointer( i_sav_position, seek_beginning );
749         return false;
750     }
751
752     if( MKV_IS_ID( el, KaxSeekHead ) )
753     {
754         /* Multiple allowed */
755         msg_Dbg( &sys.demuxer, "|   + Seek head" );
756         if( i_seekhead_count < 10 )
757         {
758             i_seekhead_position = i_element_position;
759             ParseSeekHead( static_cast<KaxSeekHead*>( el ) );
760         }
761     }
762     else if( MKV_IS_ID( el, KaxInfo ) ) // FIXME
763     {
764         /* Multiple allowed, mandatory */
765         msg_Dbg( &sys.demuxer, "|   + Information" );
766         if( i_info_position < 0 )
767             ParseInfo( static_cast<KaxInfo*>( el ) );
768         i_info_position = i_element_position;
769     }
770     else if( MKV_IS_ID( el, KaxTracks ) ) // FIXME
771     {
772         /* Multiple allowed */
773         msg_Dbg( &sys.demuxer, "|   + Tracks" );
774         if( i_tracks_position < 0 )
775             ParseTracks( static_cast<KaxTracks*>( el ) );
776         if ( tracks.size() == 0 )
777         {
778             msg_Err( &sys.demuxer, "No tracks supported" );
779             delete el;
780             es.I_O().setFilePointer( i_sav_position, seek_beginning );
781             return false;
782         }
783         i_tracks_position = i_element_position;
784     }
785     else if( MKV_IS_ID( el, KaxCues ) )
786     {
787         msg_Dbg( &sys.demuxer, "|   + Cues" );
788         if( i_cues_position < 0 )
789             LoadCues( static_cast<KaxCues*>( el ) );
790         i_cues_position = i_element_position;
791     }
792     else if( MKV_IS_ID( el, KaxAttachments ) )
793     {
794         msg_Dbg( &sys.demuxer, "|   + Attachments" );
795         if( i_attachments_position < 0 )
796             ParseAttachments( static_cast<KaxAttachments*>( el ) );
797         i_attachments_position = i_element_position;
798     }
799     else if( MKV_IS_ID( el, KaxChapters ) )
800     {
801         msg_Dbg( &sys.demuxer, "|   + Chapters" );
802         if( i_chapters_position < 0 )
803             ParseChapters( static_cast<KaxChapters*>( el ) );
804         i_chapters_position = i_element_position;
805     }
806     else if( MKV_IS_ID( el, KaxTags ) )
807     {
808         msg_Dbg( &sys.demuxer, "|   + Tags" );
809         if( i_tags_position < 0 )
810             LoadTags( static_cast<KaxTags*>( el ) );
811         i_tags_position = i_element_position;
812     }
813     else
814     {
815         msg_Dbg( &sys.demuxer, "|   + LoadSeekHeadItem Unknown (%s)", typeid(*el).name() );
816     }
817     delete el;
818
819     es.I_O().setFilePointer( i_sav_position, seek_beginning );
820     return true;
821 }
822
823 struct spoint
824 {
825     spoint(unsigned int tk, mtime_t date, int64_t pos, int64_t cpos):
826         i_track(tk),i_date(date), i_seek_pos(pos),
827         i_cluster_pos(cpos), p_next(NULL){}
828     unsigned int     i_track;
829     mtime_t i_date;
830     int64_t i_seek_pos;
831     int64_t i_cluster_pos;
832     spoint * p_next;
833 };
834
835 void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_global_position )
836 {
837     KaxBlock    *block;
838     KaxSimpleBlock *simpleblock;
839     int64_t     i_block_duration;
840     size_t      i_track;
841     int64_t     i_seek_position = i_start_pos;
842     int64_t     i_seek_time = i_start_time;
843     mtime_t     i_pts = 0;
844     spoint *p_first = NULL;
845     spoint *p_last = NULL;
846     int i_cat;
847     bool b_has_key = false;
848
849     for( size_t i = 0; i < tracks.size(); i++)
850         tracks[i]->i_last_dts = VLC_TS_INVALID;
851
852     if( i_global_position >= 0 )
853     {
854         /* Special case for seeking in files with no cues */
855         EbmlElement *el = NULL;
856
857         /* Start from the last known index instead of the beginning eachtime */
858         if( i_index == 0)
859             es.I_O().setFilePointer( i_start_pos, seek_beginning );
860         else
861             es.I_O().setFilePointer( p_indexes[ i_index - 1 ].i_position,
862                                      seek_beginning );
863         delete ep;
864         ep = new EbmlParser( &es, segment, &sys.demuxer );
865         cluster = NULL;
866
867         while( ( el = ep->Get() ) != NULL )
868         {
869             if( MKV_IS_ID( el, KaxCluster ) )
870             {
871                 cluster = (KaxCluster *)el;
872                 i_cluster_pos = cluster->GetElementPosition();
873                 if( i_index == 0 ||
874                     ( i_index > 0 &&
875                       p_indexes[i_index - 1].i_position < (int64_t)cluster->GetElementPosition() ) )
876                 {
877                     ParseCluster(false);
878                     IndexAppendCluster( cluster );
879                 }
880                 if( es.I_O().getFilePointer() >= (unsigned) i_global_position )
881                     break;
882             }
883         }
884     }
885
886     /* Don't try complex seek if we seek to 0 */
887     if( i_date == 0 && i_time_offset == 0 )
888     {
889         es_out_Control( sys.demuxer.out, ES_OUT_SET_PCR, VLC_TS_0 );
890         es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME,
891                         INT64_C(0) );
892         es.I_O().setFilePointer( i_start_pos );
893
894         delete ep;
895         ep = new EbmlParser( &es, segment, &sys.demuxer );
896         cluster = NULL;
897         sys.i_start_pts = 0;
898         sys.i_pts = 0;
899         sys.i_pcr = 0;
900         return;
901     }
902
903     int i_idx = 0;
904     if ( i_index > 0 )
905     {
906
907         for( ; i_idx < i_index; i_idx++ )
908             if( p_indexes[i_idx].i_time + i_time_offset > i_date )
909                 break;
910
911         if( i_idx > 0 )
912             i_idx--;
913
914         i_seek_position = p_indexes[i_idx].i_position;
915         i_seek_time = p_indexes[i_idx].i_time;
916     }
917
918     msg_Dbg( &sys.demuxer, "seek got %"PRId64" (%d%%)",
919                 i_seek_time, (int)( 100 * i_seek_position / stream_Size( sys.demuxer.s ) ) );
920
921     es.I_O().setFilePointer( i_seek_position, seek_beginning );
922
923     delete ep;
924     ep = new EbmlParser( &es, segment, &sys.demuxer );
925     cluster = NULL;
926
927     sys.i_start_pts = i_date;
928
929     /* now parse until key frame */
930     const int es_types[3] = { VIDEO_ES, AUDIO_ES, SPU_ES };
931     i_cat = es_types[0];
932     mtime_t i_seek_preroll = 0;
933     for( int i = 0; i < 2; i_cat = es_types[++i] )
934     {
935         for( i_track = 0; i_track < tracks.size(); i_track++ )
936         {
937             if( tracks[i_track]->i_seek_preroll )
938             {
939                 bool b_enabled;
940                 if( es_out_Control( sys.demuxer.out,
941                                     ES_OUT_GET_ES_STATE,
942                                     tracks[i_track]->p_es,
943                                     &b_enabled ) == VLC_SUCCESS &&
944                     b_enabled )
945                     i_seek_preroll = __MAX( i_seek_preroll,
946                                             tracks[i_track]->i_seek_preroll );
947             }
948             if( tracks[i_track]->fmt.i_cat == i_cat )
949             {
950                 spoint * seekpoint = new spoint(i_track, i_seek_time, i_seek_position, i_seek_position);
951                 if( unlikely( !seekpoint ) )
952                 {
953                     for( spoint * sp = p_first; sp; )
954                     {
955                         spoint * tmp = sp;
956                         sp = sp->p_next;
957                         delete tmp;
958                     }
959                     return;
960                 }
961                 if( unlikely( !p_first ) )
962                 {
963                     p_first = seekpoint;
964                     p_last = seekpoint;
965                 }
966                 else
967                 {
968                     p_last->p_next = seekpoint;
969                     p_last = seekpoint;
970                 }
971             }
972         }
973         if( likely( p_first ) )
974             break;
975     }
976     /*Neither video nor audio track... no seek further*/
977     if( unlikely( !p_first ) )
978     {
979         es_out_Control( sys.demuxer.out, ES_OUT_SET_PCR, i_date );
980         es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_date );
981         return;
982     }
983     i_date -= i_seek_preroll;
984     for(;;)
985     {
986         do
987         {
988             bool b_key_picture;
989             bool b_discardable_picture;
990             if( BlockGet( block, simpleblock, &b_key_picture, &b_discardable_picture, &i_block_duration ) )
991             {
992                 msg_Warn( &sys.demuxer, "cannot get block EOF?" );
993                 return;
994             }
995
996             /* check if block's track is in our list */
997             for( i_track = 0; i_track < tracks.size(); i_track++ )
998             {
999                 if( (simpleblock && tracks[i_track]->i_number == simpleblock->TrackNum()) ||
1000                     (block && tracks[i_track]->i_number == block->TrackNum()) )
1001                     break;
1002             }
1003
1004             if( simpleblock )
1005                 i_pts = sys.i_chapter_time + simpleblock->GlobalTimecode() / (mtime_t) 1000;
1006             else
1007                 i_pts = sys.i_chapter_time + block->GlobalTimecode() / (mtime_t) 1000;
1008             if( i_track < tracks.size() )
1009             {
1010                 if( tracks[i_track]->fmt.i_cat == i_cat && b_key_picture )
1011                 {
1012                     /* get the seekpoint */
1013                     spoint * sp;
1014                     for( sp =  p_first; sp; sp = sp->p_next )
1015                         if( sp->i_track == i_track )
1016                             break;
1017
1018                     sp->i_date = i_pts;
1019                     if( simpleblock )
1020                         sp->i_seek_pos = simpleblock->GetElementPosition();
1021                     else
1022                         sp->i_seek_pos = i_block_pos;
1023                     sp->i_cluster_pos = i_cluster_pos;
1024                     b_has_key = true;
1025                 }
1026             }
1027
1028             delete block;
1029         } while( i_pts < i_date );
1030         if( b_has_key || !i_idx )
1031             break;
1032
1033         /* No key picture was found in the cluster seek to previous seekpoint */
1034         i_date = i_time_offset + p_indexes[i_idx].i_time;
1035         i_idx--;
1036         i_pts = 0;
1037         es.I_O().setFilePointer( p_indexes[i_idx].i_position );
1038         delete ep;
1039         ep = new EbmlParser( &es, segment, &sys.demuxer );
1040         cluster = NULL;
1041     }
1042
1043     /* rewind to the last I img */
1044     spoint * p_min;
1045     for( p_min  = p_first, p_last = p_first; p_last; p_last = p_last->p_next )
1046         if( p_last->i_date < p_min->i_date )
1047             p_min = p_last;
1048
1049     sys.i_pcr = sys.i_pts = p_min->i_date;
1050     es_out_Control( sys.demuxer.out, ES_OUT_SET_PCR, VLC_TS_0 + sys.i_pcr );
1051     es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_date );
1052     cluster = (KaxCluster *) ep->UnGet( p_min->i_seek_pos, p_min->i_cluster_pos );
1053
1054     /* hack use BlockGet to get the cluster then goto the wanted block */
1055     if ( !cluster )
1056     {
1057         bool b_key_picture;
1058         bool b_discardable_picture;
1059         BlockGet( block, simpleblock, &b_key_picture, &b_discardable_picture, &i_block_duration );
1060         delete block;
1061         cluster = (KaxCluster *) ep->UnGet( p_min->i_seek_pos, p_min->i_cluster_pos );
1062     }
1063
1064     while( p_first )
1065     {
1066         p_min = p_first;
1067         p_first = p_first->p_next;
1068         delete p_min;
1069     }
1070 }
1071
1072 int matroska_segment_c::BlockFindTrackIndex( size_t *pi_track,
1073                                              const KaxBlock *p_block, const KaxSimpleBlock *p_simpleblock )
1074 {
1075     size_t i_track;
1076     for( i_track = 0; i_track < tracks.size(); i_track++ )
1077     {
1078         const mkv_track_t *tk = tracks[i_track];
1079
1080         if( ( p_block != NULL && tk->i_number == p_block->TrackNum() ) ||
1081             ( p_simpleblock != NULL && tk->i_number == p_simpleblock->TrackNum() ) )
1082         {
1083             break;
1084         }
1085     }
1086
1087     if( i_track >= tracks.size() )
1088         return VLC_EGENERIC;
1089
1090     if( pi_track )
1091         *pi_track = i_track;
1092     return VLC_SUCCESS;
1093 }
1094
1095 void matroska_segment_c::ComputeTrackPriority()
1096 {
1097     bool b_has_default_video = false;
1098     bool b_has_default_audio = false;
1099     /* check for default */
1100     for(size_t i_track = 0; i_track < tracks.size(); i_track++)
1101     {
1102         mkv_track_t *p_tk = tracks[i_track];
1103         es_format_t *p_fmt = &p_tk->fmt;
1104         if( p_fmt->i_cat == VIDEO_ES )
1105             b_has_default_video |=
1106                 p_tk->b_enabled && ( p_tk->b_default || p_tk->b_forced );
1107         else if( p_fmt->i_cat == AUDIO_ES )
1108             b_has_default_audio |=
1109                 p_tk->b_enabled && ( p_tk->b_default || p_tk->b_forced );
1110     }
1111
1112     for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
1113     {
1114         mkv_track_t *p_tk = tracks[i_track];
1115         es_format_t *p_fmt = &p_tk->fmt;
1116
1117         if( unlikely( p_fmt->i_cat == UNKNOWN_ES || !p_tk->psz_codec ) )
1118         {
1119             msg_Warn( &sys.demuxer, "invalid track[%d, n=%d]", (int)i_track, p_tk->i_number );
1120             p_tk->p_es = NULL;
1121             continue;
1122         }
1123         else if( unlikely( !b_has_default_video && p_fmt->i_cat == VIDEO_ES ) )
1124         {
1125             p_tk->b_default = true;
1126             b_has_default_video = true;
1127         }
1128         else if( unlikely( !b_has_default_audio &&  p_fmt->i_cat == AUDIO_ES ) )
1129         {
1130             p_tk->b_default = true;
1131             b_has_default_audio = true;
1132         }
1133         if( unlikely( !p_tk->b_enabled ) )
1134             p_tk->fmt.i_priority = ES_PRIORITY_NOT_SELECTABLE;
1135         else if( p_tk->b_forced )
1136             p_tk->fmt.i_priority = ES_PRIORITY_SELECTABLE_MIN + 2;
1137         else if( p_tk->b_default )
1138             p_tk->fmt.i_priority = ES_PRIORITY_SELECTABLE_MIN + 1;
1139         else
1140             p_tk->fmt.i_priority = ES_PRIORITY_SELECTABLE_MIN;
1141
1142         /* Avoid multivideo tracks when unnecessary */
1143         if( p_tk->fmt.i_cat == VIDEO_ES )
1144             p_tk->fmt.i_priority--;
1145     } 
1146 }
1147
1148 bool matroska_segment_c::Select( mtime_t i_start_time )
1149 {
1150     /* add all es */
1151     msg_Dbg( &sys.demuxer, "found %d es", (int)tracks.size() );
1152
1153     for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
1154     {
1155         mkv_track_t *p_tk = tracks[i_track];
1156         es_format_t *p_fmt = &p_tk->fmt;
1157
1158         if( unlikely( p_fmt->i_cat == UNKNOWN_ES || !p_tk->psz_codec ) )
1159         {
1160             msg_Warn( &sys.demuxer, "invalid track[%d, n=%d]", (int)i_track, p_tk->i_number );
1161             p_tk->p_es = NULL;
1162             continue;
1163         }
1164
1165         if( !p_tk->p_es )
1166             p_tk->p_es = es_out_Add( sys.demuxer.out, &p_tk->fmt );
1167
1168         /* Turn on a subtitles track if it has been flagged as default -
1169          * but only do this if no subtitles track has already been engaged,
1170          * either by an earlier 'default track' (??) or by default
1171          * language choice behaviour.
1172          */
1173         if( p_tk->b_default || p_tk->b_forced )
1174         {
1175             es_out_Control( sys.demuxer.out,
1176                             ES_OUT_SET_ES_DEFAULT,
1177                             p_tk->p_es );
1178         }
1179     }
1180     es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_start_time );
1181
1182     sys.i_start_pts = i_start_time;
1183     // reset the stream reading to the first cluster of the segment used
1184     es.I_O().setFilePointer( i_start_pos );
1185
1186     delete ep;
1187     ep = new EbmlParser( &es, segment, &sys.demuxer );
1188
1189     return true;
1190 }
1191
1192 void matroska_segment_c::UnSelect( )
1193 {
1194     sys.p_ev->ResetPci();
1195     for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
1196     {
1197         if ( tracks[i_track]->p_es != NULL )
1198         {
1199 //            es_format_Clean( &tracks[i_track]->fmt );
1200             es_out_Del( sys.demuxer.out, tracks[i_track]->p_es );
1201             tracks[i_track]->p_es = NULL;
1202         }
1203     }
1204     delete ep;
1205     ep = NULL;
1206 }
1207
1208 int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_simpleblock, bool *pb_key_picture, bool *pb_discardable_picture, int64_t *pi_duration )
1209 {
1210     pp_simpleblock = NULL;
1211     pp_block = NULL;
1212
1213     *pb_key_picture         = true;
1214     *pb_discardable_picture = false;
1215     size_t i_tk;
1216     *pi_duration = 0;
1217
1218     for( ;; )
1219     {
1220         EbmlElement *el = NULL;
1221         int         i_level;
1222
1223         if ( ep == NULL )
1224             return VLC_EGENERIC;
1225
1226         if( pp_simpleblock != NULL || ((el = ep->Get()) == NULL && pp_block != NULL) )
1227         {
1228             /* Check blocks validity to protect againts broken files */
1229             if( BlockFindTrackIndex( &i_tk, pp_block , pp_simpleblock ) )
1230             {
1231                 ep->Unkeep();
1232                 pp_simpleblock = NULL;
1233                 pp_block = NULL;
1234                 continue;
1235             }
1236             if( pp_simpleblock != NULL )
1237             {
1238                 *pb_key_picture         = pp_simpleblock->IsKeyframe();
1239                 *pb_discardable_picture = pp_simpleblock->IsDiscardable();
1240             }
1241             /* We have block group let's check if the picture is a keyframe */
1242             else if( *pb_key_picture )
1243             {
1244                 switch(tracks[i_tk]->fmt.i_codec)
1245                 {
1246                     case VLC_CODEC_THEORA:
1247                         {
1248                             DataBuffer *p_data = &pp_block->GetBuffer(0);
1249                             size_t sz = p_data->Size();
1250                             const uint8_t * p_buff = p_data->Buffer();
1251                             /* if the second bit of a Theora frame is 1 
1252                                it's not a keyframe */
1253                             if( sz && p_buff )
1254                             {
1255                                 if( p_buff[0] & 0x40 )
1256                                     *pb_key_picture = false;
1257                             }
1258                             else
1259                                 *pb_key_picture = false;
1260                             break;
1261                         }
1262                 }
1263             }
1264
1265             /* update the index */
1266 #define idx p_indexes[i_index - 1]
1267             if( i_index > 0 && idx.i_time == -1 )
1268             {
1269                 if ( pp_simpleblock != NULL )
1270                     idx.i_time        = pp_simpleblock->GlobalTimecode() / (mtime_t)1000;
1271                 else
1272                     idx.i_time        = (*pp_block).GlobalTimecode() / (mtime_t)1000;
1273                 idx.b_key         = *pb_key_picture;
1274             }
1275 #undef idx
1276             return VLC_SUCCESS;
1277         }
1278
1279         i_level = ep->GetLevel();
1280
1281         if( el == NULL )
1282         {
1283             if( i_level > 1 )
1284             {
1285                 ep->Up();
1286                 continue;
1287             }
1288             msg_Warn( &sys.demuxer, "EOF" );
1289             return VLC_EGENERIC;
1290         }
1291
1292         /* Verify that we are still inside our cluster
1293          * It can happens whith broken files and when seeking
1294          * without index */
1295         if( i_level > 1 )
1296         {
1297             if( cluster && !ep->IsTopPresent( cluster ) )
1298             {
1299                 msg_Warn( &sys.demuxer, "Unexpected escape from current cluster" );
1300                 cluster = NULL;
1301             }
1302             if( !cluster )
1303                 continue;
1304         }
1305
1306         /* do parsing */
1307         try
1308         {
1309             switch ( i_level )
1310             {
1311                 case 1:
1312                     if( MKV_IS_ID( el, KaxCluster ) )
1313                     {
1314                         cluster = (KaxCluster*)el;
1315                         i_cluster_pos = cluster->GetElementPosition();
1316
1317                         // reset silent tracks
1318                         for (size_t i=0; i<tracks.size(); i++)
1319                         {
1320                             tracks[i]->b_silent = false;
1321                         }
1322
1323                         ep->Down();
1324                     }
1325                     else if( MKV_IS_ID( el, KaxCues ) )
1326                     {
1327                         msg_Warn( &sys.demuxer, "find KaxCues FIXME" );
1328                         return VLC_EGENERIC;
1329                     }
1330                     else
1331                     {
1332                         msg_Dbg( &sys.demuxer, "unknown (%s)", typeid( el ).name() );
1333                     }
1334                     break;
1335                 case 2:
1336                     if( unlikely( el->GetSize() >= SIZE_MAX ) )
1337                     {
1338                         msg_Err( &sys.demuxer, "Error while reading %s... upping level", typeid(*el).name());
1339                         ep->Up();
1340                         break;
1341                     }
1342                     if( MKV_IS_ID( el, KaxClusterTimecode ) )
1343                     {
1344                         KaxClusterTimecode &ctc = *(KaxClusterTimecode*)el;
1345
1346                         ctc.ReadData( es.I_O(), SCOPE_ALL_DATA );
1347                         cluster->InitTimecode( uint64( ctc ), i_timescale );
1348
1349                         /* add it to the index */
1350                         if( i_index == 0 ||
1351                             ( i_index > 0 &&
1352                               p_indexes[i_index - 1].i_position < (int64_t)cluster->GetElementPosition() ) )
1353                             IndexAppendCluster( cluster );
1354                     }
1355                     else if( MKV_IS_ID( el, KaxClusterSilentTracks ) )
1356                     {
1357                         ep->Down();
1358                     }
1359                     else if( MKV_IS_ID( el, KaxBlockGroup ) )
1360                     {
1361                         i_block_pos = el->GetElementPosition();
1362                         ep->Down();
1363                     }
1364                     else if( MKV_IS_ID( el, KaxSimpleBlock ) )
1365                     {
1366                         pp_simpleblock = (KaxSimpleBlock*)el;
1367
1368                         pp_simpleblock->ReadData( es.I_O() );
1369                         pp_simpleblock->SetParent( *cluster );
1370                     }
1371                     break;
1372                 case 3:
1373                     if( unlikely( el->GetSize() >= SIZE_MAX ) )
1374                     {
1375                         msg_Err( &sys.demuxer, "Error while reading %s... upping level", typeid(*el).name());
1376                         ep->Up();
1377                         ep->Unkeep();
1378                         pp_simpleblock = NULL;
1379                         pp_block = NULL;
1380                         break;
1381                     }
1382                     if( MKV_IS_ID( el, KaxBlock ) )
1383                     {
1384                         pp_block = (KaxBlock*)el;
1385
1386                         pp_block->ReadData( es.I_O() );
1387                         pp_block->SetParent( *cluster );
1388
1389                         ep->Keep();
1390                     }
1391                     else if( MKV_IS_ID( el, KaxBlockDuration ) )
1392                     {
1393                         KaxBlockDuration &dur = *(KaxBlockDuration*)el;
1394
1395                         dur.ReadData( es.I_O() );
1396                         *pi_duration = uint64( dur );
1397                     }
1398                     else if( MKV_IS_ID( el, KaxReferenceBlock ) )
1399                     {
1400                         KaxReferenceBlock &ref = *(KaxReferenceBlock*)el;
1401
1402                         ref.ReadData( es.I_O() );
1403
1404                         if( *pb_key_picture )
1405                             *pb_key_picture = false;
1406                         else if( int64( ref ) > 0 )
1407                             *pb_discardable_picture = true;
1408                     }
1409                     else if( MKV_IS_ID( el, KaxClusterSilentTrackNumber ) )
1410                     {
1411                         KaxClusterSilentTrackNumber &track_num = *(KaxClusterSilentTrackNumber*)el;
1412                         track_num.ReadData( es.I_O() );
1413                         // find the track
1414                         for (size_t i=0; i<tracks.size(); i++)
1415                         {
1416                             if ( tracks[i]->i_number == uint32(track_num))
1417                             {
1418                                 tracks[i]->b_silent = true;
1419                                 break;
1420                             }
1421                         }
1422                     }
1423 #if LIBMATROSKA_VERSION >= 0x010401
1424                     else if( MKV_IS_ID( el, KaxDiscardPadding ) )
1425                     {
1426                         KaxDiscardPadding &dp = *(KaxDiscardPadding*) el;
1427                         *pi_duration -= int64(dp);
1428                     }
1429 #endif
1430                     break;
1431                 default:
1432                     msg_Err( &sys.demuxer, "invalid level = %d", i_level );
1433                     return VLC_EGENERIC;
1434             }
1435         }
1436         catch(...)
1437         {
1438             msg_Err( &sys.demuxer, "Error while reading %s... upping level", typeid(*el).name());
1439             ep->Up();
1440             ep->Unkeep();
1441             pp_simpleblock = NULL;
1442             pp_block = NULL;
1443         }
1444     }
1445 }
1446
1447 SimpleTag::~SimpleTag()
1448 {
1449     free(psz_tag_name);
1450     free(psz_lang);
1451     free(p_value);
1452     for(size_t i = 0; i < sub_tags.size(); i++)
1453         delete sub_tags[i];
1454 }
1455
1456 Tag::~Tag()
1457 {
1458     for(size_t i = 0; i < simple_tags.size(); i++)
1459         delete simple_tags[i];
1460 }