]> git.sesse.net Git - vlc/blob - modules/demux/mkv/matroska_segment.cpp
Improved support for AVI with DV data type 1.
[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     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     if( i_global_position >= 0 )
699     {
700         /* Special case for seeking in files with no cues */
701         EbmlElement *el = NULL;
702
703         /* Start from the last known index instead of the beginning eachtime */
704         if( i_index == 0)
705             es.I_O().setFilePointer( i_start_pos, seek_beginning );
706         else
707             es.I_O().setFilePointer( p_indexes[ i_index - 1 ].i_position,
708                                      seek_beginning );
709         delete ep;
710         ep = new EbmlParser( &es, segment, &sys.demuxer );
711         cluster = NULL;
712
713         while( ( el = ep->Get() ) != NULL )
714         {
715             if( MKV_IS_ID( el, KaxCluster ) )
716             {
717                 cluster = (KaxCluster *)el;
718                 i_cluster_pos = cluster->GetElementPosition();
719                 if( i_index == 0 ||
720                     ( i_index > 0 &&
721                       p_indexes[i_index - 1].i_position < (int64_t)cluster->GetElementPosition() ) )
722                 {
723                     ParseCluster(false);
724                     IndexAppendCluster( cluster );
725                 }
726                 if( es.I_O().getFilePointer() >= (unsigned) i_global_position )
727                     break;
728             }
729         }
730     }
731
732 #ifndef WIN32
733     /* Don't try complex seek if we seek to 0 */
734     if( i_date == 0 )
735     {
736         es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, 0 );
737         es_out_Control( sys.demuxer.out, ES_OUT_SET_PCR, VLC_TS_0 );
738         es.I_O().setFilePointer( i_start_pos );
739
740         delete ep;
741         ep = new EbmlParser( &es, segment, &sys.demuxer );
742         cluster = NULL;
743         sys.i_start_pts = 0;
744         sys.i_pts = 0;
745         sys.i_pcr = 0;
746         return;       
747     }
748 #endif
749
750     int i_idx = 0;
751     if ( i_index > 0 )
752     {
753
754         for( ; i_idx < i_index; i_idx++ )
755             if( p_indexes[i_idx].i_time + i_time_offset > i_date )
756                 break;
757
758         if( i_idx > 0 )
759             i_idx--;
760
761         i_seek_position = p_indexes[i_idx].i_position;
762         i_seek_time = p_indexes[i_idx].i_time;
763     }
764
765     msg_Dbg( &sys.demuxer, "seek got %"PRId64" (%d%%)",
766                 i_seek_time, (int)( 100 * i_seek_position / stream_Size( sys.demuxer.s ) ) );
767
768     es.I_O().setFilePointer( i_seek_position, seek_beginning );
769
770     delete ep;
771     ep = new EbmlParser( &es, segment, &sys.demuxer );
772     cluster = NULL;
773
774     sys.i_start_pts = i_date;
775
776     es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_date );
777
778     /* now parse until key frame */
779     const int es_types[3] = { VIDEO_ES, AUDIO_ES, SPU_ES };
780     i_cat = es_types[0];
781     for( int i = 0; i < 2; i_cat = es_types[++i] )
782     {
783         for( i_track = 0; i_track < tracks.size(); i_track++ )
784         {
785             if( tracks[i_track]->fmt.i_cat == i_cat )
786             {
787                 spoint * seekpoint = new spoint(i_track, i_seek_time, i_seek_position, i_seek_position);
788                 if( unlikely( !seekpoint ) )
789                 {
790                     for( spoint * sp = p_first; sp; )
791                     {
792                         spoint * tmp = sp;
793                         sp = sp->p_next;
794                         delete tmp;                    
795                     }
796                     return;
797                 }
798                 if( unlikely( !p_first ) )
799                 {
800                     p_first = seekpoint;
801                     p_last = seekpoint;
802                 }
803                 else
804                 {
805                     p_last->p_next = seekpoint;
806                     p_last = seekpoint;
807                 }
808             }
809         }
810         if( likely( p_first ) )
811             break;
812     }
813     /*Neither video nor audio track... no seek further*/
814     if( unlikely( !p_first ) )
815         return; 
816
817     for(;;)
818     {
819         while( i_pts < i_date )
820         {
821             bool b_key_picture;
822             bool b_discardable_picture;
823             if( BlockGet( block, simpleblock, &b_key_picture, &b_discardable_picture, &i_block_duration ) )
824             {
825                 msg_Warn( &sys.demuxer, "cannot get block EOF?" );
826                 return;
827             }
828
829             /* check if block's track is in our list */
830             for( i_track = 0; i_track < tracks.size(); i_track++ )
831             {
832                 if( (simpleblock && tracks[i_track]->i_number == simpleblock->TrackNum()) ||
833                     (block && tracks[i_track]->i_number == block->TrackNum()) )
834                     break;
835             }
836
837             if( simpleblock )
838                 i_pts = sys.i_chapter_time + simpleblock->GlobalTimecode() / (mtime_t) 1000;
839             else
840                 i_pts = sys.i_chapter_time + block->GlobalTimecode() / (mtime_t) 1000;
841             if( i_track < tracks.size() )
842             {
843                 if( tracks[i_track]->fmt.i_cat == i_cat && b_key_picture )
844                 {
845                     /* get the seekpoint */
846                     spoint * sp;
847                     for( sp =  p_first; sp; sp = sp->p_next )
848                         if( sp->i_track == i_track )
849                             break;
850
851                     sp->i_date = i_pts;
852                     if( simpleblock )
853                         sp->i_seek_pos = simpleblock->GetElementPosition();
854                     else
855                         sp->i_seek_pos = i_block_pos;
856                     sp->i_cluster_pos = i_cluster_pos;
857                     b_has_key = true;
858                 }
859             }
860
861             delete block;
862         }
863         if( b_has_key || !i_idx )
864             break;
865
866         /* No key picture was found in the cluster seek to previous seekpoint */
867         i_date = i_time_offset + p_indexes[i_idx].i_time;
868         i_idx--;
869         i_pts = 0;
870         es.I_O().setFilePointer( p_indexes[i_idx].i_position );
871         delete ep;
872         ep = new EbmlParser( &es, segment, &sys.demuxer );
873         cluster = NULL;
874     }
875
876     /* rewind to the last I img */
877     spoint * p_min;
878     for( p_min  = p_first, p_last = p_first; p_last; p_last = p_last->p_next )
879         if( p_last->i_date < p_min->i_date )
880             p_min = p_last;
881
882     sys.i_pcr = sys.i_pts = p_min->i_date;
883     es_out_Control( sys.demuxer.out, ES_OUT_SET_PCR, VLC_TS_0 + sys.i_pcr );
884     cluster = (KaxCluster *) ep->UnGet( p_min->i_seek_pos, p_min->i_cluster_pos );
885
886     /* hack use BlockGet to get the cluster then goto the wanted block */
887     if ( !cluster )
888     {
889         bool b_key_picture;
890         bool b_discardable_picture;
891         BlockGet( block, simpleblock, &b_key_picture, &b_discardable_picture, &i_block_duration );
892         delete block;
893         cluster = (KaxCluster *) ep->UnGet( p_min->i_seek_pos, p_min->i_cluster_pos );
894     }
895
896     while( p_first )
897     {
898         p_min = p_first;
899         p_first = p_first->p_next;
900         delete p_min;
901     }
902 }
903
904 int matroska_segment_c::BlockFindTrackIndex( size_t *pi_track,
905                                              const KaxBlock *p_block, const KaxSimpleBlock *p_simpleblock )
906 {
907     size_t i_track;
908     for( i_track = 0; i_track < tracks.size(); i_track++ )
909     {
910         const mkv_track_t *tk = tracks[i_track];
911
912         if( ( p_block != NULL && tk->i_number == p_block->TrackNum() ) ||
913             ( p_simpleblock != NULL && tk->i_number == p_simpleblock->TrackNum() ) )
914         {
915             break;
916         }
917     }
918
919     if( i_track >= tracks.size() )
920         return VLC_EGENERIC;
921
922     if( pi_track )
923         *pi_track = i_track;
924     return VLC_SUCCESS;
925 }
926
927 static inline void fill_extra_data( mkv_track_t *p_tk, unsigned int offset )
928 {
929     if(p_tk->i_extra_data <= offset) return;
930     p_tk->fmt.i_extra = p_tk->i_extra_data - offset;
931     p_tk->fmt.p_extra = xmalloc( p_tk->fmt.i_extra );
932     if(!p_tk->fmt.p_extra) { p_tk->fmt.i_extra = 0; return; };
933     memcpy( p_tk->fmt.p_extra, p_tk->p_extra_data + offset, p_tk->fmt.i_extra );
934 }
935
936 bool matroska_segment_c::Select( mtime_t i_start_time )
937 {
938     /* add all es */
939     msg_Dbg( &sys.demuxer, "found %d es", (int)tracks.size() );
940
941     bool b_has_default_video = false;
942     bool b_has_default_audio = false;
943     /* check for default */
944     for(size_t i_track = 0; i_track < tracks.size(); i_track++)
945     {
946         mkv_track_t *p_tk = tracks[i_track];
947         es_format_t *p_fmt = &p_tk->fmt;
948         if( p_fmt->i_cat == VIDEO_ES )
949             b_has_default_video |=
950                 p_tk->b_enabled && ( p_tk->b_default || p_tk->b_forced );
951         else if( p_fmt->i_cat == AUDIO_ES )
952             b_has_default_audio |=
953                 p_tk->b_enabled && ( p_tk->b_default || p_tk->b_forced );
954     }
955
956     for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
957     {
958         mkv_track_t *p_tk = tracks[i_track];
959         es_format_t *p_fmt = &p_tk->fmt;
960
961         if( unlikely( p_fmt->i_cat == UNKNOWN_ES || !p_tk->psz_codec ) )
962         {
963             msg_Warn( &sys.demuxer, "invalid track[%d, n=%d]", (int)i_track, p_tk->i_number );
964             p_tk->p_es = NULL;
965             continue;
966         }
967         else if( unlikely( !b_has_default_video && p_fmt->i_cat == VIDEO_ES ) )
968         {
969             p_tk->b_default = true;
970             b_has_default_video = true;
971         }
972         else if( unlikely( !b_has_default_audio &&  p_fmt->i_cat == AUDIO_ES ) )
973         {
974             p_tk->b_default = true;
975             b_has_default_audio = true;
976         }
977
978         if( !strcmp( p_tk->psz_codec, "V_MS/VFW/FOURCC" ) )
979         {
980             if( p_tk->i_extra_data < (int)sizeof( VLC_BITMAPINFOHEADER ) )
981             {
982                 msg_Err( &sys.demuxer, "missing/invalid VLC_BITMAPINFOHEADER" );
983                 p_tk->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
984             }
985             else
986             {
987                 VLC_BITMAPINFOHEADER *p_bih = (VLC_BITMAPINFOHEADER*)p_tk->p_extra_data;
988
989                 p_tk->fmt.video.i_width = GetDWLE( &p_bih->biWidth );
990                 p_tk->fmt.video.i_height= GetDWLE( &p_bih->biHeight );
991                 p_tk->fmt.i_codec       = GetFOURCC( &p_bih->biCompression );
992
993                 p_tk->fmt.i_extra       = GetDWLE( &p_bih->biSize ) - sizeof( VLC_BITMAPINFOHEADER );
994                 if( p_tk->fmt.i_extra > 0 )
995                 {
996                     /* Very unlikely yet possible: bug #5659*/
997                     size_t maxlen = p_tk->i_extra_data - sizeof( VLC_BITMAPINFOHEADER );
998                     p_tk->fmt.i_extra = ( (unsigned)p_tk->fmt.i_extra < maxlen )?
999                         p_tk->fmt.i_extra : maxlen;
1000
1001                     p_tk->fmt.p_extra = xmalloc( p_tk->fmt.i_extra );
1002                     memcpy( p_tk->fmt.p_extra, &p_bih[1], p_tk->fmt.i_extra );
1003                 }
1004             }
1005             p_tk->b_dts_only = true;
1006         }
1007         else if( !strcmp( p_tk->psz_codec, "V_MPEG1" ) ||
1008                  !strcmp( p_tk->psz_codec, "V_MPEG2" ) )
1009         {
1010             p_tk->fmt.i_codec = VLC_CODEC_MPGV;
1011             if( p_tk->i_extra_data )
1012                 fill_extra_data( p_tk, 0 );
1013         }
1014         else if( !strncmp( p_tk->psz_codec, "V_THEORA", 8 ) )
1015         {
1016             p_tk->fmt.i_codec = VLC_CODEC_THEORA;
1017             fill_extra_data( p_tk, 0 );
1018             p_tk->b_pts_only = true;
1019         }
1020         else if( !strncmp( p_tk->psz_codec, "V_REAL/RV", 9 ) )
1021         {
1022             uint8_t *p = p_tk->p_extra_data;
1023
1024             if( !strcmp( p_tk->psz_codec, "V_REAL/RV10" ) )
1025                 p_fmt->i_codec = VLC_CODEC_RV10;
1026             else if( !strcmp( p_tk->psz_codec, "V_REAL/RV20" ) )
1027                 p_fmt->i_codec = VLC_CODEC_RV20;
1028             else if( !strcmp( p_tk->psz_codec, "V_REAL/RV30" ) )
1029                 p_fmt->i_codec = VLC_CODEC_RV30;
1030             else if( !strcmp( p_tk->psz_codec, "V_REAL/RV40" ) )
1031                 p_fmt->i_codec = VLC_CODEC_RV40;
1032
1033             /* Extract the framerate from the header */
1034             if( p_tk->i_extra_data >= 26 &&
1035                 p[4] == 'V' && p[5] == 'I' && p[6] == 'D' && p[7] == 'O' &&
1036                 p[8] == 'R' && p[9] == 'V' &&
1037                 (p[10] == '3' || p[10] == '4') && p[11] == '0' )
1038             {
1039                 p_tk->fmt.video.i_frame_rate =
1040                     p[22] << 24 | p[23] << 16 | p[24] << 8 | p[25] << 0;
1041                 p_tk->fmt.video.i_frame_rate_base = 65536;
1042             }
1043
1044             fill_extra_data( p_tk, 26 );
1045             p_tk->b_dts_only = true;
1046         }
1047         else if( !strncmp( p_tk->psz_codec, "V_DIRAC", 7 ) )
1048         {
1049             p_tk->fmt.i_codec = VLC_CODEC_DIRAC;
1050         }
1051         else if( !strncmp( p_tk->psz_codec, "V_VP8", 5 ) )
1052         {
1053             p_tk->fmt.i_codec = VLC_CODEC_VP8;
1054             p_tk->b_pts_only = true;
1055         }
1056         else if( !strncmp( p_tk->psz_codec, "V_MPEG4", 7 ) )
1057         {
1058             if( !strcmp( p_tk->psz_codec, "V_MPEG4/MS/V3" ) )
1059             {
1060                 p_tk->fmt.i_codec = VLC_CODEC_DIV3;
1061             }
1062             else if( !strncmp( p_tk->psz_codec, "V_MPEG4/ISO", 11 ) )
1063             {
1064                 /* A MPEG 4 codec, SP, ASP, AP or AVC */
1065                 if( !strcmp( p_tk->psz_codec, "V_MPEG4/ISO/AVC" ) )
1066                     p_tk->fmt.i_codec = VLC_FOURCC( 'a', 'v', 'c', '1' );
1067                 else
1068                     p_tk->fmt.i_codec = VLC_CODEC_MP4V;
1069                 fill_extra_data( p_tk, 0 );
1070             }
1071         }
1072         else if( !strcmp( p_tk->psz_codec, "V_QUICKTIME" ) )
1073         {
1074             MP4_Box_t *p_box = (MP4_Box_t*)xmalloc( sizeof( MP4_Box_t ) );
1075             stream_t *p_mp4_stream = stream_MemoryNew( VLC_OBJECT(&sys.demuxer),
1076                                                        p_tk->p_extra_data,
1077                                                        p_tk->i_extra_data,
1078                                                        true );
1079             if( MP4_ReadBoxCommon( p_mp4_stream, p_box ) &&
1080                 MP4_ReadBox_sample_vide( p_mp4_stream, p_box ) )
1081             {
1082                 p_tk->fmt.i_codec = p_box->i_type;
1083                 p_tk->fmt.video.i_width = p_box->data.p_sample_vide->i_width;
1084                 p_tk->fmt.video.i_height = p_box->data.p_sample_vide->i_height;
1085                 p_tk->fmt.i_extra = p_box->data.p_sample_vide->i_qt_image_description;
1086                 p_tk->fmt.p_extra = xmalloc( p_tk->fmt.i_extra );
1087                 memcpy( p_tk->fmt.p_extra, p_box->data.p_sample_vide->p_qt_image_description, p_tk->fmt.i_extra );
1088                 MP4_FreeBox_sample_vide( p_box );
1089             }
1090             else
1091             {
1092                 free( p_box );
1093             }
1094             stream_Delete( p_mp4_stream );
1095         }
1096         else if( !strcmp( p_tk->psz_codec, "V_MJPEG" ) )
1097         {
1098             p_tk->fmt.i_codec = VLC_CODEC_MJPG;
1099         }
1100         else if( !strcmp( p_tk->psz_codec, "A_MS/ACM" ) )
1101         {
1102             if( p_tk->i_extra_data < (int)sizeof( WAVEFORMATEX ) )
1103             {
1104                 msg_Err( &sys.demuxer, "missing/invalid WAVEFORMATEX" );
1105                 p_tk->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1106             }
1107             else
1108             {
1109                 WAVEFORMATEX *p_wf = (WAVEFORMATEX*)p_tk->p_extra_data;
1110
1111                 wf_tag_to_fourcc( GetWLE( &p_wf->wFormatTag ), &p_tk->fmt.i_codec, NULL );
1112
1113                 if( p_tk->fmt.i_codec == VLC_FOURCC( 'u', 'n', 'd', 'f' ) )
1114                     msg_Err( &sys.demuxer, "Unrecognized wf tag: 0x%x", GetWLE( &p_wf->wFormatTag ) );
1115                 p_tk->fmt.audio.i_channels   = GetWLE( &p_wf->nChannels );
1116                 p_tk->fmt.audio.i_rate = GetDWLE( &p_wf->nSamplesPerSec );
1117                 p_tk->fmt.i_bitrate    = GetDWLE( &p_wf->nAvgBytesPerSec ) * 8;
1118                 p_tk->fmt.audio.i_blockalign = GetWLE( &p_wf->nBlockAlign );;
1119                 p_tk->fmt.audio.i_bitspersample = GetWLE( &p_wf->wBitsPerSample );
1120
1121                 p_tk->fmt.i_extra            = GetWLE( &p_wf->cbSize );
1122                 if( p_tk->fmt.i_extra > 0 )
1123                 {
1124                     p_tk->fmt.p_extra = xmalloc( p_tk->fmt.i_extra );
1125                     memcpy( p_tk->fmt.p_extra, &p_wf[1], p_tk->fmt.i_extra );
1126                 }
1127             }
1128         }
1129         else if( !strcmp( p_tk->psz_codec, "A_MPEG/L3" ) ||
1130                  !strcmp( p_tk->psz_codec, "A_MPEG/L2" ) ||
1131                  !strcmp( p_tk->psz_codec, "A_MPEG/L1" ) )
1132         {
1133             p_tk->fmt.i_codec = VLC_CODEC_MPGA;
1134         }
1135         else if( !strcmp( p_tk->psz_codec, "A_AC3" ) )
1136         {
1137             p_tk->fmt.i_codec = VLC_CODEC_A52;
1138         }
1139         else if( !strcmp( p_tk->psz_codec, "A_EAC3" ) )
1140         {
1141             p_tk->fmt.i_codec = VLC_CODEC_EAC3;
1142         }
1143         else if( !strcmp( p_tk->psz_codec, "A_DTS" ) )
1144         {
1145             p_tk->fmt.i_codec = VLC_CODEC_DTS;
1146         }
1147         else if( !strcmp( p_tk->psz_codec, "A_MLP" ) )
1148         {
1149             p_tk->fmt.i_codec = VLC_CODEC_MLP;
1150         }
1151         else if( !strcmp( p_tk->psz_codec, "A_TRUEHD" ) )
1152         {
1153             /* FIXME when more samples arrive */
1154             p_tk->fmt.i_codec = VLC_CODEC_TRUEHD;
1155             p_fmt->b_packetized = false;
1156         }
1157         else if( !strcmp( p_tk->psz_codec, "A_FLAC" ) )
1158         {
1159             p_tk->fmt.i_codec = VLC_CODEC_FLAC;
1160             fill_extra_data( p_tk, 0 );
1161         }
1162         else if( !strcmp( p_tk->psz_codec, "A_VORBIS" ) )
1163         {
1164             p_tk->fmt.i_codec = VLC_CODEC_VORBIS;
1165             fill_extra_data( p_tk, 0 );
1166         }
1167         else if( !strncmp( p_tk->psz_codec, "A_AAC/MPEG2/", strlen( "A_AAC/MPEG2/" ) ) ||
1168                  !strncmp( p_tk->psz_codec, "A_AAC/MPEG4/", strlen( "A_AAC/MPEG4/" ) ) )
1169         {
1170             int i_profile, i_srate, sbr = 0;
1171             static const unsigned int i_sample_rates[] =
1172             {
1173                     96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
1174                     16000, 12000, 11025,  8000,  7350,     0,     0,     0
1175             };
1176
1177             p_tk->fmt.i_codec = VLC_CODEC_MP4A;
1178             /* create data for faad (MP4DecSpecificDescrTag)*/
1179
1180             if( !strcmp( &p_tk->psz_codec[12], "MAIN" ) )
1181             {
1182                 i_profile = 0;
1183             }
1184             else if( !strcmp( &p_tk->psz_codec[12], "LC" ) )
1185             {
1186                 i_profile = 1;
1187             }
1188             else if( !strcmp( &p_tk->psz_codec[12], "SSR" ) )
1189             {
1190                 i_profile = 2;
1191             }
1192             else if( !strcmp( &p_tk->psz_codec[12], "LC/SBR" ) )
1193             {
1194                 i_profile = 1;
1195                 sbr = 1;
1196             }
1197             else
1198             {
1199                 i_profile = 3;
1200             }
1201
1202             for( i_srate = 0; i_srate < 13; i_srate++ )
1203             {
1204                 if( i_sample_rates[i_srate] == p_tk->i_original_rate )
1205                 {
1206                     break;
1207                 }
1208             }
1209             msg_Dbg( &sys.demuxer, "profile=%d srate=%d", i_profile, i_srate );
1210
1211             p_tk->fmt.i_extra = sbr ? 5 : 2;
1212             p_tk->fmt.p_extra = xmalloc( p_tk->fmt.i_extra );
1213             ((uint8_t*)p_tk->fmt.p_extra)[0] = ((i_profile + 1) << 3) | ((i_srate&0xe) >> 1);
1214             ((uint8_t*)p_tk->fmt.p_extra)[1] = ((i_srate & 0x1) << 7) | (p_tk->fmt.audio.i_channels << 3);
1215             if (sbr != 0)
1216             {
1217                 int syncExtensionType = 0x2B7;
1218                 int iDSRI;
1219                 for (iDSRI=0; iDSRI<13; iDSRI++)
1220                     if( i_sample_rates[iDSRI] == p_tk->fmt.audio.i_rate )
1221                         break;
1222                 ((uint8_t*)p_tk->fmt.p_extra)[2] = (syncExtensionType >> 3) & 0xFF;
1223                 ((uint8_t*)p_tk->fmt.p_extra)[3] = ((syncExtensionType & 0x7) << 5) | 5;
1224                 ((uint8_t*)p_tk->fmt.p_extra)[4] = ((1 & 0x1) << 7) | (iDSRI << 3);
1225             }
1226         }
1227         else if( !strcmp( p_tk->psz_codec, "A_AAC" ) )
1228         {
1229             p_tk->fmt.i_codec = VLC_CODEC_MP4A;
1230             fill_extra_data( p_tk, 0 );
1231         }
1232         else if( !strcmp( p_tk->psz_codec, "A_WAVPACK4" ) )
1233         {
1234             p_tk->fmt.i_codec = VLC_CODEC_WAVPACK;
1235             fill_extra_data( p_tk, 0 );
1236         }
1237         else if( !strcmp( p_tk->psz_codec, "A_TTA1" ) )
1238         {
1239             p_fmt->i_codec = VLC_CODEC_TTA;
1240             if( p_tk->i_extra_data > 0 )
1241             {
1242               fill_extra_data( p_tk, 0 );
1243             }
1244             else
1245             {
1246                 p_fmt->i_extra = 30;
1247                 p_fmt->p_extra = xmalloc( p_fmt->i_extra );
1248                 uint8_t *p_extra = (uint8_t*)p_fmt->p_extra;
1249                 memcpy( &p_extra[ 0], "TTA1", 4 );
1250                 SetWLE( &p_extra[ 4], 1 );
1251                 SetWLE( &p_extra[ 6], p_fmt->audio.i_channels );
1252                 SetWLE( &p_extra[ 8], p_fmt->audio.i_bitspersample );
1253                 SetDWLE( &p_extra[10], p_fmt->audio.i_rate );
1254                 SetDWLE( &p_extra[14], 0xffffffff );
1255                 memset( &p_extra[18], 0, 30  - 18 );
1256             }
1257         }
1258         else if( !strcmp( p_tk->psz_codec, "A_PCM/INT/BIG" ) ||
1259                  !strcmp( p_tk->psz_codec, "A_PCM/INT/LIT" ) ||
1260                  !strcmp( p_tk->psz_codec, "A_PCM/FLOAT/IEEE" ) )
1261         {
1262             if( !strcmp( p_tk->psz_codec, "A_PCM/INT/BIG" ) )
1263             {
1264                 p_tk->fmt.i_codec = VLC_FOURCC( 't', 'w', 'o', 's' );
1265             }
1266             else
1267             {
1268                 p_tk->fmt.i_codec = VLC_FOURCC( 'a', 'r', 'a', 'w' );
1269             }
1270             p_tk->fmt.audio.i_blockalign = ( p_tk->fmt.audio.i_bitspersample + 7 ) / 8 * p_tk->fmt.audio.i_channels;
1271         }
1272         else if( !strncmp( p_tk->psz_codec, "A_REAL/", 7 ) )
1273         {
1274             if( !strcmp( p_tk->psz_codec, "A_REAL/14_4" ) )
1275             {
1276                 p_fmt->i_codec = VLC_CODEC_RA_144;
1277                 p_fmt->audio.i_channels = 1;
1278                 p_fmt->audio.i_rate = 8000;
1279                 p_fmt->audio.i_blockalign = 0x14;
1280             }
1281             else if( p_tk->i_extra_data > 28 )
1282             {
1283                 uint8_t *p = p_tk->p_extra_data;
1284                 if( memcmp( p, ".ra", 3 ) ) {
1285                     msg_Err( &sys.demuxer, "Invalid Real ExtraData 0x%4.4s", (char *)p );
1286                     p_tk->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1287                 }
1288                 else {
1289                     if( !strcmp( p_tk->psz_codec, "A_REAL/COOK" ) )
1290                         p_tk->fmt.i_codec = VLC_CODEC_COOK;
1291                     else if( !strcmp( p_tk->psz_codec, "A_REAL/ATRC" ) )
1292                         p_tk->fmt.i_codec = VLC_CODEC_ATRAC3;
1293                     else if( !strcmp( p_tk->psz_codec, "A_REAL/28_8" ) )
1294                         p_tk->fmt.i_codec = VLC_CODEC_RA_288;
1295                     /* FIXME RALF and SIPR */
1296
1297                     fill_extra_data( p_tk, p_tk->fmt.i_codec == VLC_CODEC_RA_288 ? 0 : 78);
1298                 }
1299             }
1300         }
1301         else if( !strcmp( p_tk->psz_codec, "S_KATE" ) )
1302         {
1303             p_tk->fmt.i_codec = VLC_CODEC_KATE;
1304             p_tk->fmt.subs.psz_encoding = strdup( "UTF-8" );
1305
1306             fill_extra_data( p_tk, 0 );
1307         }
1308         else if( !strcmp( p_tk->psz_codec, "S_TEXT/ASCII" ) )
1309         {
1310             p_fmt->i_codec = VLC_CODEC_SUBT;
1311             p_fmt->subs.psz_encoding = strdup( "ASCII" );
1312         }
1313         else if( !strcmp( p_tk->psz_codec, "S_TEXT/UTF8" ) )
1314         {
1315             p_tk->fmt.i_codec = VLC_CODEC_SUBT;
1316             p_tk->fmt.subs.psz_encoding = strdup( "UTF-8" );
1317         }
1318         else if( !strcmp( p_tk->psz_codec, "S_TEXT/USF" ) )
1319         {
1320             p_tk->fmt.i_codec = VLC_FOURCC( 'u', 's', 'f', ' ' );
1321             p_tk->fmt.subs.psz_encoding = strdup( "UTF-8" );
1322             if( p_tk->i_extra_data )
1323                 fill_extra_data( p_tk, 0 );
1324         }
1325         else if( !strcmp( p_tk->psz_codec, "S_TEXT/SSA" ) ||
1326                  !strcmp( p_tk->psz_codec, "S_TEXT/ASS" ) ||
1327                  !strcmp( p_tk->psz_codec, "S_SSA" ) ||
1328                  !strcmp( p_tk->psz_codec, "S_ASS" ))
1329         {
1330             p_tk->fmt.i_codec = VLC_CODEC_SSA;
1331             p_tk->fmt.subs.psz_encoding = strdup( "UTF-8" );
1332             if( p_tk->i_extra_data )
1333                 fill_extra_data( p_tk, 0 );
1334         }
1335         else if( !strcmp( p_tk->psz_codec, "S_VOBSUB" ) )
1336         {
1337             p_tk->fmt.i_codec = VLC_CODEC_SPU;
1338             if( p_tk->i_extra_data )
1339             {
1340                 char *psz_start;
1341                 char *psz_buf = (char *)malloc( p_tk->i_extra_data + 1);
1342                 if( psz_buf != NULL )
1343                 {
1344                     memcpy( psz_buf, p_tk->p_extra_data , p_tk->i_extra_data );
1345                     psz_buf[p_tk->i_extra_data] = '\0';
1346
1347                     psz_start = strstr( psz_buf, "size:" );
1348                     if( psz_start &&
1349                         vobsub_size_parse( psz_start,
1350                                            &p_tk->fmt.subs.spu.i_original_frame_width,
1351                                            &p_tk->fmt.subs.spu.i_original_frame_height ) == VLC_SUCCESS )
1352                     {
1353                         msg_Dbg( &sys.demuxer, "original frame size vobsubs: %dx%d",
1354                                  p_tk->fmt.subs.spu.i_original_frame_width,
1355                                  p_tk->fmt.subs.spu.i_original_frame_height );
1356                     }
1357                     else
1358                     {
1359                         msg_Warn( &sys.demuxer, "reading original frame size for vobsub failed" );
1360                     }
1361
1362                     psz_start = strstr( psz_buf, "palette:" );
1363                     if( psz_start &&
1364                         vobsub_palette_parse( psz_start, &p_tk->fmt.subs.spu.palette[1] ) == VLC_SUCCESS )
1365                     {
1366                         p_tk->fmt.subs.spu.palette[0] =  0xBeef;
1367                         msg_Dbg( &sys.demuxer, "vobsub palette read" );
1368                     }
1369                     else
1370                     {
1371                         msg_Warn( &sys.demuxer, "reading original palette failed" );
1372                     }
1373                     free( psz_buf );
1374                 }
1375             }
1376         }
1377         else if( !strcmp( p_tk->psz_codec, "S_HDMV/PGS" ) )
1378         {
1379             p_tk->fmt.i_codec = VLC_CODEC_BD_PG;
1380         }
1381         else if( !strcmp( p_tk->psz_codec, "B_VOBBTN" ) )
1382         {
1383             p_tk->fmt.i_cat = NAV_ES;
1384             continue;
1385         }
1386         else
1387         {
1388             msg_Err( &sys.demuxer, "unknown codec id=`%s'", p_tk->psz_codec );
1389             p_tk->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1390         }
1391         if( unlikely( !p_tk->b_enabled ) )
1392             p_tk->fmt.i_priority = -2;
1393         else if( p_tk->b_forced )
1394             p_tk->fmt.i_priority = 2;
1395         else if( p_tk->b_default )
1396             p_tk->fmt.i_priority = 1;
1397         else
1398             p_tk->fmt.i_priority = 0;
1399
1400         /* Avoid multivideo tracks when unnecessary */
1401         if( p_tk->fmt.i_cat == VIDEO_ES )
1402             p_tk->fmt.i_priority--;
1403
1404         p_tk->p_es = es_out_Add( sys.demuxer.out, &p_tk->fmt );
1405
1406         /* Turn on a subtitles track if it has been flagged as default -
1407          * but only do this if no subtitles track has already been engaged,
1408          * either by an earlier 'default track' (??) or by default
1409          * language choice behaviour.
1410          */
1411         if( p_tk->b_default )
1412         {
1413             es_out_Control( sys.demuxer.out,
1414                             ES_OUT_SET_ES_DEFAULT,
1415                             p_tk->p_es );
1416         }
1417     }
1418     es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_start_time );
1419
1420     sys.i_start_pts = i_start_time;
1421     // reset the stream reading to the first cluster of the segment used
1422     es.I_O().setFilePointer( i_start_pos );
1423
1424     delete ep;
1425     ep = new EbmlParser( &es, segment, &sys.demuxer );
1426
1427     return true;
1428 }
1429
1430 void matroska_segment_c::UnSelect( )
1431 {
1432     sys.p_ev->ResetPci();
1433     for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
1434     {
1435         if ( tracks[i_track]->p_es != NULL )
1436         {
1437 //            es_format_Clean( &tracks[i_track]->fmt );
1438             es_out_Del( sys.demuxer.out, tracks[i_track]->p_es );
1439             tracks[i_track]->p_es = NULL;
1440         }
1441     }
1442     delete ep;
1443     ep = NULL;
1444 }
1445
1446 int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_simpleblock, bool *pb_key_picture, bool *pb_discardable_picture, int64_t *pi_duration )
1447 {
1448     pp_simpleblock = NULL;
1449     pp_block = NULL;
1450
1451     *pb_key_picture         = true;
1452     *pb_discardable_picture = false;
1453
1454     for( ;; )
1455     {
1456         EbmlElement *el = NULL;
1457         int         i_level;
1458
1459         if ( ep == NULL )
1460             return VLC_EGENERIC;
1461
1462         if( pp_simpleblock != NULL || ((el = ep->Get()) == NULL && pp_block != NULL) )
1463         {
1464             /* Check blocks validity to protect againts broken files */
1465             if( BlockFindTrackIndex( NULL, pp_block , pp_simpleblock ) )
1466             {
1467                 delete pp_block;
1468                 pp_simpleblock = NULL;
1469                 pp_block = NULL;
1470                 continue;
1471             }
1472             if( pp_simpleblock != NULL )
1473             {
1474                 *pb_key_picture         = pp_simpleblock->IsKeyframe();
1475                 *pb_discardable_picture = pp_simpleblock->IsDiscardable();
1476             }
1477
1478             /* update the index */
1479 #define idx p_indexes[i_index - 1]
1480             if( i_index > 0 && idx.i_time == -1 )
1481             {
1482                 if ( pp_simpleblock != NULL )
1483                     idx.i_time        = pp_simpleblock->GlobalTimecode() / (mtime_t)1000;
1484                 else
1485                     idx.i_time        = (*pp_block).GlobalTimecode() / (mtime_t)1000;
1486                 idx.b_key         = *pb_key_picture;
1487             }
1488 #undef idx
1489             return VLC_SUCCESS;
1490         }
1491
1492         i_level = ep->GetLevel();
1493
1494         if( el == NULL )
1495         {
1496             if( i_level > 1 )
1497             {
1498                 ep->Up();
1499                 continue;
1500             }
1501             msg_Warn( &sys.demuxer, "EOF" );
1502             return VLC_EGENERIC;
1503         }
1504
1505         /* Verify that we are still inside our cluster
1506          * It can happens whith broken files and when seeking
1507          * without index */
1508         if( i_level > 1 )
1509         {
1510             if( cluster && !ep->IsTopPresent( cluster ) )
1511             {
1512                 msg_Warn( &sys.demuxer, "Unexpected escape from current cluster" );
1513                 cluster = NULL;
1514             }
1515             if( !cluster )
1516                 continue;
1517         }
1518
1519         /* do parsing */
1520         switch ( i_level )
1521         {
1522         case 1:
1523             if( MKV_IS_ID( el, KaxCluster ) )
1524             {
1525                 cluster = (KaxCluster*)el;
1526                 i_cluster_pos = cluster->GetElementPosition();
1527
1528                 // reset silent tracks
1529                 for (size_t i=0; i<tracks.size(); i++)
1530                 {
1531                     tracks[i]->b_silent = false;
1532                 }
1533
1534                 ep->Down();
1535             }
1536             else if( MKV_IS_ID( el, KaxCues ) )
1537             {
1538                 msg_Warn( &sys.demuxer, "find KaxCues FIXME" );
1539                 return VLC_EGENERIC;
1540             }
1541             else
1542             {
1543                 msg_Dbg( &sys.demuxer, "unknown (%s)", typeid( el ).name() );
1544             }
1545             break;
1546         case 2:
1547             if( MKV_IS_ID( el, KaxClusterTimecode ) )
1548             {
1549                 KaxClusterTimecode &ctc = *(KaxClusterTimecode*)el;
1550
1551                 ctc.ReadData( es.I_O(), SCOPE_ALL_DATA );
1552                 cluster->InitTimecode( uint64( ctc ), i_timescale );
1553  
1554                 /* add it to the index */
1555                 if( i_index == 0 ||
1556                     ( i_index > 0 &&
1557                       p_indexes[i_index - 1].i_position < (int64_t)cluster->GetElementPosition() ) )
1558                     IndexAppendCluster( cluster );
1559             }
1560             else if( MKV_IS_ID( el, KaxClusterSilentTracks ) )
1561             {
1562                 ep->Down();
1563             }
1564             else if( MKV_IS_ID( el, KaxBlockGroup ) )
1565             {
1566                 i_block_pos = el->GetElementPosition();
1567                 ep->Down();
1568             }
1569             else if( MKV_IS_ID( el, KaxSimpleBlock ) )
1570             {
1571                 pp_simpleblock = (KaxSimpleBlock*)el;
1572
1573                 pp_simpleblock->ReadData( es.I_O() );
1574                 pp_simpleblock->SetParent( *cluster );
1575             }
1576             break;
1577         case 3:
1578             if( MKV_IS_ID( el, KaxBlock ) )
1579             {
1580                 pp_block = (KaxBlock*)el;
1581
1582                 pp_block->ReadData( es.I_O() );
1583                 pp_block->SetParent( *cluster );
1584
1585                 ep->Keep();
1586             }
1587             else if( MKV_IS_ID( el, KaxBlockDuration ) )
1588             {
1589                 KaxBlockDuration &dur = *(KaxBlockDuration*)el;
1590
1591                 dur.ReadData( es.I_O() );
1592                 *pi_duration = uint64( dur );
1593             }
1594             else if( MKV_IS_ID( el, KaxReferenceBlock ) )
1595             {
1596                 KaxReferenceBlock &ref = *(KaxReferenceBlock*)el;
1597
1598                 ref.ReadData( es.I_O() );
1599
1600                 if( *pb_key_picture )
1601                     *pb_key_picture = false;
1602                 else if( int64( ref ) > 0 )
1603                     *pb_discardable_picture = true;
1604             }
1605             else if( MKV_IS_ID( el, KaxClusterSilentTrackNumber ) )
1606             {
1607                 KaxClusterSilentTrackNumber &track_num = *(KaxClusterSilentTrackNumber*)el;
1608                 track_num.ReadData( es.I_O() );
1609                 // find the track
1610                 for (size_t i=0; i<tracks.size(); i++)
1611                 {
1612                     if ( tracks[i]->i_number == uint32(track_num))
1613                     {
1614                         tracks[i]->b_silent = true;
1615                         break;
1616                     }
1617                 }
1618             }
1619             break;
1620         default:
1621             msg_Err( &sys.demuxer, "invalid level = %d", i_level );
1622             return VLC_EGENERIC;
1623         }
1624     }
1625 }
1626