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