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