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