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