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