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