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