matroska_segment.cpp 49.9 KB
Newer Older
1
/*****************************************************************************
Pere Orga's avatar
Pere Orga committed
2
 * matroska_segment.cpp : matroska demuxer
3
 *****************************************************************************
Jean-Baptiste Kempf's avatar
LGPL    
Jean-Baptiste Kempf committed
4
 * Copyright (C) 2003-2010 VLC authors and VideoLAN
5
6
7
8
9
 * $Id$
 *
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
 *          Steve Lhomme <steve.lhomme@free.fr>
 *
Jean-Baptiste Kempf's avatar
LGPL    
Jean-Baptiste Kempf committed
10
11
12
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
13
14
15
16
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Jean-Baptiste Kempf's avatar
LGPL    
Jean-Baptiste Kempf committed
17
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
19
 *
Jean-Baptiste Kempf's avatar
LGPL    
Jean-Baptiste Kempf committed
20
21
22
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23
24
 *****************************************************************************/

25
26
27
#include "matroska_segment.hpp"
#include "chapters.hpp"
#include "demux.hpp"
Denis Charmet's avatar
Denis Charmet committed
28
#include "util.hpp"
29
30
#include "Ebml_parser.hpp"

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
matroska_segment_c::matroska_segment_c( demux_sys_t & demuxer, EbmlStream & estream )
    :segment(NULL)
    ,es(estream)
    ,i_timescale(MKVD_TIMECODESCALE)
    ,i_duration(-1)
    ,i_start_time(0)
    ,i_seekhead_count(0)
    ,i_seekhead_position(-1)
    ,i_cues_position(-1)
    ,i_tracks_position(-1)
    ,i_info_position(-1)
    ,i_chapters_position(-1)
    ,i_tags_position(-1)
    ,i_attachments_position(-1)
    ,cluster(NULL)
    ,i_block_pos(0)
    ,i_cluster_pos(0)
    ,i_start_pos(0)
    ,p_segment_uid(NULL)
    ,p_prev_segment_uid(NULL)
    ,p_next_segment_uid(NULL)
    ,b_cues(false)
    ,i_index(0)
    ,i_index_max(1024)
    ,psz_muxing_application(NULL)
    ,psz_writing_application(NULL)
    ,psz_segment_filename(NULL)
    ,psz_title(NULL)
    ,psz_date_utc(NULL)
    ,i_default_edition(0)
    ,sys(demuxer)
    ,ep(NULL)
    ,b_preloaded(false)
64
    ,b_ref_external_segments(false)
65
66
67
68
{
    p_indexes = (mkv_index_t*)malloc( sizeof( mkv_index_t ) * i_index_max );
}

69
70
71
72
73
74
matroska_segment_c::~matroska_segment_c()
{
    for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
    {
        delete tracks[i_track]->p_compression_data;
        es_format_Clean( &tracks[i_track]->fmt );
Denis Charmet's avatar
Denis Charmet committed
75
        delete tracks[i_track]->p_sys;
76
77
78
79
        free( tracks[i_track]->p_extra_data );
        free( tracks[i_track]->psz_codec );
        delete tracks[i_track];
    }
80

81
82
83
84
85
86
    free( psz_writing_application );
    free( psz_muxing_application );
    free( psz_segment_filename );
    free( psz_title );
    free( psz_date_utc );
    free( p_indexes );
87

88
89
90
91
92
    delete ep;
    delete segment;
    delete p_segment_uid;
    delete p_prev_segment_uid;
    delete p_next_segment_uid;
93

94
95
96
    vlc_delete_all( stored_editions );
    vlc_delete_all( translations );
    vlc_delete_all( families );
97
98
}

99

100
/*****************************************************************************
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
101
102
 * Tools                                                                     *
 *****************************************************************************
103
104
105
 *  * LoadCues : load the cues element and update index
 *  * LoadTags : load ... the tags element
 *  * InformationCreate : create all information, load tags if present
106
 *****************************************************************************/
107
void matroska_segment_c::LoadCues( KaxCues *cues )
108
{
109
    bool b_invalid_cue;
110
111
    EbmlParser  *ep;
    EbmlElement *el;
112

113
    if( b_cues )
114
    {
115
116
        msg_Err( &sys.demuxer, "There can be only 1 Cues per section." );
        return;
117
118
    }

119
120
121
122
123
    ep = new EbmlParser( &es, cues, &sys.demuxer );
    while( ( el = ep->Get() ) != NULL )
    {
        if( MKV_IS_ID( el, KaxCuePoint ) )
        {
124
            b_invalid_cue = false;
125
#define idx p_indexes[i_index]
126

127
128
129
130
131
            idx.i_track       = -1;
            idx.i_block_number= -1;
            idx.i_position    = -1;
            idx.i_time        = 0;
            idx.b_key         = true;
132

133
134
135
136
137
138
            ep->Down();
            while( ( el = ep->Get() ) != NULL )
            {
                if( MKV_IS_ID( el, KaxCueTime ) )
                {
                    KaxCueTime &ctime = *(KaxCueTime*)el;
139
140
                    try
                    {
141
142
143
144
145
146
                        if( unlikely( ctime.GetSize() >= SIZE_MAX ) )
                        {
                            msg_Err( &sys.demuxer, "CueTime size too big");
                            b_invalid_cue = true;
                            break;
                        }
147
148
149
150
151
152
153
154
                        ctime.ReadData( es.I_O() );
                    }
                    catch(...)
                    {
                        msg_Err( &sys.demuxer, "Error while reading CueTime" );
                        b_invalid_cue = true;
                        break;
                    }
155
156
157
158
159
                    idx.i_time = uint64( ctime ) * i_timescale / (mtime_t)1000;
                }
                else if( MKV_IS_ID( el, KaxCueTrackPositions ) )
                {
                    ep->Down();
160
                    try
161
                    {
162
                        while( ( el = ep->Get() ) != NULL )
163
                        {
164
165
166
167
168
169
170
171
                            if( unlikely( el->GetSize() >= SIZE_MAX ) )
                            {
                                ep->Up();
                                msg_Err( &sys.demuxer, "Error %s too big, aborting", typeid(*el).name() );
                                b_invalid_cue = true;
                                break;
                            }

172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
                            if( MKV_IS_ID( el, KaxCueTrack ) )
                            {
                                KaxCueTrack &ctrack = *(KaxCueTrack*)el;
                                ctrack.ReadData( es.I_O() );
                                idx.i_track = uint16( ctrack );
                            }
                            else if( MKV_IS_ID( el, KaxCueClusterPosition ) )
                            {
                                KaxCueClusterPosition &ccpos = *(KaxCueClusterPosition*)el;

                                ccpos.ReadData( es.I_O() );
                                idx.i_position = segment->GetGlobalPosition( uint64( ccpos ) );
                            }
                            else if( MKV_IS_ID( el, KaxCueBlockNumber ) )
                            {
                                KaxCueBlockNumber &cbnum = *(KaxCueBlockNumber*)el;

                                cbnum.ReadData( es.I_O() );
                                idx.i_block_number = uint32( cbnum );
                            }
                            else
                            {
                                msg_Dbg( &sys.demuxer, "         * Unknown (%s)", typeid(*el).name() );
                            }
196
197
                        }
                    }
198
199
200
201
202
203
204
                    catch(...)
                    {
                        ep->Up();   
                        msg_Err( &sys.demuxer, "Error while reading %s", typeid(*el).name() );
                        b_invalid_cue = true;
                        break;
                    }
205
206
207
208
209
210
211
212
                    ep->Up();
                }
                else
                {
                    msg_Dbg( &sys.demuxer, "     * Unknown (%s)", typeid(*el).name() );
                }
            }
            ep->Up();
213

214
215
216
217
218
#if 0
            msg_Dbg( &sys.demuxer, " * added time=%"PRId64" pos=%"PRId64
                     " track=%d bnum=%d", idx.i_time, idx.i_position,
                     idx.i_track, idx.i_block_number );
#endif
219
            if( likely( !b_invalid_cue ) )
220
            {
221
222
223
224
225
226
227
                i_index++;
                if( i_index >= i_index_max )
                {
                    i_index_max += 1024;
                    p_indexes = (mkv_index_t*)xrealloc( p_indexes,
                                                        sizeof( mkv_index_t ) * i_index_max );
                }
228
229
            }
#undef idx
230
        }
231
        else
232
        {
233
            msg_Dbg( &sys.demuxer, " * Unknown (%s)", typeid(*el).name() );
234
235
        }
    }
236
237
238
239
    delete ep;
    b_cues = true;
    msg_Dbg( &sys.demuxer, "|   - loading cues done." );
}
240

241

242
243
244
static const struct {
    vlc_meta_type_t type;
    const char *key;
245
    int target_type; /* 0 is valid for all target_type */
246
} metadata_map[] = {
247
                     {vlc_meta_Album,       "TITLE",         50},
248
                     {vlc_meta_Title,       "TITLE",         0},
249
250
251
252
253
254
255
256
                     {vlc_meta_Artist,      "ARTIST",        0},
                     {vlc_meta_Genre,       "GENRE",         0},
                     {vlc_meta_Copyright,   "COPYRIGHT",     0},
                     {vlc_meta_TrackNumber, "PART_NUMBER",   0},
                     {vlc_meta_Description, "DESCRIPTION",   0},
                     {vlc_meta_Description, "COMMENT",       0},
                     {vlc_meta_Rating,      "RATING",        0},
                     {vlc_meta_Date,        "DATE_RELEASED", 0},
257
                     {vlc_meta_Date,        "DATE_RELEASE",  0},
258
                     {vlc_meta_Date,        "DATE_RECORDED", 0},
259
260
261
262
263
                     {vlc_meta_URL,         "URL",           0},
                     {vlc_meta_Publisher,   "PUBLISHER",     0},
                     {vlc_meta_EncodedBy,   "ENCODED_BY",    0},
                     {vlc_meta_TrackTotal,  "TOTAL_PARTS",   0},
                     {vlc_meta_Title,       NULL,            0},
264
265
};

266
SimpleTag * matroska_segment_c::ParseSimpleTags( KaxTagSimple *tag, int target_type )
267
268
269
{
    EbmlElement *el;
    EbmlParser *ep = new EbmlParser( &es, tag, &sys.demuxer );
270
    SimpleTag * p_simple = new SimpleTag;
271
272
    size_t max_size = tag->GetSize();
    size_t size = 0;
273
274
275
276
277
278

    if( !p_simple )
    {
        msg_Err( &sys.demuxer, "Couldn't allocate memory for Simple Tag... ignoring it");
        return NULL;
    }
279
280
281
282
283

    if( !sys.meta )
        sys.meta = vlc_meta_New();

    msg_Dbg( &sys.demuxer, "|   + Simple Tag ");
284
    try
285
    {
286
        while( ( el = ep->Get() ) != NULL && size < max_size)
287
        {
288
289
290
291
292
293
294
            if( unlikely( el->GetSize() >= SIZE_MAX ) )
            {
                msg_Err( &sys.demuxer, "Error %s too big ignoring the tag", typeid(*el).name() );
                delete ep;
                delete p_simple;
                return NULL;
            }
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
            if( MKV_IS_ID( el, KaxTagName ) )
            {
                KaxTagName &key = *(KaxTagName*)el;
                key.ReadData( es.I_O(), SCOPE_ALL_DATA );
                p_simple->psz_tag_name = strdup( UTFstring( key ).GetUTF8().c_str() );
            }
            else if( MKV_IS_ID( el, KaxTagString ) )
            {
                KaxTagString &value = *(KaxTagString*)el;
                value.ReadData( es.I_O(), SCOPE_ALL_DATA );
                p_simple->p_value = strdup( UTFstring( value ).GetUTF8().c_str() );
            }
            else if(  MKV_IS_ID( el, KaxTagLangue ) )
            {
                KaxTagLangue &language = *(KaxTagLangue*) el;
                language.ReadData( es.I_O(), SCOPE_ALL_DATA );
                p_simple->psz_lang = strdup( string( language ).c_str());
            }
            else if(  MKV_IS_ID( el, KaxTagDefault ) )
            {
                KaxTagDefault & dft = *(KaxTagDefault*) el;
                dft.ReadData( es.I_O(), SCOPE_ALL_DATA );
                p_simple->b_default = (bool) uint8( dft );
            }
            /*Tags can be nested*/
            else if( MKV_IS_ID( el, KaxTagSimple) )
            {
                SimpleTag * p_st = ParseSimpleTags( (KaxTagSimple*)el, target_type );
                if( p_st )
                    p_simple->sub_tags.push_back( p_st );
            }
            /*TODO Handle binary tags*/
327
            size += el->HeadSize() + el->GetSize();
328
        }
329
330
331
332
333
334
335
    }
    catch(...)
    {
        msg_Err( &sys.demuxer, "Error while reading Tag ");
        delete ep;
        delete p_simple;
        return NULL;
336
337
338
    }
    delete ep;

339
    if( !p_simple->psz_tag_name || !p_simple->p_value )
340
341
    {
        msg_Warn( &sys.demuxer, "Invalid MKV SimpleTag found.");
342
343
        delete p_simple;
        return NULL;
344
345
346
    }
    for( int i = 0; metadata_map[i].key; i++ )
    {
347
        if( !strcmp( p_simple->psz_tag_name, metadata_map[i].key ) &&
348
            (metadata_map[i].target_type == 0 || target_type == metadata_map[i].target_type ) )
349
        {
350
351
            vlc_meta_Set( sys.meta, metadata_map[i].type, p_simple->p_value );
            msg_Dbg( &sys.demuxer, "|   |   + Meta %s: %s", p_simple->psz_tag_name, p_simple->p_value);
352
353
354
            goto done;
        }
    }
355
356
    msg_Dbg( &sys.demuxer, "|   |   + Meta %s: %s", p_simple->psz_tag_name, p_simple->p_value);
    vlc_meta_AddExtra( sys.meta, p_simple->psz_tag_name, p_simple->p_value);
357
done:
358
    return p_simple;
359
360
}

361
362
#define PARSE_TAG( type ) \
    do { \
363
364
365
366
367
368
369
        msg_Dbg( &sys.demuxer, "|   + " type ); \
        ep->Down();                             \
        while( ( el = ep->Get() ) != NULL )     \
        {                                       \
            msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid( *el ).name() ); \
        }                                      \
        ep->Up(); } while( 0 )
370
371


372
void matroska_segment_c::LoadTags( KaxTags *tags )
373
{
374
    /* Master elements */
375
376
    EbmlParser *ep = new EbmlParser( &es, tags, &sys.demuxer );
    EbmlElement *el;
377

378
    while( ( el = ep->Get() ) != NULL )
379
    {
380
        if( MKV_IS_ID( el, KaxTag ) )
381
        {
382
383
384
385
386
387
            Tag * p_tag = new Tag;
            if(!p_tag)
            {
                msg_Err( &sys.demuxer,"Couldn't allocate memory for tag... ignoring it");
                continue;
            }
388
389
            msg_Dbg( &sys.demuxer, "+ Tag" );
            ep->Down();
390
            int target_type = 50;
391
            while( ( el = ep->Get() ) != NULL )
392
            {
393
                if( MKV_IS_ID( el, KaxTagTargets ) )
394
395
396
397
398
                {
                    msg_Dbg( &sys.demuxer, "|   + Targets" );
                    ep->Down();
                    while( ( el = ep->Get() ) != NULL )
                    {
399
                        try
400
                        {
401
402
403
404
405
                            if( unlikely( el->GetSize() >= SIZE_MAX ) )
                            {
                                msg_Err( &sys.demuxer, "Invalid size while reading tag");
                                break;
                            }
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
                            if( MKV_IS_ID( el, KaxTagTargetTypeValue ) )
                            {
                                KaxTagTargetTypeValue &value = *(KaxTagTargetTypeValue*)el;
                                value.ReadData( es.I_O() );

                                msg_Dbg( &sys.demuxer, "|   |   + TargetTypeValue: %u", uint32(value));
                                target_type = uint32(value);
                            }
                            if( MKV_IS_ID( el, KaxTagTrackUID ) )
                            {
                                p_tag->i_tag_type = TRACK_UID;
                                KaxTagTrackUID &uid = *(KaxTagTrackUID*) el;
                                uid.ReadData( es.I_O() );
                                p_tag->i_uid = uint64( uid );
                                msg_Dbg( &sys.demuxer, "|   |   + TrackUID: %"PRIu64, p_tag->i_uid);

                            }
                            if( MKV_IS_ID( el, KaxTagEditionUID ) )
                            {
                                p_tag->i_tag_type = EDITION_UID;
                                KaxTagEditionUID &uid = *(KaxTagEditionUID*) el;
                                uid.ReadData( es.I_O() );
                                p_tag->i_uid = uint64( uid );
                                msg_Dbg( &sys.demuxer, "|   |   + EditionUID: %"PRIu64, p_tag->i_uid);
                            }
                            if( MKV_IS_ID( el, KaxTagChapterUID ) )
                            {
                                p_tag->i_tag_type = CHAPTER_UID;
                                KaxTagChapterUID &uid = *(KaxTagChapterUID*) el;
                                uid.ReadData( es.I_O() );
                                p_tag->i_uid = uint64( uid );
                                msg_Dbg( &sys.demuxer, "|   |   + ChapterUID: %"PRIu64, p_tag->i_uid);
                            }
                            if( MKV_IS_ID( el, KaxTagAttachmentUID ) )
                            {
                                p_tag->i_tag_type = ATTACHMENT_UID;
                                KaxTagAttachmentUID &uid = *(KaxTagAttachmentUID*) el;
                                uid.ReadData( es.I_O() );
                                p_tag->i_uid = uint64( uid );
                                msg_Dbg( &sys.demuxer, "|   |   + AttachmentUID: %"PRIu64, p_tag->i_uid);
                            }
447
                        }
448
                        catch(...)
449
                        {
450
451
                            msg_Err( &sys.demuxer, "Error while reading tag");
                            break;
452
                        }
453
                    }
454
                    ep->Up();
455
456
                }
                else if( MKV_IS_ID( el, KaxTagSimple ) )
457
458
459
460
461
462
463
                {
                    SimpleTag * p_simple =
                        ParseSimpleTags( static_cast<KaxTagSimple*>( el ),
                                         target_type );
                    if( p_simple )
                        p_tag->simple_tags.push_back( p_simple );
                }
464
#if 0 // not valid anymore
465
                else if( MKV_IS_ID( el, KaxTagGeneral ) )
466
                    PARSE_TAG( "General" );
467
                else if( MKV_IS_ID( el, KaxTagGenres ) )
468
                    PARSE_TAG( "Genres" );
469
                else if( MKV_IS_ID( el, KaxTagAudioSpecific ) )
470
                    PARSE_TAG( "Audio Specific" );
471
                else if( MKV_IS_ID( el, KaxTagImageSpecific ) )
472
                    PARSE_TAG( "Images Specific" );
473
                else if( MKV_IS_ID( el, KaxTagMultiComment ) )
474
                {
475
476
477
                    msg_Dbg( &sys.demuxer, "|   + Multi Comment" );
                }
                else if( MKV_IS_ID( el, KaxTagMultiCommercial ) )
478
                {
479
                    msg_Dbg( &sys.demuxer, "|   + Multi Commercial" );
480
                }
481
                else if( MKV_IS_ID( el, KaxTagMultiDate ) )
482
                {
483
                    msg_Dbg( &sys.demuxer, "|   + Multi Date" );
484
                }
485
                else if( MKV_IS_ID( el, KaxTagMultiEntity ) )
486
                {
487
                    msg_Dbg( &sys.demuxer, "|   + Multi Entity" );
488
                }
489
                else if( MKV_IS_ID( el, KaxTagMultiIdentifier ) )
490
                {
491
                    msg_Dbg( &sys.demuxer, "|   + Multi Identifier" );
492
                }
493
                else if( MKV_IS_ID( el, KaxTagMultiLegal ) )
494
                {
495
                    msg_Dbg( &sys.demuxer, "|   + Multi Legal" );
496
                }
497
                else if( MKV_IS_ID( el, KaxTagMultiTitle ) )
498
                {
499
                    msg_Dbg( &sys.demuxer, "|   + Multi Title" );
500
                }
501
#endif
502
503
                else
                {
504
                    msg_Dbg( &sys.demuxer, "|   + LoadTag Unknown (%s)", typeid( *el ).name() );
505
506
                }
            }
507
            ep->Up();
508
            this->tags.push_back(p_tag);
509
510
511
        }
        else
        {
512
            msg_Dbg( &sys.demuxer, "+ Unknown (%s)", typeid( *el ).name() );
513
514
        }
    }
515
    delete ep;
516

517
    msg_Dbg( &sys.demuxer, "loading tags done." );
518
}
519
#undef PARSE_TAG
520
521
522
523
524
525

/*****************************************************************************
 * InformationCreate:
 *****************************************************************************/
void matroska_segment_c::InformationCreate( )
{
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
526
527
    if( !sys.meta )
        sys.meta = vlc_meta_New();
528

529
530
531
    if( psz_title )
    {
        vlc_meta_SetTitle( sys.meta, psz_title );
532
    }
533
#if 0
534
    if( psz_date_utc )
535
    {
536
537
        vlc_meta_SetDate( sys.meta, psz_date_utc );
    }
538

539
540
541
542
543
544
545
546
547
548
549
    if( psz_segment_filename )
    {
        fprintf( stderr, "***** WARNING: Unhandled meta - Use custom\n" );
    }
    if( psz_muxing_application )
    {
        fprintf( stderr, "***** WARNING: Unhandled meta - Use custom\n" );
    }
    if( psz_writing_application )
    {
        fprintf( stderr, "***** WARNING: Unhandled meta - Use custom\n" );
550
551
    }

552
553
554
555
556
557
558
559
560
561
562
    for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
    {
//        mkv_track_t *tk = tracks[i_track];
//        vlc_meta_t *mtk = vlc_meta_New();
        fprintf( stderr, "***** WARNING: Unhandled child meta\n");
    }
#endif
#if 0
    if( i_tags_position >= 0 )
    {
        bool b_seekable;
563

564
565
        stream_Control( sys.demuxer.s, STREAM_CAN_FASTSEEK, &b_seekable );
        if( b_seekable )
566
        {
567
            LoadTags( );
568
        }
569
570
571
    }
#endif
}
572
573


574
575
576
/*****************************************************************************
 * Misc
 *****************************************************************************/
577

578
void matroska_segment_c::IndexAppendCluster( KaxCluster *cluster )
579
{
580
581
582
583
#define idx p_indexes[i_index]
    idx.i_track       = -1;
    idx.i_block_number= -1;
    idx.i_position    = cluster->GetElementPosition();
Denis Charmet's avatar
Denis Charmet committed
584
    idx.i_time        = cluster->GlobalTimecode()/ (mtime_t) 1000;
585
    idx.b_key         = true;
586

587
588
589
590
    i_index++;
    if( i_index >= i_index_max )
    {
        i_index_max += 1024;
591
        p_indexes = (mkv_index_t*)xrealloc( p_indexes,
592
                                        sizeof( mkv_index_t ) * i_index_max );
593
    }
594
#undef idx
595
596
}

597
bool matroska_segment_c::PreloadFamily( const matroska_segment_c & of_segment )
598
{
599
600
    if ( b_preloaded )
        return false;
601

602
    for (size_t i=0; i<families.size(); i++)
603
    {
604
        for (size_t j=0; j<of_segment.families.size(); j++)
605
        {
606
607
            if ( *(families[i]) == *(of_segment.families[j]) )
                return Preload( );
608
609
        }
    }
610
611

    return false;
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
}

bool matroska_segment_c::CompareSegmentUIDs( const matroska_segment_c * p_item_a, const matroska_segment_c * p_item_b )
{
    EbmlBinary *p_tmp;

    if ( p_item_a == NULL || p_item_b == NULL )
        return false;

    p_tmp = (EbmlBinary *)p_item_a->p_segment_uid;
    if ( p_item_b->p_prev_segment_uid != NULL
          && *p_tmp == *p_item_b->p_prev_segment_uid )
        return true;

    p_tmp = (EbmlBinary *)p_item_a->p_next_segment_uid;
    if ( !p_tmp )
        return false;
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
629

630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
    if ( p_item_b->p_segment_uid != NULL
          && *p_tmp == *p_item_b->p_segment_uid )
        return true;

    if ( p_item_b->p_prev_segment_uid != NULL
          && *p_tmp == *p_item_b->p_prev_segment_uid )
        return true;

    return false;
}

bool matroska_segment_c::Preload( )
{
    if ( b_preloaded )
        return false;

    EbmlElement *el = NULL;

    ep->Reset( &sys.demuxer );

    while( ( el = ep->Get() ) != NULL )
    {
        if( MKV_IS_ID( el, KaxSeekHead ) )
        {
            /* Multiple allowed */
            /* We bail at 10, to prevent possible recursion */
            msg_Dbg(  &sys.demuxer, "|   + Seek head" );
            if( i_seekhead_count < 10 )
            {
                i_seekhead_position = (int64_t) es.I_O().getFilePointer();
                ParseSeekHead( static_cast<KaxSeekHead*>( el ) );
            }
        }
        else if( MKV_IS_ID( el, KaxInfo ) )
        {
            /* Multiple allowed, mandatory */
            msg_Dbg(  &sys.demuxer, "|   + Information" );
            if( i_info_position < 0 ) // FIXME
                ParseInfo( static_cast<KaxInfo*>( el ) );
            i_info_position = (int64_t) es.I_O().getFilePointer();
        }
        else if( MKV_IS_ID( el, KaxTracks ) )
        {
            /* Multiple allowed */
            msg_Dbg(  &sys.demuxer, "|   + Tracks" );
            if( i_tracks_position < 0 ) // FIXME
                ParseTracks( static_cast<KaxTracks*>( el ) );
            if ( tracks.size() == 0 )
            {
                msg_Err( &sys.demuxer, "No tracks supported" );
                return false;
            }
            i_tracks_position = (int64_t) es.I_O().getFilePointer();
        }
        else if( MKV_IS_ID( el, KaxCues ) )
        {
            msg_Dbg(  &sys.demuxer, "|   + Cues" );
            if( i_cues_position < 0 )
                LoadCues( static_cast<KaxCues*>( el ) );
            i_cues_position = (int64_t) es.I_O().getFilePointer();
        }
        else if( MKV_IS_ID( el, KaxCluster ) )
        {
            msg_Dbg( &sys.demuxer, "|   + Cluster" );

            cluster = (KaxCluster*)el;

            i_cluster_pos = i_start_pos = cluster->GetElementPosition();
            ParseCluster( );

            ep->Down();
            /* stop pre-parsing the stream */
            break;
        }
        else if( MKV_IS_ID( el, KaxAttachments ) )
        {
            msg_Dbg( &sys.demuxer, "|   + Attachments" );
            if( i_attachments_position < 0 )
                ParseAttachments( static_cast<KaxAttachments*>( el ) );
            i_attachments_position = (int64_t) es.I_O().getFilePointer();
        }
        else if( MKV_IS_ID( el, KaxChapters ) )
        {
            msg_Dbg( &sys.demuxer, "|   + Chapters" );
            if( i_chapters_position < 0 )
                ParseChapters( static_cast<KaxChapters*>( el ) );
            i_chapters_position = (int64_t) es.I_O().getFilePointer();
        }
        else if( MKV_IS_ID( el, KaxTag ) )
        {
            msg_Dbg( &sys.demuxer, "|   + Tags" );
721
722
            /*FIXME if( i_tags_position < 0)
                LoadTags( static_cast<KaxTags*>( el ) );*/
723
724
            i_tags_position = (int64_t) es.I_O().getFilePointer();
        }
725
726
        else if( MKV_IS_ID( el, EbmlVoid ) )
            msg_Dbg( &sys.demuxer, "|   + Void" );
727
728
729
730
        else
            msg_Dbg( &sys.demuxer, "|   + Preload Unknown (%s)", typeid(*el).name() );
    }

731
732
    ComputeTrackPriority();

733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
    b_preloaded = true;

    return true;
}

/* Here we try to load elements that were found in Seek Heads, but not yet parsed */
bool matroska_segment_c::LoadSeekHeadItem( const EbmlCallbacks & ClassInfos, int64_t i_element_position )
{
    int64_t     i_sav_position = (int64_t)es.I_O().getFilePointer();
    EbmlElement *el;

    es.I_O().setFilePointer( i_element_position, seek_beginning );
    el = es.FindNextID( ClassInfos, 0xFFFFFFFFL);

    if( el == NULL )
    {
        msg_Err( &sys.demuxer, "cannot load some cues/chapters/tags etc. (broken seekhead or file)" );
        es.I_O().setFilePointer( i_sav_position, seek_beginning );
        return false;
    }

    if( MKV_IS_ID( el, KaxSeekHead ) )
    {
        /* Multiple allowed */
        msg_Dbg( &sys.demuxer, "|   + Seek head" );
        if( i_seekhead_count < 10 )
        {
            i_seekhead_position = i_element_position;
            ParseSeekHead( static_cast<KaxSeekHead*>( el ) );
        }
    }
    else if( MKV_IS_ID( el, KaxInfo ) ) // FIXME
    {
        /* Multiple allowed, mandatory */
        msg_Dbg( &sys.demuxer, "|   + Information" );
        if( i_info_position < 0 )
            ParseInfo( static_cast<KaxInfo*>( el ) );
        i_info_position = i_element_position;
    }
    else if( MKV_IS_ID( el, KaxTracks ) ) // FIXME
    {
        /* Multiple allowed */
        msg_Dbg( &sys.demuxer, "|   + Tracks" );
        if( i_tracks_position < 0 )
            ParseTracks( static_cast<KaxTracks*>( el ) );
        if ( tracks.size() == 0 )
        {
            msg_Err( &sys.demuxer, "No tracks supported" );
            delete el;
            es.I_O().setFilePointer( i_sav_position, seek_beginning );
            return false;
        }
        i_tracks_position = i_element_position;
    }
    else if( MKV_IS_ID( el, KaxCues ) )
    {
        msg_Dbg( &sys.demuxer, "|   + Cues" );
        if( i_cues_position < 0 )
            LoadCues( static_cast<KaxCues*>( el ) );
        i_cues_position = i_element_position;
    }
    else if( MKV_IS_ID( el, KaxAttachments ) )
    {
        msg_Dbg( &sys.demuxer, "|   + Attachments" );
        if( i_attachments_position < 0 )
            ParseAttachments( static_cast<KaxAttachments*>( el ) );
        i_attachments_position = i_element_position;
    }
    else if( MKV_IS_ID( el, KaxChapters ) )
    {
        msg_Dbg( &sys.demuxer, "|   + Chapters" );
        if( i_chapters_position < 0 )
            ParseChapters( static_cast<KaxChapters*>( el ) );
        i_chapters_position = i_element_position;
    }
808
    else if( MKV_IS_ID( el, KaxTags ) )
809
810
811
    {
        msg_Dbg( &sys.demuxer, "|   + Tags" );
        if( i_tags_position < 0 )
812
            LoadTags( static_cast<KaxTags*>( el ) );
813
814
815
816
817
818
819
820
821
822
823
824
        i_tags_position = i_element_position;
    }
    else
    {
        msg_Dbg( &sys.demuxer, "|   + LoadSeekHeadItem Unknown (%s)", typeid(*el).name() );
    }
    delete el;

    es.I_O().setFilePointer( i_sav_position, seek_beginning );
    return true;
}

Denis Charmet's avatar
Denis Charmet committed
825
826
struct spoint
{
Denis Charmet's avatar
Denis Charmet committed
827
828
829
    spoint(unsigned int tk, mtime_t date, int64_t pos, int64_t cpos):
        i_track(tk),i_date(date), i_seek_pos(pos),
        i_cluster_pos(cpos), p_next(NULL){}
Denis Charmet's avatar
Denis Charmet committed
830
831
832
833
834
835
836
    unsigned int     i_track;
    mtime_t i_date;
    int64_t i_seek_pos;
    int64_t i_cluster_pos;
    spoint * p_next;
};

837
838
839
840
841
842
843
844
void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_global_position )
{
    KaxBlock    *block;
    KaxSimpleBlock *simpleblock;
    int64_t     i_block_duration;
    size_t      i_track;
    int64_t     i_seek_position = i_start_pos;
    int64_t     i_seek_time = i_start_time;
Denis Charmet's avatar
Denis Charmet committed
845
846
847
    mtime_t     i_pts = 0;
    spoint *p_first = NULL;
    spoint *p_last = NULL;
Denis Charmet's avatar
Denis Charmet committed
848
    int i_cat;
849
    bool b_has_key = false;
850

Denis Charmet's avatar
Denis Charmet committed
851
852
853
    for( size_t i = 0; i < tracks.size(); i++)
        tracks[i]->i_last_dts = VLC_TS_INVALID;

854
855
856
857
    if( i_global_position >= 0 )
    {
        /* Special case for seeking in files with no cues */
        EbmlElement *el = NULL;
Denis Charmet's avatar
Denis Charmet committed
858
859
860
861
862
863
864

        /* Start from the last known index instead of the beginning eachtime */
        if( i_index == 0)
            es.I_O().setFilePointer( i_start_pos, seek_beginning );
        else
            es.I_O().setFilePointer( p_indexes[ i_index - 1 ].i_position,
                                     seek_beginning );
865
866
867
868
869
870
871
872
873
874
875
        delete ep;
        ep = new EbmlParser( &es, segment, &sys.demuxer );
        cluster = NULL;

        while( ( el = ep->Get() ) != NULL )
        {
            if( MKV_IS_ID( el, KaxCluster ) )
            {
                cluster = (KaxCluster *)el;
                i_cluster_pos = cluster->GetElementPosition();
                if( i_index == 0 ||
Denis Charmet's avatar
Denis Charmet committed
876
877
                    ( i_index > 0 &&
                      p_indexes[i_index - 1].i_position < (int64_t)cluster->GetElementPosition() ) )
878
                {
879
                    ParseCluster(false);
880
881
                    IndexAppendCluster( cluster );
                }
Denis Charmet's avatar
Denis Charmet committed
882
                if( es.I_O().getFilePointer() >= (unsigned) i_global_position )
Denis Charmet's avatar
Denis Charmet committed
883
                    break;
884
885
886
887
            }
        }
    }

Denis Charmet's avatar
Denis Charmet committed
888
    /* Don't try complex seek if we seek to 0 */
889
    if( i_date == 0 && i_time_offset == 0 )
Denis Charmet's avatar
Denis Charmet committed
890
    {
891
        es_out_Control( sys.demuxer.out, ES_OUT_SET_PCR, VLC_TS_0 );
892
893
        es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME,
                        INT64_C(0) );
Denis Charmet's avatar
Denis Charmet committed
894
895
896
897
898
        es.I_O().setFilePointer( i_start_pos );

        delete ep;
        ep = new EbmlParser( &es, segment, &sys.demuxer );
        cluster = NULL;
899
900
        sys.i_start_pts = 0;
        sys.i_pts = 0;
901
        sys.i_pcr = 0;
902
        return;
Denis Charmet's avatar
Denis Charmet committed
903
904
    }

905
    int i_idx = 0;
906
907
908
909
910
911
912
913
914
915
916
917
918
919
    if ( i_index > 0 )
    {

        for( ; i_idx < i_index; i_idx++ )
            if( p_indexes[i_idx].i_time + i_time_offset > i_date )
                break;

        if( i_idx > 0 )
            i_idx--;

        i_seek_position = p_indexes[i_idx].i_position;
        i_seek_time = p_indexes[i_idx].i_time;
    }

920
    msg_Dbg( &sys.demuxer, "seek got %"PRId64" - %"PRId64, i_seek_time, i_seek_position );
921
922
923
924
925
926
927
928
929
930

    es.I_O().setFilePointer( i_seek_position, seek_beginning );

    delete ep;
    ep = new EbmlParser( &es, segment, &sys.demuxer );
    cluster = NULL;

    sys.i_start_pts = i_date;

    /* now parse until key frame */
931
932
    const int es_types[3] = { VIDEO_ES, AUDIO_ES, SPU_ES };
    i_cat = es_types[0];
933
    mtime_t i_seek_preroll = 0;
934
    for( int i = 0; i < 2; i_cat = es_types[++i] )
935
    {
Denis Charmet's avatar
Denis Charmet committed
936
        for( i_track = 0; i_track < tracks.size(); i_track++ )
937
        {
938
939
            if( tracks[i_track]->i_seek_preroll )
            {
940
                bool b_enabled;
941
942
943
                if( es_out_Control( sys.demuxer.out,
                                    ES_OUT_GET_ES_STATE,
                                    tracks[i_track]->p_es,
944
                                    &b_enabled ) == VLC_SUCCESS &&
945
946
947
948
                    b_enabled )
                    i_seek_preroll = __MAX( i_seek_preroll,
                                            tracks[i_track]->i_seek_preroll );
            }
Denis Charmet's avatar
Denis Charmet committed
949
            if( tracks[i_track]->fmt.i_cat == i_cat )
Denis Charmet's avatar
Denis Charmet committed
950
            {
Denis Charmet's avatar
Denis Charmet committed
951
952
                spoint * seekpoint = new spoint(i_track, i_seek_time, i_seek_position, i_seek_position);
                if( unlikely( !seekpoint ) )
Denis Charmet's avatar
Denis Charmet committed
953
                {
Denis Charmet's avatar
Denis Charmet committed
954
955
956
957
                    for( spoint * sp = p_first; sp; )
                    {
                        spoint * tmp = sp;
                        sp = sp->p_next;
958
                        delete tmp;
Denis Charmet's avatar
Denis Charmet committed
959
960
961
962
963
964
965
966
967
968
969
970
                    }
                    return;
                }
                if( unlikely( !p_first ) )
                {
                    p_first = seekpoint;
                    p_last = seekpoint;
                }
                else
                {
                    p_last->p_next = seekpoint;
                    p_last = seekpoint;
Denis Charmet's avatar
Denis Charmet committed
971
972
                }
            }
973
        }
Denis Charmet's avatar
Denis Charmet committed
974
975
        if( likely( p_first ) )
            break;
976
    }
Denis Charmet's avatar
Denis Charmet committed
977
978
    /*Neither video nor audio track... no seek further*/
    if( unlikely( !p_first ) )
979
980
981
    {
        es_out_Control( sys.demuxer.out, ES_OUT_SET_PCR, i_date );
        es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_date );
982
        return;
983
    }
984
    i_date -= i_seek_preroll;
985
    for(;;)
986
    {
987
        do
988
        {
989
990
991
992
993
            bool b_key_picture;
            bool b_discardable_picture;
            if( BlockGet( block, simpleblock, &b_key_picture, &b_discardable_picture, &i_block_duration ) )
            {
                msg_Warn( &sys.demuxer, "cannot get block EOF?" );
François Cartegnie's avatar
François Cartegnie committed
994
995
996
997
998
999
                while( p_first )
                {
                    spoint *tmp = p_first;
                    p_first = p_first->p_next;
                    delete tmp;
                }
1000
1001
                return;
            }
1002

1003
1004
1005
1006
1007
1008
1009
            /* check if block's track is in our list */
            for( i_track = 0; i_track < tracks.size(); i_track++ )
            {
                if( (simpleblock && tracks[i_track]->i_number == simpleblock->TrackNum()) ||
                    (block && tracks[i_track]->i_number == block->TrackNum()) )
                    break;
            }
1010

1011
1012
1013
1014
1015
            if( simpleblock )
                i_pts = sys.i_chapter_time + simpleblock->GlobalTimecode() / (mtime_t) 1000;
            else
                i_pts = sys.i_chapter_time + block->GlobalTimecode() / (mtime_t) 1000;
            if( i_track < tracks.size() )
1016
            {
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
                if( tracks[i_track]->fmt.i_cat == i_cat && b_key_picture )
                {
                    /* get the seekpoint */
                    spoint * sp;
                    for( sp =  p_first; sp; sp = sp->p_next )
                        if( sp->i_track == i_track )
                            break;

                    sp->i_date = i_pts;
                    if( simpleblock )
                        sp->i_seek_pos = simpleblock->GetElementPosition();
                    else
                        sp->i_seek_pos = i_block_pos;
                    sp->i_cluster_pos = i_cluster_pos;
                    b_has_key = true;
                }
1033
            }
1034
1035

            delete block;
1036
        } while( i_pts < i_date );
1037
1038
        if( b_has_key || !i_idx )
            break;
1039

1040
1041
1042
1043
1044
1045
1046
1047
        /* No key picture was found in the cluster seek to previous seekpoint */
        i_date = i_time_offset + p_indexes[i_idx].i_time;
        i_idx--;
        i_pts = 0;
        es.I_O().setFilePointer( p_indexes[i_idx].i_position );
        delete ep;
        ep = new EbmlParser( &es, segment, &sys.demuxer );
        cluster = NULL;
1048
1049
    }

Denis Charmet's avatar
Denis Charmet committed
1050
1051
1052
1053
1054
1055
    /* rewind to the last I img */
    spoint * p_min;
    for( p_min  = p_first, p_last = p_first; p_last; p_last = p_last->p_next )
        if( p_last->i_date < p_min->i_date )
            p_min = p_last;

1056
1057
    sys.i_pcr = sys.i_pts = p_min->i_date;
    es_out_Control( sys.demuxer.out, ES_OUT_SET_PCR, VLC_TS_0 + sys.i_pcr );
1058
    es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_date );
Denis Charmet's avatar
Denis Charmet committed
1059
1060
1061
1062
    cluster = (KaxCluster *) ep->UnGet( p_min->i_seek_pos, p_min->i_cluster_pos );

    /* hack use BlockGet to get the cluster then goto the wanted block */
    if ( !cluster )
1063
    {
Denis Charmet's avatar
Denis Charmet committed
1064
1065
1066
1067
1068
1069
        bool b_key_picture;
        bool b_discardable_picture;
        BlockGet( block, simpleblock, &b_key_picture, &b_discardable_picture, &i_block_duration );
        delete block;
        cluster = (KaxCluster *) ep->UnGet( p_min->i_seek_pos, p_min->i_cluster_pos );
    }
1070

Denis Charmet's avatar
Denis Charmet committed
1071
1072
1073
1074
1075
    while( p_first )
    {
        p_min = p_first;
        p_first = p_first->p_next;
        delete p_min;
1076
1077
1078
    }
}

1079
1080
int matroska_segment_c::BlockFindTrackIndex( size_t *pi_track,
                                             const KaxBlock *p_block, const KaxSimpleBlock *p_simpleblock )
1081
{
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
1082
    size_t i_track;
1083
    for( i_track = 0; i_track < tracks.size(); i_track++ )
1084
    {
1085
        const mkv_track_t *tk = tracks[i_track];
1086

1087
1088
        if( ( p_block != NULL && tk->i_number == p_block->TrackNum() ) ||
            ( p_simpleblock != NULL && tk->i_number == p_simpleblock->TrackNum() ) )
1089
1090
1091
1092
1093
        {
            break;
        }
    }

1094
1095
    if( i_track >= tracks.size() )
        return VLC_EGENERIC;
1096

1097
1098
1099
    if( pi_track )
        *pi_track = i_track;
    return VLC_SUCCESS;
1100
1101
}

1102
void matroska_segment_c::ComputeTrackPriority()
1103
{
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
    bool b_has_default_video = false;
    bool b_has_default_audio = false;
    /* check for default */
    for(size_t i_track = 0; i_track < tracks.size(); i_track++)
    {
        mkv_track_t *p_tk = tracks[i_track];
        es_format_t *p_fmt = &p_tk->fmt;
        if( p_fmt->i_cat == VIDEO_ES )
            b_has_default_video |=
                p_tk->b_enabled && ( p_tk->b_default || p_tk->b_forced );
        else if( p_fmt->i_cat == AUDIO_ES )
            b_has_default_audio |=
                p_tk->b_enabled && ( p_tk->b_default || p_tk->b_forced );
    }

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
1119
    for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
1120
    {
1121
1122
1123
        mkv_track_t *p_tk = tracks[i_track];
        es_format_t *p_fmt = &p_tk->fmt;

1124
        if( unlikely( p_fmt->i_cat == UNKNOWN_ES || !p_tk->psz_codec ) )
1125
        {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
1126
1127
            msg_Warn( &sys.demuxer, "invalid track[%d, n=%d]", (int)i_track, p_tk->i_number );
            p_tk->p_es = NULL;
1128
            continue;
1129
        }
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
        else if( unlikely( !b_has_default_video && p_fmt->i_cat == VIDEO_ES ) )
        {
            p_tk->b_default = true;
            b_has_default_video = true;
        }
        else if( unlikely( !b_has_default_audio &&  p_fmt->i_cat == AUDIO_ES ) )
        {
            p_tk->b_default = true;
            b_has_default_audio = true;
        }
        if( unlikely( !p_tk->b_enabled ) )
1141
            p_tk->fmt.i_priority = ES_PRIORITY_NOT_SELECTABLE;
1142
        else if( p_tk->b_forced )
1143
            p_tk->fmt.i_priority = ES_PRIORITY_SELECTABLE_MIN + 2;
1144
        else if( p_tk->b_default )
1145
            p_tk->fmt.i_priority = ES_PRIORITY_SELECTABLE_MIN + 1;
1146
        else
1147
            p_tk->fmt.i_priority = ES_PRIORITY_SELECTABLE_MIN;
1148
1149
1150
1151

        /* Avoid multivideo tracks when unnecessary */
        if( p_tk->fmt.i_cat == VIDEO_ES )
            p_tk->fmt.i_priority--;
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
    } 
}

bool matroska_segment_c::Select( mtime_t i_start_time )
{
    /* add all es */
    msg_Dbg( &sys.demuxer, "found %d es", (int)tracks.size() );

    for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
    {
        mkv_track_t *p_tk = tracks[i_track];
        es_format_t *p_fmt = &p_tk->fmt;

        if( unlikely( p_fmt->i_cat == UNKNOWN_ES || !p_tk->psz_codec ) )
        {
            msg_Warn( &sys.demuxer, "invalid track[%d, n=%d]", (int)i_track, p_tk->i_number );
            p_tk->p_es = NULL;
            continue;
        }
1171

1172
1173
        if( !p_tk->p_es )
            p_tk->p_es = es_out_Add( sys.demuxer.out, &p_tk->fmt );
1174

1175
1176
1177
1178
1179
        /* Turn on a subtitles track if it has been flagged as default -
         * but only do this if no subtitles track has already been engaged,
         * either by an earlier 'default track' (??) or by default
         * language choice behaviour.
         */
1180
        if( p_tk->b_default || p_tk->b_forced )
1181
1182
        {
            es_out_Control( sys.demuxer.out,
1183
                            ES_OUT_SET_ES_DEFAULT,
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
1184
                            p_tk->p_es );
1185
1186
        }
    }
1187
    es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_start_time );
1188

1189
1190
1191
    sys.i_start_pts = i_start_time;
    // reset the stream reading to the first cluster of the segment used
    es.I_O().setFilePointer( i_start_pos );
1192

1193
1194
    delete ep;
    ep = new EbmlParser( &es, segment, &sys.demuxer );
1195

1196
    return true;
1197
1198
}

1199
void matroska_segment_c::UnSelect( )
1200
{
1201
    sys.p_ev->ResetPci();
1202
    for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
1203
    {
1204
        if ( tracks[i_track]->p_es != NULL )
1205
        {