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