]> git.sesse.net Git - vlc/blob - modules/demux/mkv/matroska_segment_parse.cpp
MKV: remove unused i_time_offset variable when seeking
[vlc] / modules / demux / mkv / matroska_segment_parse.cpp
1 /*****************************************************************************
2  * matroska_segment_parse.cpp : matroska demuxer
3  *****************************************************************************
4  * Copyright (C) 2003-2010 VLC authors and VideoLAN
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 it
11  * under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program; if not, write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24 #include "mkv.hpp"
25 #include "matroska_segment.hpp"
26 #include "chapters.hpp"
27 #include "demux.hpp"
28 #include "Ebml_parser.hpp"
29 #include "util.hpp"
30
31 extern "C" {
32 #include "../vobsub.h"
33 #include "../xiph.h"
34 #include "../windows_audio_commons.h"
35 #include "../mp4/libmp4.h"
36 }
37
38 #include <vlc_codecs.h>
39
40 /* GetFourCC helper */
41 #define GetFOURCC( p )  __GetFOURCC( (uint8_t*)p )
42 static vlc_fourcc_t __GetFOURCC( uint8_t *p )
43 {
44     return VLC_FOURCC( p[0], p[1], p[2], p[3] );
45 }
46
47 static inline void fill_extra_data( mkv_track_t *p_tk, unsigned int offset )
48 {
49     if(p_tk->i_extra_data <= offset) return;
50     p_tk->fmt.i_extra = p_tk->i_extra_data - offset;
51     p_tk->fmt.p_extra = xmalloc( p_tk->fmt.i_extra );
52     if(!p_tk->fmt.p_extra) { p_tk->fmt.i_extra = 0; return; };
53     memcpy( p_tk->fmt.p_extra, p_tk->p_extra_data + offset, p_tk->fmt.i_extra );
54 }
55
56 /*****************************************************************************
57  * Some functions to manipulate memory
58  *****************************************************************************/
59 static inline char * ToUTF8( const UTFstring &u )
60 {
61     return strdup( u.GetUTF8().c_str() );
62 }
63
64 /*****************************************************************************
65  * ParseSeekHead:
66  *****************************************************************************/
67 void matroska_segment_c::ParseSeekHead( KaxSeekHead *seekhead )
68 {
69     EbmlParser  *ep;
70     EbmlElement *l;
71     bool b_seekable;
72
73     i_seekhead_count++;
74
75     stream_Control( sys.demuxer.s, STREAM_CAN_SEEK, &b_seekable );
76     if( !b_seekable )
77         return;
78
79     ep = new EbmlParser( &es, seekhead, &sys.demuxer,
80                          var_InheritBool( &sys.demuxer, "mkv-use-dummy" ) );
81
82     while( ( l = ep->Get() ) != NULL )
83     {
84         if( MKV_IS_ID( l, KaxSeek ) )
85         {
86             EbmlId id = EBML_ID(EbmlVoid);
87             int64_t i_pos = -1;
88
89 #ifdef MKV_DEBUG
90             msg_Dbg( &sys.demuxer, "|   |   + Seek" );
91 #endif
92             ep->Down();
93             try
94             {
95                 while( ( l = ep->Get() ) != NULL )
96                 {
97                     if( unlikely( !l->ValidateSize() ) )
98                     {
99                         msg_Err( &sys.demuxer,"%s too big... skipping it",  typeid(*l).name() );
100                         continue;
101                     }
102                     if( MKV_IS_ID( l, KaxSeekID ) )
103                     {
104                         KaxSeekID &sid = *(KaxSeekID*)l;
105                         sid.ReadData( es.I_O() );
106                         id = EbmlId( sid.GetBuffer(), sid.GetSize() );
107                     }
108                     else if( MKV_IS_ID( l, KaxSeekPosition ) )
109                     {
110                         KaxSeekPosition &spos = *(KaxSeekPosition*)l;
111                         spos.ReadData( es.I_O() );
112                         i_pos = (int64_t)segment->GetGlobalPosition( uint64( spos ) );
113                     }
114                     else if ( !MKV_IS_ID( l, EbmlVoid ) && !MKV_IS_ID( l, EbmlCrc32 ))
115                     {
116                         /* Many mkvmerge files hit this case. It seems to be a broken SeekHead */
117                         msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid(*l).name() );
118                     }
119                 }
120             }
121             catch(...)
122             {
123                 msg_Err( &sys.demuxer,"Error while reading %s",  typeid(*l).name() );
124             }
125             ep->Up();
126
127             if( i_pos >= 0 )
128             {
129                 if( id == EBML_ID(KaxCues) )
130                 {
131                     msg_Dbg( &sys.demuxer, "|   - cues at %" PRId64, i_pos );
132                     LoadSeekHeadItem( EBML_INFO(KaxCues), i_pos );
133                 }
134                 else if( id == EBML_ID(KaxInfo) )
135                 {
136                     msg_Dbg( &sys.demuxer, "|   - info at %" PRId64, i_pos );
137                     LoadSeekHeadItem( EBML_INFO(KaxInfo), i_pos );
138                 }
139                 else if( id == EBML_ID(KaxChapters) )
140                 {
141                     msg_Dbg( &sys.demuxer, "|   - chapters at %" PRId64, i_pos );
142                     LoadSeekHeadItem( EBML_INFO(KaxChapters), i_pos );
143                 }
144                 else if( id == EBML_ID(KaxTags) )
145                 {
146                     msg_Dbg( &sys.demuxer, "|   - tags at %" PRId64, i_pos );
147                     LoadSeekHeadItem( EBML_INFO(KaxTags), i_pos );
148                 }
149                 else if( id == EBML_ID(KaxSeekHead) )
150                 {
151                     msg_Dbg( &sys.demuxer, "|   - chained seekhead at %" PRId64, i_pos );
152                     LoadSeekHeadItem( EBML_INFO(KaxSeekHead), i_pos );
153                 }
154                 else if( id == EBML_ID(KaxTracks) )
155                 {
156                     msg_Dbg( &sys.demuxer, "|   - tracks at %" PRId64, i_pos );
157                     LoadSeekHeadItem( EBML_INFO(KaxTracks), i_pos );
158                 }
159                 else if( id == EBML_ID(KaxAttachments) )
160                 {
161                     msg_Dbg( &sys.demuxer, "|   - attachments at %" PRId64, i_pos );
162                     LoadSeekHeadItem( EBML_INFO(KaxAttachments), i_pos );
163                 }
164 #ifdef MKV_DEBUG
165                 else if( id != EBML_ID(KaxCluster) && id != EBML_ID(EbmlVoid) &&
166                          id != EBML_ID(EbmlCrc32))
167                     msg_Dbg( &sys.demuxer, "|   - unknown seekhead reference at %" PRId64, i_pos );
168 #endif
169             }
170         }
171         else if ( !MKV_IS_ID( l, EbmlVoid ) && !MKV_IS_ID( l, EbmlCrc32 ))
172             msg_Dbg( &sys.demuxer, "|   |   + ParseSeekHead Unknown (%s)", typeid(*l).name() );
173     }
174     delete ep;
175 }
176
177
178 /**
179  * Helper function to print the mkv parse tree
180  */
181 static void MkvTree( demux_t & demuxer, int i_level, const char *psz_format, ... )
182 {
183     va_list args;
184     if( i_level > 9 )
185     {
186         msg_Err( &demuxer, "MKV tree is too deep" );
187         return;
188     }
189     va_start( args, psz_format );
190     static const char psz_foo[] = "|   |   |   |   |   |   |   |   |   |";
191     char *psz_foo2 = (char*)malloc( i_level * 4 + 3 + strlen( psz_format ) );
192     strncpy( psz_foo2, psz_foo, 4 * i_level );
193     psz_foo2[ 4 * i_level ] = '+';
194     psz_foo2[ 4 * i_level + 1 ] = ' ';
195     strcpy( &psz_foo2[ 4 * i_level + 2 ], psz_format );
196     msg_GenericVa( &demuxer,VLC_MSG_DBG, psz_foo2, args );
197     free( psz_foo2 );
198     va_end( args );
199 }
200
201
202 /*****************************************************************************
203  * ParseTrackEntry:
204  *****************************************************************************/
205 void matroska_segment_c::ParseTrackEntry( KaxTrackEntry *m )
206 {
207     bool bSupported = true;
208
209     /* Init the track */
210     mkv_track_t *tk = new mkv_track_t();
211     memset( tk, 0, sizeof( mkv_track_t ) );
212
213     es_format_Init( &tk->fmt, UNKNOWN_ES, 0 );
214     tk->p_es = NULL;
215     tk->fmt.psz_language       = strdup("English");
216     tk->fmt.psz_description    = NULL;
217
218     tk->b_default              = true;
219     tk->b_enabled              = true;
220     tk->b_forced               = false;
221     tk->b_silent               = false;
222     tk->i_number               = tracks.size() - 1;
223     tk->i_extra_data           = 0;
224     tk->p_extra_data           = NULL;
225     tk->psz_codec              = NULL;
226     tk->b_dts_only             = false;
227     tk->i_default_duration     = 0;
228     tk->b_no_duration          = false;
229     tk->f_timecodescale        = 1.0;
230
231     tk->b_inited               = false;
232     tk->i_data_init            = 0;
233     tk->p_data_init            = NULL;
234
235     tk->psz_codec_name         = NULL;
236     tk->psz_codec_settings     = NULL;
237     tk->psz_codec_info_url     = NULL;
238     tk->psz_codec_download_url = NULL;
239
240     tk->i_compression_type     = MATROSKA_COMPRESSION_NONE;
241     tk->i_encoding_scope       = MATROSKA_ENCODING_SCOPE_ALL_FRAMES;
242     tk->p_compression_data     = NULL;
243
244     msg_Dbg( &sys.demuxer, "|   |   + Track Entry" );
245
246     for( size_t i = 0; i < m->ListSize(); i++ )
247     {
248         EbmlElement *l = (*m)[i];
249
250         if( MKV_IS_ID( l, KaxTrackNumber ) )
251         {
252             KaxTrackNumber &tnum = *(KaxTrackNumber*)l;
253
254             tk->i_number = uint32( tnum );
255             msg_Dbg( &sys.demuxer, "|   |   |   + Track Number=%u", uint32( tnum ) );
256         }
257         else  if( MKV_IS_ID( l, KaxTrackUID ) )
258         {
259             KaxTrackUID &tuid = *(KaxTrackUID*)l;
260
261             msg_Dbg( &sys.demuxer, "|   |   |   + Track UID=%u",  uint32( tuid ) );
262         }
263         else  if( MKV_IS_ID( l, KaxTrackType ) )
264         {
265             const char *psz_type;
266             KaxTrackType &ttype = *(KaxTrackType*)l;
267
268             switch( uint8(ttype) )
269             {
270                 case track_audio:
271                     psz_type = "audio";
272                     tk->fmt.i_cat = AUDIO_ES;
273                     tk->fmt.audio.i_channels = 1;
274                     tk->fmt.audio.i_rate = 8000;
275                     break;
276                 case track_video:
277                     psz_type = "video";
278                     tk->fmt.i_cat = VIDEO_ES;
279                     break;
280                 case track_subtitle:
281                     psz_type = "subtitle";
282                     tk->fmt.i_cat = SPU_ES;
283                     break;
284                 case track_buttons:
285                     psz_type = "buttons";
286                     tk->fmt.i_cat = SPU_ES;
287                     break;
288                 default:
289                     psz_type = "unknown";
290                     tk->fmt.i_cat = UNKNOWN_ES;
291                     break;
292             }
293
294             msg_Dbg( &sys.demuxer, "|   |   |   + Track Type=%s", psz_type );
295         }
296         else  if( MKV_IS_ID( l, KaxTrackFlagEnabled ) ) // UNUSED
297         {
298             KaxTrackFlagEnabled &fenb = *(KaxTrackFlagEnabled*)l;
299
300             tk->b_enabled = uint32( fenb );
301             msg_Dbg( &sys.demuxer, "|   |   |   + Track Enabled=%u", uint32( fenb ) );
302         }
303         else  if( MKV_IS_ID( l, KaxTrackFlagDefault ) )
304         {
305             KaxTrackFlagDefault &fdef = *(KaxTrackFlagDefault*)l;
306
307             tk->b_default = uint32( fdef );
308             msg_Dbg( &sys.demuxer, "|   |   |   + Track Default=%u", uint32( fdef ) );
309         }
310         else  if( MKV_IS_ID( l, KaxTrackFlagForced ) ) // UNUSED
311         {
312             KaxTrackFlagForced &ffor = *(KaxTrackFlagForced*)l;
313             tk->b_forced = uint32( ffor );
314
315             msg_Dbg( &sys.demuxer, "|   |   |   + Track Forced=%u", uint32( ffor ) );
316         }
317         else  if( MKV_IS_ID( l, KaxTrackFlagLacing ) ) // UNUSED
318         {
319             KaxTrackFlagLacing &lac = *(KaxTrackFlagLacing*)l;
320
321             msg_Dbg( &sys.demuxer, "|   |   |   + Track Lacing=%d", uint32( lac ) );
322         }
323         else  if( MKV_IS_ID( l, KaxTrackMinCache ) ) // UNUSED
324         {
325             KaxTrackMinCache &cmin = *(KaxTrackMinCache*)l;
326
327             msg_Dbg( &sys.demuxer, "|   |   |   + Track MinCache=%d", uint32( cmin ) );
328         }
329         else  if( MKV_IS_ID( l, KaxTrackMaxCache ) ) // UNUSED
330         {
331             KaxTrackMaxCache &cmax = *(KaxTrackMaxCache*)l;
332
333             msg_Dbg( &sys.demuxer, "|   |   |   + Track MaxCache=%d", uint32( cmax ) );
334         }
335         else  if( MKV_IS_ID( l, KaxTrackDefaultDuration ) )
336         {
337             KaxTrackDefaultDuration &defd = *(KaxTrackDefaultDuration*)l;
338
339             tk->i_default_duration = uint64(defd);
340             msg_Dbg( &sys.demuxer, "|   |   |   + Track Default Duration=%" PRId64, tk->i_default_duration );
341             tk->i_default_duration /= 1000;
342         }
343         else  if( MKV_IS_ID( l, KaxTrackTimecodeScale ) )
344         {
345             KaxTrackTimecodeScale &ttcs = *(KaxTrackTimecodeScale*)l;
346
347             tk->f_timecodescale = float( ttcs );
348             if ( tk->f_timecodescale <= 0 ) tk->f_timecodescale = 1.0;
349             msg_Dbg( &sys.demuxer, "|   |   |   + Track TimeCodeScale=%f", tk->f_timecodescale );
350         }
351         else  if( MKV_IS_ID( l, KaxMaxBlockAdditionID ) ) // UNUSED
352         {
353             KaxMaxBlockAdditionID &mbl = *(KaxMaxBlockAdditionID*)l;
354
355             msg_Dbg( &sys.demuxer, "|   |   |   + Track Max BlockAdditionID=%d", uint32( mbl ) );
356         }
357         else if( MKV_IS_ID( l, KaxTrackName ) )
358         {
359             KaxTrackName &tname = *(KaxTrackName*)l;
360
361             tk->fmt.psz_description = ToUTF8( UTFstring( tname ) );
362             msg_Dbg( &sys.demuxer, "|   |   |   + Track Name=%s", tk->fmt.psz_description );
363         }
364         else  if( MKV_IS_ID( l, KaxTrackLanguage ) )
365         {
366             KaxTrackLanguage &lang = *(KaxTrackLanguage*)l;
367
368             free( tk->fmt.psz_language );
369             tk->fmt.psz_language = strdup( string( lang ).c_str() );
370             msg_Dbg( &sys.demuxer,
371                      "|   |   |   + Track Language=`%s'", tk->fmt.psz_language );
372         }
373         else  if( MKV_IS_ID( l, KaxCodecID ) )
374         {
375             KaxCodecID &codecid = *(KaxCodecID*)l;
376
377             tk->psz_codec = strdup( string( codecid ).c_str() );
378             msg_Dbg( &sys.demuxer, "|   |   |   + Track CodecId=%s", string( codecid ).c_str() );
379         }
380         else  if( MKV_IS_ID( l, KaxCodecPrivate ) )
381         {
382             KaxCodecPrivate &cpriv = *(KaxCodecPrivate*)l;
383
384             tk->i_extra_data = cpriv.GetSize();
385             if( tk->i_extra_data > 0 )
386             {
387                 tk->p_extra_data = (uint8_t*)malloc( tk->i_extra_data );
388                 memcpy( tk->p_extra_data, cpriv.GetBuffer(), tk->i_extra_data );
389             }
390             msg_Dbg( &sys.demuxer, "|   |   |   + Track CodecPrivate size=%" PRId64, cpriv.GetSize() );
391         }
392         else if( MKV_IS_ID( l, KaxCodecName ) )
393         {
394             KaxCodecName &cname = *(KaxCodecName*)l;
395
396             tk->psz_codec_name = ToUTF8( UTFstring( cname ) );
397             msg_Dbg( &sys.demuxer, "|   |   |   + Track Codec Name=%s", tk->psz_codec_name );
398         }
399         //AttachmentLink
400         else if( MKV_IS_ID( l, KaxCodecDecodeAll ) ) // UNUSED
401         {
402             KaxCodecDecodeAll &cdall = *(KaxCodecDecodeAll*)l;
403
404             msg_Dbg( &sys.demuxer, "|   |   |   + Track Codec Decode All=%u", uint8( cdall ) );
405         }
406         else if( MKV_IS_ID( l, KaxTrackOverlay ) ) // UNUSED
407         {
408             KaxTrackOverlay &tovr = *(KaxTrackOverlay*)l;
409
410             msg_Dbg( &sys.demuxer, "|   |   |   + Track Overlay=%u", uint32( tovr ) );
411         }
412 #if LIBMATROSKA_VERSION >= 0x010401
413         else if( MKV_IS_ID( l, KaxCodecDelay ) )
414         {
415             KaxCodecDelay &codecdelay = *(KaxCodecDelay*)l;
416             tk->i_codec_delay = uint64_t( codecdelay ) / 1000;
417             msg_Dbg( &sys.demuxer, "|   |   |   + Track Codec Delay =%" PRIu64,
418                      tk->i_codec_delay );
419         }
420         else if( MKV_IS_ID( l, KaxSeekPreRoll ) )
421         {
422             KaxSeekPreRoll &spr = *(KaxSeekPreRoll*)l;
423             tk->i_seek_preroll = uint64_t(spr) / 1000;
424             msg_Dbg( &sys.demuxer, "|   |   |   + Track Seek Preroll =%" PRIu64, tk->i_seek_preroll );
425         }
426 #endif
427         else if( MKV_IS_ID( l, KaxContentEncodings ) )
428         {
429             EbmlMaster *cencs = static_cast<EbmlMaster*>(l);
430             MkvTree( sys.demuxer, 3, "Content Encodings" );
431             if ( cencs->ListSize() > 1 )
432             {
433                 msg_Err( &sys.demuxer, "Multiple Compression method not supported" );
434                 bSupported = false;
435             }
436             for( size_t j = 0; j < cencs->ListSize(); j++ )
437             {
438                 EbmlElement *l2 = (*cencs)[j];
439                 if( MKV_IS_ID( l2, KaxContentEncoding ) )
440                 {
441                     MkvTree( sys.demuxer, 4, "Content Encoding" );
442                     EbmlMaster *cenc = static_cast<EbmlMaster*>(l2);
443                     for( size_t k = 0; k < cenc->ListSize(); k++ )
444                     {
445                         EbmlElement *l3 = (*cenc)[k];
446                         if( MKV_IS_ID( l3, KaxContentEncodingOrder ) )
447                         {
448                             KaxContentEncodingOrder &encord = *(KaxContentEncodingOrder*)l3;
449                             MkvTree( sys.demuxer, 5, "Order: %i", uint32( encord ) );
450                         }
451                         else if( MKV_IS_ID( l3, KaxContentEncodingScope ) )
452                         {
453                             KaxContentEncodingScope &encscope = *(KaxContentEncodingScope*)l3;
454                             tk->i_encoding_scope = uint32( encscope );
455                             MkvTree( sys.demuxer, 5, "Scope: %i", uint32( encscope ) );
456                         }
457                         else if( MKV_IS_ID( l3, KaxContentEncodingType ) )
458                         {
459                             KaxContentEncodingType &enctype = *(KaxContentEncodingType*)l3;
460                             MkvTree( sys.demuxer, 5, "Type: %i", uint32( enctype ) );
461                         }
462                         else if( MKV_IS_ID( l3, KaxContentCompression ) )
463                         {
464                             EbmlMaster *compr = static_cast<EbmlMaster*>(l3);
465                             MkvTree( sys.demuxer, 5, "Content Compression" );
466                             //Default compression type is 0 (Zlib)
467                             tk->i_compression_type = MATROSKA_COMPRESSION_ZLIB;
468                             for( size_t n = 0; n < compr->ListSize(); n++ )
469                             {
470                                 EbmlElement *l4 = (*compr)[n];
471                                 if( MKV_IS_ID( l4, KaxContentCompAlgo ) )
472                                 {
473                                     KaxContentCompAlgo &compalg = *(KaxContentCompAlgo*)l4;
474                                     MkvTree( sys.demuxer, 6, "Compression Algorithm: %i", uint32(compalg) );
475                                     tk->i_compression_type = uint32( compalg );
476                                     if ( ( tk->i_compression_type != MATROSKA_COMPRESSION_ZLIB ) &&
477                                          ( tk->i_compression_type != MATROSKA_COMPRESSION_HEADER ) )
478                                     {
479                                         msg_Err( &sys.demuxer, "Track Compression method %d not supported", tk->i_compression_type );
480                                         bSupported = false;
481                                     }
482                                 }
483                                 else if( MKV_IS_ID( l4, KaxContentCompSettings ) )
484                                 {
485                                     tk->p_compression_data = new KaxContentCompSettings( *(KaxContentCompSettings*)l4 );
486                                 }
487                                 else if ( !MKV_IS_ID( l4, EbmlVoid ) )
488                                 {
489                                     MkvTree( sys.demuxer, 6, "Unknown (%s)", typeid(*l4).name() );
490                                 }
491                             }
492                         }
493                         // ContentEncryption Unsupported
494                         else if ( !MKV_IS_ID( l3, EbmlVoid ) )
495                         {
496                             MkvTree( sys.demuxer, 5, "Unknown (%s)", typeid(*l3).name() );
497                         }
498                     }
499                 }
500                 else if ( !MKV_IS_ID( l2, EbmlVoid ) )
501                 {
502                     MkvTree( sys.demuxer, 4, "Unknown (%s)", typeid(*l2).name() );
503                 }
504             }
505         }
506 //        else if( MKV_IS_ID( l, KaxCodecSettings) ) DEPRECATED by matroska
507 //        {
508 //            KaxCodecSettings &cset = *(KaxCodecSettings*)l;
509
510 //            tk->psz_codec_settings = ToUTF8( UTFstring( cset ) );
511 //            msg_Dbg( &sys.demuxer, "|   |   |   + Track Codec Settings=%s", tk->psz_codec_settings );
512 //        }
513 //        else if( MKV_IS_ID( l, KaxCodecInfoURL) ) DEPRECATED by matroska
514 //        {
515 //            KaxCodecInfoURL &ciurl = *(KaxCodecInfoURL*)l;
516
517 //            tk->psz_codec_info_url = strdup( string( ciurl ).c_str() );
518 //            msg_Dbg( &sys.demuxer, "|   |   |   + Track Codec Info URL=%s", tk->psz_codec_info_url );
519 //        }
520 //        else if( MKV_IS_ID( l, KaxCodecDownloadURL) ) DEPRECATED by matroska
521 //        {
522 //            KaxCodecDownloadURL &cdurl = *(KaxCodecDownloadURL*)l;
523
524 //            tk->psz_codec_download_url = strdup( string( cdurl ).c_str() );
525 //            msg_Dbg( &sys.demuxer, "|   |   |   + Track Codec Info URL=%s", tk->psz_codec_download_url );
526 //        }
527         else  if( MKV_IS_ID( l, KaxTrackVideo ) )
528         {
529             EbmlMaster *tkv = static_cast<EbmlMaster*>(l);
530             unsigned int i_crop_right = 0, i_crop_left = 0, i_crop_top = 0, i_crop_bottom = 0;
531             unsigned int i_display_unit = 0, i_display_width = 0, i_display_height = 0;
532
533             msg_Dbg( &sys.demuxer, "|   |   |   + Track Video" );
534             tk->f_fps = 0.0;
535
536             tk->fmt.video.i_frame_rate_base = (unsigned int)tk->i_default_duration;
537             tk->fmt.video.i_frame_rate = 1000000;
538
539             for( unsigned int j = 0; j < tkv->ListSize(); j++ )
540             {
541                 EbmlElement *l = (*tkv)[j];
542                 if( MKV_IS_ID( l, KaxVideoFlagInterlaced ) ) // UNUSED
543                 {
544                     KaxVideoFlagInterlaced &fint = *(KaxVideoFlagInterlaced*)l;
545
546                     msg_Dbg( &sys.demuxer, "|   |   |   |   + Track Video Interlaced=%u", uint8( fint ) );
547                 }
548                 else if( MKV_IS_ID( l, KaxVideoStereoMode ) ) // UNUSED
549                 {
550                     KaxVideoStereoMode &stereo = *(KaxVideoStereoMode*)l;
551
552                     msg_Dbg( &sys.demuxer, "|   |   |   |   + Track Video Stereo Mode=%u", uint8( stereo ) );
553                 }
554                 else if( MKV_IS_ID( l, KaxVideoPixelWidth ) )
555                 {
556                     KaxVideoPixelWidth &vwidth = *(KaxVideoPixelWidth*)l;
557
558                     tk->fmt.video.i_width += uint16( vwidth );
559                     msg_Dbg( &sys.demuxer, "|   |   |   |   + width=%d", uint16( vwidth ) );
560                 }
561                 else if( MKV_IS_ID( l, KaxVideoPixelHeight ) )
562                 {
563                     KaxVideoPixelWidth &vheight = *(KaxVideoPixelWidth*)l;
564
565                     tk->fmt.video.i_height += uint16( vheight );
566                     msg_Dbg( &sys.demuxer, "|   |   |   |   + height=%d", uint16( vheight ) );
567                 }
568                 else if( MKV_IS_ID( l, KaxVideoDisplayWidth ) )
569                 {
570                     KaxVideoDisplayWidth &vwidth = *(KaxVideoDisplayWidth*)l;
571
572                     i_display_width = uint16( vwidth );
573                     msg_Dbg( &sys.demuxer, "|   |   |   |   + display width=%d", uint16( vwidth ) );
574                 }
575                 else if( MKV_IS_ID( l, KaxVideoDisplayHeight ) )
576                 {
577                     KaxVideoDisplayWidth &vheight = *(KaxVideoDisplayWidth*)l;
578
579                     i_display_height = uint16( vheight );
580                     msg_Dbg( &sys.demuxer, "|   |   |   |   + display height=%d", uint16( vheight ) );
581                 }
582                 else if( MKV_IS_ID( l, KaxVideoPixelCropBottom ) )
583                 {
584                     KaxVideoPixelCropBottom &cropval = *(KaxVideoPixelCropBottom*)l;
585
586                     i_crop_bottom = uint16( cropval );
587                     msg_Dbg( &sys.demuxer, "|   |   |   |   + crop pixel bottom=%d", uint16( cropval ) );
588                 }
589                 else if( MKV_IS_ID( l, KaxVideoPixelCropTop ) )
590                 {
591                     KaxVideoPixelCropTop &cropval = *(KaxVideoPixelCropTop*)l;
592
593                     i_crop_top = uint16( cropval );
594                     msg_Dbg( &sys.demuxer, "|   |   |   |   + crop pixel top=%d", uint16( cropval ) );
595                 }
596                 else if( MKV_IS_ID( l, KaxVideoPixelCropRight ) )
597                 {
598                     KaxVideoPixelCropRight &cropval = *(KaxVideoPixelCropRight*)l;
599
600                     i_crop_right = uint16( cropval );
601                     msg_Dbg( &sys.demuxer, "|   |   |   |   + crop pixel right=%d", uint16( cropval ) );
602                 }
603                 else if( MKV_IS_ID( l, KaxVideoPixelCropLeft ) )
604                 {
605                     KaxVideoPixelCropLeft &cropval = *(KaxVideoPixelCropLeft*)l;
606
607                     i_crop_left = uint16( cropval );
608                     msg_Dbg( &sys.demuxer, "|   |   |   |   + crop pixel left=%d", uint16( cropval ) );
609                 }
610                 else if( MKV_IS_ID( l, KaxVideoDisplayUnit ) )
611                 {
612                     KaxVideoDisplayUnit &vdmode = *(KaxVideoDisplayUnit*)l;
613
614                     i_display_unit = uint8( vdmode );
615                     msg_Dbg( &sys.demuxer, "|   |   |   |   + Track Video Display Unit=%s",
616                              i_display_unit == 0 ? "pixels" : ( i_display_unit == 1 ? "centimeters": "inches" ) );
617                 }
618                 else if( MKV_IS_ID( l, KaxVideoAspectRatio ) ) // UNUSED
619                 {
620                     KaxVideoAspectRatio &ratio = *(KaxVideoAspectRatio*)l;
621
622                     msg_Dbg( &sys.demuxer, "   |   |   |   + Track Video Aspect Ratio Type=%u", uint8( ratio ) );
623                 }
624                 // ColourSpace UNUSED
625                 else if( MKV_IS_ID( l, KaxVideoFrameRate ) )
626                 {
627                     KaxVideoFrameRate &vfps = *(KaxVideoFrameRate*)l;
628
629                     tk->f_fps = __MAX( float( vfps ), 1 );
630                     msg_Dbg( &sys.demuxer, "   |   |   |   + fps=%f", float( vfps ) );
631                 }
632 //                else if( MKV_IS_ID( l, KaxVideoGamma) ) //DEPRECATED by Matroska
633 //                {
634 //                    KaxVideoGamma &gamma = *(KaxVideoGamma*)l;
635
636 //                    msg_Dbg( &sys.demuxer, "   |   |   |   + gamma=%f", float( gamma ) );
637 //                }
638                 else if ( !MKV_IS_ID( l, EbmlVoid ) )
639                 {
640                     msg_Dbg( &sys.demuxer, "|   |   |   |   + Unknown (%s)", typeid(*l).name() );
641                 }
642             }
643             if( i_display_height && i_display_width )
644             {
645                 tk->fmt.video.i_sar_num = i_display_width  * tk->fmt.video.i_height;
646                 tk->fmt.video.i_sar_den = i_display_height * tk->fmt.video.i_width;
647             }
648             if( i_crop_left || i_crop_right || i_crop_top || i_crop_bottom )
649             {
650                 tk->fmt.video.i_visible_width   = tk->fmt.video.i_width;
651                 tk->fmt.video.i_visible_height  = tk->fmt.video.i_height;
652                 tk->fmt.video.i_x_offset        = i_crop_left;
653                 tk->fmt.video.i_y_offset        = i_crop_top;
654                 tk->fmt.video.i_visible_width  -= i_crop_left + i_crop_right;
655                 tk->fmt.video.i_visible_height -= i_crop_top + i_crop_bottom;
656             }
657             /* FIXME: i_display_* allows you to not only set DAR, but also a zoom factor.
658                we do not support this atm */
659         }
660         else  if( MKV_IS_ID( l, KaxTrackAudio ) )
661         {
662             EbmlMaster *tka = static_cast<EbmlMaster*>(l);
663
664             /* Initialize default values */
665             tk->fmt.audio.i_channels = 1;
666             tk->fmt.audio.i_rate = 8000;
667
668             msg_Dbg( &sys.demuxer, "|   |   |   + Track Audio" );
669
670             for( unsigned int j = 0; j < tka->ListSize(); j++ )
671             {
672                 EbmlElement *l = (*tka)[j];
673
674                 if( MKV_IS_ID( l, KaxAudioSamplingFreq ) )
675                 {
676                     KaxAudioSamplingFreq &afreq = *(KaxAudioSamplingFreq*)l;
677
678                     tk->i_original_rate = tk->fmt.audio.i_rate = (int)float( afreq );
679                     msg_Dbg( &sys.demuxer, "|   |   |   |   + afreq=%d", tk->fmt.audio.i_rate );
680                 }
681                 else if( MKV_IS_ID( l, KaxAudioOutputSamplingFreq ) )
682                 {
683                     KaxAudioOutputSamplingFreq &afreq = *(KaxAudioOutputSamplingFreq*)l;
684
685                     tk->fmt.audio.i_rate = (int)float( afreq );
686                     msg_Dbg( &sys.demuxer, "|   |   |   |   + aoutfreq=%d", tk->fmt.audio.i_rate );
687                 }
688                 else if( MKV_IS_ID( l, KaxAudioChannels ) )
689                 {
690                     KaxAudioChannels &achan = *(KaxAudioChannels*)l;
691
692                     tk->fmt.audio.i_channels = uint8( achan );
693                     msg_Dbg( &sys.demuxer, "|   |   |   |   + achan=%u", uint8( achan ) );
694                 }
695                 else if( MKV_IS_ID( l, KaxAudioBitDepth ) )
696                 {
697                     KaxAudioBitDepth &abits = *(KaxAudioBitDepth*)l;
698
699                     tk->fmt.audio.i_bitspersample = uint8( abits );
700                     msg_Dbg( &sys.demuxer, "|   |   |   |   + abits=%u", uint8( abits ) );
701                 }
702                 else if ( !MKV_IS_ID( l, EbmlVoid ) )
703                 {
704                     msg_Dbg( &sys.demuxer, "|   |   |   |   + Unknown (%s)", typeid(*l).name() );
705                 }
706             }
707         }
708         else if ( !MKV_IS_ID( l, EbmlVoid ) )
709         {
710             msg_Dbg( &sys.demuxer, "|   |   |   + Unknown (%s)",
711                      typeid(*l).name() );
712         }
713     }
714
715     if ( bSupported )
716     {
717 #ifdef HAVE_ZLIB_H
718         if( tk->i_compression_type == MATROSKA_COMPRESSION_ZLIB &&
719             tk->i_encoding_scope & MATROSKA_ENCODING_SCOPE_PRIVATE &&
720             tk->i_extra_data && tk->p_extra_data &&
721             zlib_decompress_extra( &sys.demuxer, tk) )
722             return;
723 #endif
724         if( TrackInit( tk ) )
725         {
726             msg_Err(&sys.demuxer, "Couldn't init track %d", tk->i_number );
727             free(tk->p_extra_data);
728             delete tk;
729             return;
730         }
731
732         tracks.push_back( tk );
733     }
734     else
735     {
736         msg_Err( &sys.demuxer, "Track Entry %d not supported", tk->i_number );
737         free(tk->p_extra_data);
738         delete tk;
739     }
740 }
741
742 /*****************************************************************************
743  * ParseTracks:
744  *****************************************************************************/
745 void matroska_segment_c::ParseTracks( KaxTracks *tracks )
746 {
747     EbmlElement *el;
748     int i_upper_level = 0;
749
750     /* Master elements */
751     if( unlikely( tracks->IsFiniteSize() && tracks->GetSize() >= SIZE_MAX ) )
752     {
753         msg_Err( &sys.demuxer, "Track too big, aborting" );
754         return;
755     }
756     try
757     {
758         tracks->Read( es, EBML_CONTEXT(tracks), i_upper_level, el, true );
759     }
760     catch(...)
761     {
762         msg_Err( &sys.demuxer, "Couldn't read tracks" );
763         return;
764     }
765
766     for( size_t i = 0; i < tracks->ListSize(); i++ )
767     {
768         EbmlElement *l = (*tracks)[i];
769
770         if( MKV_IS_ID( l, KaxTrackEntry ) )
771         {
772             ParseTrackEntry( static_cast<KaxTrackEntry *>(l) );
773         }
774         else if ( !MKV_IS_ID( l, EbmlVoid ) )
775         {
776             msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid(*l).name() );
777         }
778     }
779 }
780
781 /*****************************************************************************
782  * ParseInfo:
783  *****************************************************************************/
784 void matroska_segment_c::ParseInfo( KaxInfo *info )
785 {
786     EbmlElement *el;
787     EbmlMaster  *m;
788     int i_upper_level = 0;
789
790     /* Master elements */
791     m = static_cast<EbmlMaster *>(info);
792     if( unlikely( m->IsFiniteSize() && m->GetSize() >= SIZE_MAX ) )
793     {
794         msg_Err( &sys.demuxer, "Info too big, aborting" );
795         return;
796     }
797     try
798     {
799         m->Read( es, EBML_CONTEXT(info), i_upper_level, el, true );
800     }
801     catch(...)
802     {
803         msg_Err( &sys.demuxer, "Couldn't read info" );
804         return;
805     }   
806
807     for( size_t i = 0; i < m->ListSize(); i++ )
808     {
809         EbmlElement *l = (*m)[i];
810
811         if( MKV_IS_ID( l, KaxSegmentUID ) )
812         {
813             if ( p_segment_uid == NULL )
814                 p_segment_uid = new KaxSegmentUID(*static_cast<KaxSegmentUID*>(l));
815
816             msg_Dbg( &sys.demuxer, "|   |   + UID=%d", *(uint32*)p_segment_uid->GetBuffer() );
817         }
818         else if( MKV_IS_ID( l, KaxPrevUID ) )
819         {
820             if ( p_prev_segment_uid == NULL )
821             {
822                 p_prev_segment_uid = new KaxPrevUID(*static_cast<KaxPrevUID*>(l));
823                 b_ref_external_segments = true;
824             }
825
826             msg_Dbg( &sys.demuxer, "|   |   + PrevUID=%d", *(uint32*)p_prev_segment_uid->GetBuffer() );
827         }
828         else if( MKV_IS_ID( l, KaxNextUID ) )
829         {
830             if ( p_next_segment_uid == NULL )
831             {
832                 p_next_segment_uid = new KaxNextUID(*static_cast<KaxNextUID*>(l));
833                 b_ref_external_segments = true;
834             }
835
836             msg_Dbg( &sys.demuxer, "|   |   + NextUID=%d", *(uint32*)p_next_segment_uid->GetBuffer() );
837         }
838         else if( MKV_IS_ID( l, KaxTimecodeScale ) )
839         {
840             KaxTimecodeScale &tcs = *(KaxTimecodeScale*)l;
841
842             i_timescale = uint64(tcs);
843
844             msg_Dbg( &sys.demuxer, "|   |   + TimecodeScale=%" PRId64,
845                      i_timescale );
846         }
847         else if( MKV_IS_ID( l, KaxDuration ) )
848         {
849             KaxDuration &dur = *(KaxDuration*)l;
850
851             i_duration = mtime_t( double( dur ) );
852
853             msg_Dbg( &sys.demuxer, "|   |   + Duration=%" PRId64,
854                      i_duration );
855         }
856         else if( MKV_IS_ID( l, KaxMuxingApp ) )
857         {
858             KaxMuxingApp &mapp = *(KaxMuxingApp*)l;
859
860             psz_muxing_application = ToUTF8( UTFstring( mapp ) );
861
862             msg_Dbg( &sys.demuxer, "|   |   + Muxing Application=%s",
863                      psz_muxing_application );
864         }
865         else if( MKV_IS_ID( l, KaxWritingApp ) )
866         {
867             KaxWritingApp &wapp = *(KaxWritingApp*)l;
868
869             psz_writing_application = ToUTF8( UTFstring( wapp ) );
870
871             msg_Dbg( &sys.demuxer, "|   |   + Writing Application=%s",
872                      psz_writing_application );
873         }
874         else if( MKV_IS_ID( l, KaxSegmentFilename ) )
875         {
876             KaxSegmentFilename &sfn = *(KaxSegmentFilename*)l;
877
878             psz_segment_filename = ToUTF8( UTFstring( sfn ) );
879
880             msg_Dbg( &sys.demuxer, "|   |   + Segment Filename=%s",
881                      psz_segment_filename );
882         }
883         else if( MKV_IS_ID( l, KaxTitle ) )
884         {
885             KaxTitle &title = *(KaxTitle*)l;
886
887             psz_title = ToUTF8( UTFstring( title ) );
888
889             msg_Dbg( &sys.demuxer, "|   |   + Title=%s", psz_title );
890         }
891         else if( MKV_IS_ID( l, KaxSegmentFamily ) )
892         {
893             KaxSegmentFamily *uid = static_cast<KaxSegmentFamily*>(l);
894
895             families.push_back( new KaxSegmentFamily(*uid) );
896
897             msg_Dbg( &sys.demuxer, "|   |   + family=%d", *(uint32*)uid->GetBuffer() );
898         }
899         else if( MKV_IS_ID( l, KaxDateUTC ) )
900         {
901             KaxDateUTC &date = *(KaxDateUTC*)l;
902             time_t i_date;
903             struct tm tmres;
904             char   buffer[25];
905
906             i_date = date.GetEpochDate();
907             if( gmtime_r( &i_date, &tmres ) &&
908                 strftime( buffer, sizeof(buffer), "%a %b %d %H:%M:%S %Y",
909                           &tmres ) )
910             {
911                 psz_date_utc = strdup( buffer );
912                 msg_Dbg( &sys.demuxer, "|   |   + Date=%s", buffer );
913             }
914         }
915         else if( MKV_IS_ID( l, KaxChapterTranslate ) )
916         {
917             KaxChapterTranslate *p_trans = static_cast<KaxChapterTranslate*>( l );
918             try
919             {
920                 if( unlikely( p_trans->IsFiniteSize() && p_trans->GetSize() >= SIZE_MAX ) )
921                 {
922                     msg_Err( &sys.demuxer, "Chapter translate too big, aborting" );
923                     continue;
924                 }
925
926                 p_trans->Read( es, EBML_CONTEXT(p_trans), i_upper_level, el, true );
927                 chapter_translation_c *p_translate = new chapter_translation_c();
928
929                 for( size_t j = 0; j < p_trans->ListSize(); j++ )
930                 {
931                     EbmlElement *l = (*p_trans)[j];
932
933                     if( MKV_IS_ID( l, KaxChapterTranslateEditionUID ) )
934                     {
935                         p_translate->editions.push_back( uint64( *static_cast<KaxChapterTranslateEditionUID*>( l ) ) );
936                     }
937                     else if( MKV_IS_ID( l, KaxChapterTranslateCodec ) )
938                     {
939                         p_translate->codec_id = uint32( *static_cast<KaxChapterTranslateCodec*>( l ) );
940                     }
941                     else if( MKV_IS_ID( l, KaxChapterTranslateID ) )
942                     {
943                         p_translate->p_translated = new KaxChapterTranslateID( *static_cast<KaxChapterTranslateID*>( l ) );
944                     }
945                 }
946
947                 translations.push_back( p_translate );
948             }
949             catch(...)
950             {
951                 msg_Err( &sys.demuxer, "Error while reading Chapter Tranlate");
952             }
953         }
954         else if ( !MKV_IS_ID( l, EbmlVoid ) )
955         {
956             msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid(*l).name() );
957         }
958     }
959
960     double f_dur = double(i_duration) * double(i_timescale) / 1000000.0;
961     i_duration = mtime_t(f_dur);
962     if( !i_duration ) i_duration = -1;
963 }
964
965
966 /*****************************************************************************
967  * ParseChapterAtom
968  *****************************************************************************/
969 void matroska_segment_c::ParseChapterAtom( int i_level, KaxChapterAtom *ca, chapter_item_c & chapters )
970 {
971     msg_Dbg( &sys.demuxer, "|   |   |   + ChapterAtom (level=%d)", i_level );
972     for( size_t i = 0; i < ca->ListSize(); i++ )
973     {
974         EbmlElement *l = (*ca)[i];
975
976         if( MKV_IS_ID( l, KaxChapterUID ) )
977         {
978             chapters.i_uid = uint64_t(*(KaxChapterUID*)l);
979             msg_Dbg( &sys.demuxer, "|   |   |   |   + ChapterUID: %" PRIu64, chapters.i_uid );
980         }
981         else if( MKV_IS_ID( l, KaxChapterFlagHidden ) )
982         {
983             KaxChapterFlagHidden &flag =*(KaxChapterFlagHidden*)l;
984             chapters.b_display_seekpoint = uint8( flag ) == 0;
985
986             msg_Dbg( &sys.demuxer, "|   |   |   |   + ChapterFlagHidden: %s", chapters.b_display_seekpoint ? "no":"yes" );
987         }
988         else if( MKV_IS_ID( l, KaxChapterSegmentUID ) )
989         {
990             chapters.p_segment_uid = new KaxChapterSegmentUID( *static_cast<KaxChapterSegmentUID*>(l) );
991             b_ref_external_segments = true;
992             msg_Dbg( &sys.demuxer, "|   |   |   |   + ChapterSegmentUID= %u", *(uint32*)chapters.p_segment_uid->GetBuffer() );
993         }
994         else if( MKV_IS_ID( l, KaxChapterSegmentEditionUID ) )
995         {
996             chapters.p_segment_edition_uid = new KaxChapterSegmentEditionUID( *static_cast<KaxChapterSegmentEditionUID*>(l) );
997             msg_Dbg( &sys.demuxer, "|   |   |   |   + ChapterSegmentEditionUID= %u",
998 #if LIBMATROSKA_VERSION < 0x010300
999                      *(uint32*)chapters.p_segment_edition_uid->GetBuffer()
1000 #else
1001                      *(uint32*)chapters.p_segment_edition_uid
1002 #endif
1003                    );
1004         }
1005         else if( MKV_IS_ID( l, KaxChapterTimeStart ) )
1006         {
1007             KaxChapterTimeStart &start =*(KaxChapterTimeStart*)l;
1008             chapters.i_start_time = uint64( start ) / INT64_C(1000);
1009
1010             msg_Dbg( &sys.demuxer, "|   |   |   |   + ChapterTimeStart: %" PRId64, chapters.i_start_time );
1011         }
1012         else if( MKV_IS_ID( l, KaxChapterTimeEnd ) )
1013         {
1014             KaxChapterTimeEnd &end =*(KaxChapterTimeEnd*)l;
1015             chapters.i_end_time = uint64( end ) / INT64_C(1000);
1016
1017             msg_Dbg( &sys.demuxer, "|   |   |   |   + ChapterTimeEnd: %" PRId64, chapters.i_end_time );
1018         }
1019         else if( MKV_IS_ID( l, KaxChapterDisplay ) )
1020         {
1021             EbmlMaster *cd = static_cast<EbmlMaster *>(l);
1022
1023             msg_Dbg( &sys.demuxer, "|   |   |   |   + ChapterDisplay" );
1024             for( size_t j = 0; j < cd->ListSize(); j++ )
1025             {
1026                 EbmlElement *l= (*cd)[j];
1027
1028                 if( MKV_IS_ID( l, KaxChapterString ) )
1029                 {
1030                     KaxChapterString &name =*(KaxChapterString*)l;
1031                     for ( int k = 0; k < i_level; k++)
1032                         chapters.psz_name += '+';
1033                     chapters.psz_name += ' ';
1034                     char *psz_tmp_utf8 = ToUTF8( UTFstring( name ) );
1035                     chapters.psz_name += psz_tmp_utf8;
1036                     chapters.b_user_display = true;
1037
1038                     msg_Dbg( &sys.demuxer, "|   |   |   |   |    + ChapterString '%s'", psz_tmp_utf8 );
1039                     free( psz_tmp_utf8 );
1040                 }
1041                 else if( MKV_IS_ID( l, KaxChapterLanguage ) )
1042                 {
1043                     KaxChapterLanguage &lang =*(KaxChapterLanguage*)l;
1044                     msg_Dbg( &sys.demuxer, "|   |   |   |   |    + ChapterLanguage '%s'",
1045                              string( lang ).c_str() );
1046                 }
1047                 else if( MKV_IS_ID( l, KaxChapterCountry ) )
1048                 {
1049                     KaxChapterCountry &ct =*(KaxChapterCountry*)l;
1050                     msg_Dbg( &sys.demuxer, "|   |   |   |   |    + ChapterCountry '%s'",
1051                              string( ct ).c_str() );
1052                 }
1053             }
1054         }
1055         else if( MKV_IS_ID( l, KaxChapterProcess ) )
1056         {
1057             msg_Dbg( &sys.demuxer, "|   |   |   |   + ChapterProcess" );
1058
1059             KaxChapterProcess *cp = static_cast<KaxChapterProcess *>(l);
1060             chapter_codec_cmds_c *p_ccodec = NULL;
1061
1062             for( size_t j = 0; j < cp->ListSize(); j++ )
1063             {
1064                 EbmlElement *k= (*cp)[j];
1065
1066                 if( MKV_IS_ID( k, KaxChapterProcessCodecID ) )
1067                 {
1068                     KaxChapterProcessCodecID *p_codec_id = static_cast<KaxChapterProcessCodecID*>( k );
1069                     if ( uint32(*p_codec_id) == 0 )
1070                         p_ccodec = new matroska_script_codec_c( sys );
1071                     else if ( uint32(*p_codec_id) == 1 )
1072                         p_ccodec = new dvd_chapter_codec_c( sys );
1073                     break;
1074                 }
1075             }
1076
1077             if ( p_ccodec != NULL )
1078             {
1079                 for( size_t j = 0; j < cp->ListSize(); j++ )
1080                 {
1081                     EbmlElement *k= (*cp)[j];
1082
1083                     if( MKV_IS_ID( k, KaxChapterProcessPrivate ) )
1084                     {
1085                         KaxChapterProcessPrivate * p_private = static_cast<KaxChapterProcessPrivate*>( k );
1086                         p_ccodec->SetPrivate( *p_private );
1087                     }
1088                     else if( MKV_IS_ID( k, KaxChapterProcessCommand ) )
1089                     {
1090                         p_ccodec->AddCommand( *static_cast<KaxChapterProcessCommand*>( k ) );
1091                     }
1092                 }
1093                 chapters.codecs.push_back( p_ccodec );
1094             }
1095         }
1096         else if( MKV_IS_ID( l, KaxChapterAtom ) )
1097         {
1098             chapter_item_c *new_sub_chapter = new chapter_item_c();
1099             ParseChapterAtom( i_level+1, static_cast<KaxChapterAtom *>(l), *new_sub_chapter );
1100             new_sub_chapter->p_parent = &chapters;
1101             chapters.sub_chapters.push_back( new_sub_chapter );
1102         }
1103     }
1104 }
1105
1106 /*****************************************************************************
1107  * ParseAttachments:
1108  *****************************************************************************/
1109 void matroska_segment_c::ParseAttachments( KaxAttachments *attachments )
1110 {
1111     EbmlElement *el;
1112     int i_upper_level = 0;
1113
1114     if( unlikely( attachments->IsFiniteSize() && attachments->GetSize() >= SIZE_MAX ) )
1115     {
1116         msg_Err( &sys.demuxer, "Attachments too big, aborting" );
1117         return;
1118     }
1119     try
1120     {
1121         attachments->Read( es, EBML_CONTEXT(attachments), i_upper_level, el, true );
1122     }
1123     catch(...)
1124     {
1125         msg_Err( &sys.demuxer, "Error while reading attachments" );
1126         return;
1127     }
1128
1129     KaxAttached *attachedFile = FindChild<KaxAttached>( *attachments );
1130
1131     while( attachedFile && ( attachedFile->GetSize() > 0 ) )
1132     {
1133         KaxFileData  &img_data     = GetChild<KaxFileData>( *attachedFile );
1134         char *psz_tmp_utf8 =  ToUTF8( UTFstring( GetChild<KaxFileName>( *attachedFile ) ) );
1135         std::string attached_filename(psz_tmp_utf8);
1136         free(psz_tmp_utf8);
1137         attachment_c *new_attachment = new attachment_c( attached_filename,
1138                                                          GetChild<KaxMimeType>( *attachedFile ),
1139                                                          img_data.GetSize() );
1140
1141         msg_Dbg( &sys.demuxer, "|   |   - %s (%s)", new_attachment->fileName(), new_attachment->mimeType() );
1142
1143         if( new_attachment->init() )
1144         {
1145             memcpy( new_attachment->p_data, img_data.GetBuffer(), img_data.GetSize() );
1146             sys.stored_attachments.push_back( new_attachment );
1147             if( !strncmp( new_attachment->mimeType(), "image/", 6 ) )
1148             {
1149                 char *psz_url;
1150                 if( asprintf( &psz_url, "attachment://%s",
1151                               new_attachment->fileName() ) == -1 )
1152                     continue;
1153                 if( !sys.meta )
1154                     sys.meta = vlc_meta_New();
1155                 vlc_meta_SetArtURL( sys.meta, psz_url );
1156                 free( psz_url );
1157             }
1158         }
1159         else
1160         {
1161             delete new_attachment;
1162         }
1163
1164         attachedFile = &GetNextChild<KaxAttached>( *attachments, *attachedFile );
1165     }
1166 }
1167
1168 /*****************************************************************************
1169  * ParseChapters:
1170  *****************************************************************************/
1171 void matroska_segment_c::ParseChapters( KaxChapters *chapters )
1172 {
1173     EbmlElement *el;
1174     int i_upper_level = 0;
1175
1176     /* Master elements */
1177     if( unlikely( chapters->IsFiniteSize() && chapters->GetSize() >= SIZE_MAX ) )
1178     {
1179         msg_Err( &sys.demuxer, "Chapters too big, aborting" );
1180         return;
1181     }
1182     try
1183     {
1184         chapters->Read( es, EBML_CONTEXT(chapters), i_upper_level, el, true );
1185     }
1186     catch(...)
1187     {
1188         msg_Err( &sys.demuxer, "Error while reading chapters" );
1189         return;
1190     }
1191
1192     for( size_t i = 0; i < chapters->ListSize(); i++ )
1193     {
1194         EbmlElement *l = (*chapters)[i];
1195
1196         if( MKV_IS_ID( l, KaxEditionEntry ) )
1197         {
1198             chapter_edition_c *p_edition = new chapter_edition_c();
1199
1200             EbmlMaster *E = static_cast<EbmlMaster *>(l );
1201             msg_Dbg( &sys.demuxer, "|   |   + EditionEntry" );
1202             for( size_t j = 0; j < E->ListSize(); j++ )
1203             {
1204                 EbmlElement *l = (*E)[j];
1205
1206                 if( MKV_IS_ID( l, KaxChapterAtom ) )
1207                 {
1208                     chapter_item_c *new_sub_chapter = new chapter_item_c();
1209                     ParseChapterAtom( 0, static_cast<KaxChapterAtom *>(l), *new_sub_chapter );
1210                     p_edition->sub_chapters.push_back( new_sub_chapter );
1211                 }
1212                 else if( MKV_IS_ID( l, KaxEditionUID ) )
1213                 {
1214                     p_edition->i_uid = uint64(*static_cast<KaxEditionUID *>( l ));
1215                 }
1216                 else if( MKV_IS_ID( l, KaxEditionFlagOrdered ) )
1217                 {
1218                     p_edition->b_ordered = var_InheritBool( &sys.demuxer, "mkv-use-ordered-chapters" ) ? (uint8(*static_cast<KaxEditionFlagOrdered *>( l )) != 0) : 0;
1219                 }
1220                 else if( MKV_IS_ID( l, KaxEditionFlagDefault ) )
1221                 {
1222                     if (uint8(*static_cast<KaxEditionFlagDefault *>( l )) != 0)
1223                         i_default_edition = stored_editions.size();
1224                 }
1225                 else if( MKV_IS_ID( l, KaxEditionFlagHidden ) )
1226                 {
1227                     // FIXME to implement
1228                 }
1229                 else if ( !MKV_IS_ID( l, EbmlVoid ) )
1230                 {
1231                     msg_Dbg( &sys.demuxer, "|   |   |   + Unknown (%s)", typeid(*l).name() );
1232                 }
1233             }
1234             stored_editions.push_back( p_edition );
1235         }
1236         else if ( !MKV_IS_ID( l, EbmlVoid ) )
1237         {
1238             msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid(*l).name() );
1239         }
1240     }
1241 }
1242
1243 void matroska_segment_c::ParseCluster( KaxCluster *cluster, bool b_update_start_time, ScopeMode read_fully )
1244 {
1245     EbmlElement *el;
1246     EbmlMaster  *m;
1247     int i_upper_level = 0;
1248
1249     /* Master elements */
1250     m = static_cast<EbmlMaster *>( cluster );
1251     if( unlikely( m->IsFiniteSize() && m->GetSize() >= SIZE_MAX ) )
1252     {
1253         msg_Err( &sys.demuxer, "Cluster too big, aborting" );
1254         return;
1255     }
1256     try
1257     {
1258         m->Read( es, EBML_CONTEXT(cluster), i_upper_level, el, true, read_fully );
1259     }
1260     catch(...)
1261     {
1262         msg_Err( &sys.demuxer, "Error while reading cluster" );
1263         return;
1264     }
1265
1266     for( unsigned int i = 0; i < m->ListSize(); i++ )
1267     {
1268         EbmlElement *l = (*m)[i];
1269
1270         if( MKV_IS_ID( l, KaxClusterTimecode ) )
1271         {
1272             KaxClusterTimecode &ctc = *(KaxClusterTimecode*)l;
1273
1274             cluster->InitTimecode( uint64( ctc ), i_timescale );
1275             break;
1276         }
1277     }
1278
1279     if( b_update_start_time )
1280         i_start_time = cluster->GlobalTimecode() / 1000;
1281 }
1282
1283
1284 int32_t matroska_segment_c::TrackInit( mkv_track_t * p_tk )
1285 {
1286     es_format_t *p_fmt = &p_tk->fmt;
1287
1288     if( p_tk->psz_codec == NULL )
1289     {
1290         msg_Err( &sys.demuxer, "Empty codec id" );
1291         p_tk->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1292         return 0;
1293     }
1294
1295     if( !strcmp( p_tk->psz_codec, "V_MS/VFW/FOURCC" ) )
1296     {
1297         if( p_tk->i_extra_data < (int)sizeof( VLC_BITMAPINFOHEADER ) )
1298         {
1299             msg_Err( &sys.demuxer, "missing/invalid VLC_BITMAPINFOHEADER" );
1300             p_tk->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1301         }
1302         else
1303         {
1304             VLC_BITMAPINFOHEADER *p_bih = (VLC_BITMAPINFOHEADER*)p_tk->p_extra_data;
1305
1306             p_tk->fmt.video.i_width = GetDWLE( &p_bih->biWidth );
1307             p_tk->fmt.video.i_height= GetDWLE( &p_bih->biHeight );
1308             p_tk->fmt.i_codec       = GetFOURCC( &p_bih->biCompression );
1309
1310             p_tk->fmt.i_extra       = GetDWLE( &p_bih->biSize ) - sizeof( VLC_BITMAPINFOHEADER );
1311             if( p_tk->fmt.i_extra > 0 )
1312             {
1313                 /* Very unlikely yet possible: bug #5659*/
1314                 size_t maxlen = p_tk->i_extra_data - sizeof( VLC_BITMAPINFOHEADER );
1315                 p_tk->fmt.i_extra = ( (unsigned)p_tk->fmt.i_extra < maxlen )?
1316                     p_tk->fmt.i_extra : maxlen;
1317
1318                 p_tk->fmt.p_extra = xmalloc( p_tk->fmt.i_extra );
1319                 memcpy( p_tk->fmt.p_extra, &p_bih[1], p_tk->fmt.i_extra );
1320             }
1321         }
1322         p_tk->b_dts_only = true;
1323     }
1324     else if( !strcmp( p_tk->psz_codec, "V_MPEG1" ) ||
1325              !strcmp( p_tk->psz_codec, "V_MPEG2" ) )
1326     {
1327         p_tk->fmt.i_codec = VLC_CODEC_MPGV;
1328         if( p_tk->i_extra_data )
1329             fill_extra_data( p_tk, 0 );
1330     }
1331     else if( !strncmp( p_tk->psz_codec, "V_THEORA", 8 ) )
1332     {
1333         p_tk->fmt.i_codec = VLC_CODEC_THEORA;
1334         fill_extra_data( p_tk, 0 );
1335         p_tk->b_pts_only = true;
1336     }
1337     else if( !strncmp( p_tk->psz_codec, "V_REAL/RV", 9 ) )
1338     {
1339         uint8_t *p = p_tk->p_extra_data;
1340
1341         if( !strcmp( p_tk->psz_codec, "V_REAL/RV10" ) )
1342             p_fmt->i_codec = VLC_CODEC_RV10;
1343         else if( !strcmp( p_tk->psz_codec, "V_REAL/RV20" ) )
1344             p_fmt->i_codec = VLC_CODEC_RV20;
1345         else if( !strcmp( p_tk->psz_codec, "V_REAL/RV30" ) )
1346             p_fmt->i_codec = VLC_CODEC_RV30;
1347         else if( !strcmp( p_tk->psz_codec, "V_REAL/RV40" ) )
1348             p_fmt->i_codec = VLC_CODEC_RV40;
1349
1350         /* Extract the framerate from the header */
1351         if( p_tk->i_extra_data >= 26 &&
1352             p[4] == 'V' && p[5] == 'I' && p[6] == 'D' && p[7] == 'O' &&
1353             p[8] == 'R' && p[9] == 'V' &&
1354             (p[10] == '3' || p[10] == '4') && p[11] == '0' )
1355         {
1356             p_tk->fmt.video.i_frame_rate =
1357                 p[22] << 24 | p[23] << 16 | p[24] << 8 | p[25] << 0;
1358             p_tk->fmt.video.i_frame_rate_base = 65536;
1359         }
1360
1361         fill_extra_data( p_tk, 26 );
1362         p_tk->b_dts_only = true;
1363     }
1364     else if( !strncmp( p_tk->psz_codec, "V_DIRAC", 7 ) )
1365     {
1366         p_tk->fmt.i_codec = VLC_CODEC_DIRAC;
1367     }
1368     else if( !strncmp( p_tk->psz_codec, "V_VP8", 5 ) )
1369     {
1370         p_tk->fmt.i_codec = VLC_CODEC_VP8;
1371         p_tk->b_pts_only = true;
1372     }
1373     else if( !strncmp( p_tk->psz_codec, "V_VP9", 5 ) )
1374     {
1375         p_tk->fmt.i_codec = VLC_CODEC_VP9;
1376         p_tk->fmt.b_packetized = false;
1377         p_tk->b_pts_only = true;
1378         fill_extra_data( p_tk, 0 );
1379     }
1380     else if( !strncmp( p_tk->psz_codec, "V_MPEG4", 7 ) )
1381     {
1382         if( !strcmp( p_tk->psz_codec, "V_MPEG4/MS/V3" ) )
1383         {
1384             p_tk->fmt.i_codec = VLC_CODEC_DIV3;
1385         }
1386         else if( !strncmp( p_tk->psz_codec, "V_MPEG4/ISO", 11 ) )
1387         {
1388             /* A MPEG 4 codec, SP, ASP, AP or AVC */
1389             if( !strcmp( p_tk->psz_codec, "V_MPEG4/ISO/AVC" ) )
1390                 p_tk->fmt.i_codec = VLC_FOURCC( 'a', 'v', 'c', '1' );
1391             else
1392                 p_tk->fmt.i_codec = VLC_CODEC_MP4V;
1393             fill_extra_data( p_tk, 0 );
1394         }
1395     }
1396     else if( !strncmp( p_tk->psz_codec, "V_MPEGH/ISO/HEVC", 16) )
1397     {
1398         p_tk->fmt.i_codec = VLC_CODEC_HEVC;
1399         fill_extra_data( p_tk, 0 );
1400     } 
1401     else if( !strcmp( p_tk->psz_codec, "V_QUICKTIME" ) )
1402     {
1403         MP4_Box_t *p_box = (MP4_Box_t*)xmalloc( sizeof( MP4_Box_t ) );
1404         stream_t *p_mp4_stream = stream_MemoryNew( VLC_OBJECT(&sys.demuxer),
1405                                                    p_tk->p_extra_data,
1406                                                    p_tk->i_extra_data,
1407                                                    true );
1408         if( MP4_ReadBoxCommon( p_mp4_stream, p_box ) &&
1409             MP4_ReadBox_sample_vide( p_mp4_stream, p_box ) )
1410         {
1411             p_tk->fmt.i_codec = p_box->i_type;
1412             uint32_t i_width = p_box->data.p_sample_vide->i_width;
1413             uint32_t i_height = p_box->data.p_sample_vide->i_height;
1414             if( i_width && i_height )
1415             {
1416                 p_tk->fmt.video.i_width = i_width;
1417                 p_tk->fmt.video.i_height = i_height;
1418             }
1419             p_tk->fmt.i_extra = p_box->data.p_sample_vide->i_qt_image_description;
1420             p_tk->fmt.p_extra = xmalloc( p_tk->fmt.i_extra );
1421             memcpy( p_tk->fmt.p_extra, p_box->data.p_sample_vide->p_qt_image_description, p_tk->fmt.i_extra );
1422             MP4_FreeBox_sample_vide( p_box );
1423         }
1424         else
1425         {
1426             free( p_box );
1427         }
1428         stream_Delete( p_mp4_stream );
1429     }
1430     else if( !strcmp( p_tk->psz_codec, "V_MJPEG" ) )
1431     {
1432         p_tk->fmt.i_codec = VLC_CODEC_MJPG;
1433     }
1434     else if( !strcmp( p_tk->psz_codec, "A_MS/ACM" ) )
1435     {
1436         if( p_tk->i_extra_data < (int)sizeof( WAVEFORMATEX ) )
1437         {
1438             msg_Err( &sys.demuxer, "missing/invalid WAVEFORMATEX" );
1439             p_tk->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1440         }
1441         else
1442         {
1443             WAVEFORMATEX *p_wf = (WAVEFORMATEX*)p_tk->p_extra_data;
1444
1445             p_tk->fmt.audio.i_channels   = GetWLE( &p_wf->nChannels );
1446             p_tk->fmt.audio.i_rate = GetDWLE( &p_wf->nSamplesPerSec );
1447             p_tk->fmt.i_bitrate    = GetDWLE( &p_wf->nAvgBytesPerSec ) * 8;
1448             p_tk->fmt.audio.i_blockalign = GetWLE( &p_wf->nBlockAlign );;
1449             p_tk->fmt.audio.i_bitspersample = GetWLE( &p_wf->wBitsPerSample );
1450
1451             p_tk->fmt.i_extra            = GetWLE( &p_wf->cbSize );
1452             if( p_tk->fmt.i_extra > 0 )
1453             {
1454                 p_tk->fmt.p_extra = xmalloc( p_tk->fmt.i_extra );
1455                 if( p_tk->fmt.p_extra )
1456                     memcpy( p_tk->fmt.p_extra, &p_wf[1], p_tk->fmt.i_extra );
1457                 else
1458                     p_tk->fmt.i_extra = 0;
1459             }
1460
1461             if( p_wf->wFormatTag == WAVE_FORMAT_EXTENSIBLE && 
1462                 p_tk->i_extra_data >= sizeof(WAVEFORMATEXTENSIBLE) )
1463             {
1464                 WAVEFORMATEXTENSIBLE * p_wext = (WAVEFORMATEXTENSIBLE*) p_wf;
1465                 sf_tag_to_fourcc( &p_wext->SubFormat,  &p_tk->fmt.i_codec, NULL);
1466                 /* FIXME should we use Samples */
1467
1468                 if( p_tk->fmt.audio.i_channels > 2 &&
1469                     ( p_tk->fmt.i_codec != VLC_FOURCC( 'u', 'n', 'd', 'f' ) ) ) 
1470                 {
1471                     uint32_t wfextcm = GetDWLE( &p_wext->dwChannelMask );
1472                     int match;
1473                     unsigned i_channel_mask = getChannelMask( &wfextcm,
1474                                                               p_tk->fmt.audio.i_channels,
1475                                                               &match );
1476                     p_tk->fmt.i_codec = vlc_fourcc_GetCodecAudio( p_tk->fmt.i_codec,
1477                                                                   p_tk->fmt.audio.i_bitspersample );
1478                     if( i_channel_mask )
1479                     {
1480                         p_tk->i_chans_to_reorder = aout_CheckChannelReorder(
1481                             pi_channels_aout, NULL,
1482                             i_channel_mask,
1483                             p_tk->pi_chan_table );
1484
1485                         p_tk->fmt.audio.i_physical_channels =
1486                         p_tk->fmt.audio.i_original_channels = i_channel_mask;
1487                     }
1488                 }
1489             }
1490             else
1491                 wf_tag_to_fourcc( GetWLE( &p_wf->wFormatTag ), &p_tk->fmt.i_codec, NULL );
1492
1493             if( p_tk->fmt.i_codec == VLC_FOURCC( 'u', 'n', 'd', 'f' ) )
1494                 msg_Err( &sys.demuxer, "Unrecognized wf tag: 0x%x", GetWLE( &p_wf->wFormatTag ) );
1495         }
1496     }
1497     else if( !strcmp( p_tk->psz_codec, "A_MPEG/L3" ) ||
1498              !strcmp( p_tk->psz_codec, "A_MPEG/L2" ) ||
1499              !strcmp( p_tk->psz_codec, "A_MPEG/L1" ) )
1500     {
1501         p_tk->fmt.i_codec = VLC_CODEC_MPGA;
1502         p_fmt->b_packetized = false;
1503     }
1504     else if( !strcmp( p_tk->psz_codec, "A_AC3" ) )
1505     {
1506         // the AC-3 default duration cannot be trusted, see #8512
1507         if ( p_tk->fmt.audio.i_rate == 8000 )
1508         {
1509             p_tk->b_no_duration = true;
1510             p_tk->i_default_duration = 0;
1511         }
1512         p_tk->fmt.i_codec = VLC_CODEC_A52;
1513     }
1514     else if( !strcmp( p_tk->psz_codec, "A_EAC3" ) )
1515     {
1516         p_tk->fmt.i_codec = VLC_CODEC_EAC3;
1517     }
1518     else if( !strcmp( p_tk->psz_codec, "A_DTS" ) )
1519     {
1520         p_tk->fmt.i_codec = VLC_CODEC_DTS;
1521     }
1522     else if( !strcmp( p_tk->psz_codec, "A_MLP" ) )
1523     {
1524         p_tk->fmt.i_codec = VLC_CODEC_MLP;
1525     }
1526     else if( !strcmp( p_tk->psz_codec, "A_TRUEHD" ) )
1527     {
1528         /* FIXME when more samples arrive */
1529         p_tk->fmt.i_codec = VLC_CODEC_TRUEHD;
1530         p_fmt->b_packetized = false;
1531     }
1532     else if( !strcmp( p_tk->psz_codec, "A_FLAC" ) )
1533     {
1534         p_tk->fmt.i_codec = VLC_CODEC_FLAC;
1535         fill_extra_data( p_tk, 8 );
1536     }
1537     else if( !strcmp( p_tk->psz_codec, "A_VORBIS" ) )
1538     {
1539         p_tk->fmt.i_codec = VLC_CODEC_VORBIS;
1540         fill_extra_data( p_tk, 0 );
1541     }
1542     else if( !strncmp( p_tk->psz_codec, "A_OPUS", 6 ) )
1543     {
1544         p_tk->fmt.i_codec = VLC_CODEC_OPUS;
1545         if( !p_tk->fmt.audio.i_rate )
1546         {
1547             msg_Err( &sys.demuxer,"No sampling rate, defaulting to 48kHz");
1548             p_tk->fmt.audio.i_rate = 48000;
1549         }
1550         const uint8_t tags[16] = {'O','p','u','s','T','a','g','s',
1551                                    0, 0, 0, 0, 0, 0, 0, 0};
1552         unsigned ps[2] = { p_tk->i_extra_data, 16 };
1553         const void *pkt[2] = { (const void *)p_tk->p_extra_data,
1554                               (const void *) tags };
1555
1556         if( xiph_PackHeaders( &p_tk->fmt.i_extra,
1557                               &p_tk->fmt.p_extra,
1558                               ps, pkt, 2 ) )
1559             msg_Err( &sys.demuxer, "Couldn't pack OPUS headers");
1560
1561     }
1562     else if( !strncmp( p_tk->psz_codec, "A_AAC/MPEG2/", strlen( "A_AAC/MPEG2/" ) ) ||
1563              !strncmp( p_tk->psz_codec, "A_AAC/MPEG4/", strlen( "A_AAC/MPEG4/" ) ) )
1564     {
1565         int i_profile, i_srate, sbr = 0;
1566         static const unsigned int i_sample_rates[] =
1567         {
1568             96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
1569             16000, 12000, 11025,  8000,  7350,     0,     0,     0
1570         };
1571
1572         p_tk->fmt.i_codec = VLC_CODEC_MP4A;
1573         /* create data for faad (MP4DecSpecificDescrTag)*/
1574
1575         if( !strcmp( &p_tk->psz_codec[12], "MAIN" ) )
1576         {
1577             i_profile = 0;
1578         }
1579         else if( !strcmp( &p_tk->psz_codec[12], "LC" ) )
1580         {
1581             i_profile = 1;
1582         }
1583         else if( !strcmp( &p_tk->psz_codec[12], "SSR" ) )
1584         {
1585             i_profile = 2;
1586         }
1587         else if( !strcmp( &p_tk->psz_codec[12], "LC/SBR" ) )
1588         {
1589             i_profile = 1;
1590             sbr = 1;
1591         }
1592         else
1593         {
1594             i_profile = 3;
1595         }
1596
1597         for( i_srate = 0; i_srate < 13; i_srate++ )
1598         {
1599             if( i_sample_rates[i_srate] == p_tk->i_original_rate )
1600             {
1601                 break;
1602             }
1603         }
1604         msg_Dbg( &sys.demuxer, "profile=%d srate=%d", i_profile, i_srate );
1605
1606         p_tk->fmt.i_extra = sbr ? 5 : 2;
1607         p_tk->fmt.p_extra = xmalloc( p_tk->fmt.i_extra );
1608         ((uint8_t*)p_tk->fmt.p_extra)[0] = ((i_profile + 1) << 3) | ((i_srate&0xe) >> 1);
1609         ((uint8_t*)p_tk->fmt.p_extra)[1] = ((i_srate & 0x1) << 7) | (p_tk->fmt.audio.i_channels << 3);
1610         if (sbr != 0)
1611         {
1612             int syncExtensionType = 0x2B7;
1613             int iDSRI;
1614             for (iDSRI=0; iDSRI<13; iDSRI++)
1615                 if( i_sample_rates[iDSRI] == p_tk->fmt.audio.i_rate )
1616                     break;
1617             ((uint8_t*)p_tk->fmt.p_extra)[2] = (syncExtensionType >> 3) & 0xFF;
1618             ((uint8_t*)p_tk->fmt.p_extra)[3] = ((syncExtensionType & 0x7) << 5) | 5;
1619             ((uint8_t*)p_tk->fmt.p_extra)[4] = ((1 & 0x1) << 7) | (iDSRI << 3);
1620         }
1621     }
1622     else if( !strcmp( p_tk->psz_codec, "A_AAC" ) )
1623     {
1624         p_tk->fmt.i_codec = VLC_CODEC_MP4A;
1625         fill_extra_data( p_tk, 0 );
1626     }
1627     else if( !strcmp( p_tk->psz_codec, "A_ALAC" ) )
1628     {
1629         p_tk->fmt.i_codec =  VLC_CODEC_ALAC;
1630         fill_extra_data( p_tk, 0 );
1631     }
1632     else if( !strcmp( p_tk->psz_codec, "A_WAVPACK4" ) )
1633     {
1634         p_tk->fmt.i_codec = VLC_CODEC_WAVPACK;
1635         fill_extra_data( p_tk, 0 );
1636     }
1637     else if( !strcmp( p_tk->psz_codec, "A_TTA1" ) )
1638     {
1639         p_fmt->i_codec = VLC_CODEC_TTA;
1640         if( p_tk->i_extra_data > 0 )
1641         {
1642             fill_extra_data( p_tk, 0 );
1643         }
1644         else
1645         {
1646             p_fmt->i_extra = 30;
1647             p_fmt->p_extra = xmalloc( p_fmt->i_extra );
1648             uint8_t *p_extra = (uint8_t*)p_fmt->p_extra;
1649             memcpy( &p_extra[ 0], "TTA1", 4 );
1650             SetWLE( &p_extra[ 4], 1 );
1651             SetWLE( &p_extra[ 6], p_fmt->audio.i_channels );
1652             SetWLE( &p_extra[ 8], p_fmt->audio.i_bitspersample );
1653             SetDWLE( &p_extra[10], p_fmt->audio.i_rate );
1654             SetDWLE( &p_extra[14], 0xffffffff );
1655             memset( &p_extra[18], 0, 30  - 18 );
1656         }
1657     }
1658     else if( !strcmp( p_tk->psz_codec, "A_PCM/INT/BIG" ) ||
1659              !strcmp( p_tk->psz_codec, "A_PCM/INT/LIT" ) ||
1660              !strcmp( p_tk->psz_codec, "A_PCM/FLOAT/IEEE" ) )
1661     {
1662         if( !strcmp( p_tk->psz_codec, "A_PCM/INT/BIG" ) )
1663         {
1664             p_tk->fmt.i_codec = VLC_FOURCC( 't', 'w', 'o', 's' );
1665         }
1666         else
1667         {
1668             p_tk->fmt.i_codec = VLC_FOURCC( 'a', 'r', 'a', 'w' );
1669         }
1670         p_tk->fmt.audio.i_blockalign = ( p_tk->fmt.audio.i_bitspersample + 7 ) / 8 * p_tk->fmt.audio.i_channels;
1671     }
1672     else if( !strncmp( p_tk->psz_codec, "A_REAL/", 7 ) )
1673     {
1674         if( !strcmp( p_tk->psz_codec, "A_REAL/14_4" ) )
1675         {
1676             p_fmt->i_codec = VLC_CODEC_RA_144;
1677             p_fmt->audio.i_channels = 1;
1678             p_fmt->audio.i_rate = 8000;
1679             p_fmt->audio.i_blockalign = 0x14;
1680         }
1681         else if( p_tk->i_extra_data > 28 )
1682         {
1683             uint8_t *p = p_tk->p_extra_data;
1684             if( memcmp( p, ".ra", 3 ) ) {
1685                 msg_Err( &sys.demuxer, "Invalid Real ExtraData 0x%4.4s", (char *)p );
1686                 p_tk->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1687             }
1688             else
1689             {
1690                 real_audio_private * priv = (real_audio_private*) p_tk->p_extra_data;
1691                 if( !strcmp( p_tk->psz_codec, "A_REAL/COOK" ) )
1692                 {
1693                     p_tk->fmt.i_codec = VLC_CODEC_COOK;
1694                     p_tk->fmt.audio.i_blockalign = hton16(priv->sub_packet_size);
1695                 }
1696                 else if( !strcmp( p_tk->psz_codec, "A_REAL/ATRC" ) )
1697                     p_tk->fmt.i_codec = VLC_CODEC_ATRAC3;
1698                 else if( !strcmp( p_tk->psz_codec, "A_REAL/28_8" ) )
1699                     p_tk->fmt.i_codec = VLC_CODEC_RA_288;
1700                 /* FIXME RALF and SIPR */
1701                 uint16_t version = (uint16_t) hton16(priv->version);
1702                 p_tk->p_sys =
1703                     new Cook_PrivateTrackData( hton16(priv->sub_packet_h),
1704                                                hton16(priv->frame_size),
1705                                                hton16(priv->sub_packet_size));
1706                 if( unlikely( !p_tk->p_sys ) )
1707                     return 1;
1708
1709                 if( unlikely( p_tk->p_sys->Init() ) )
1710                     return 1;
1711
1712                 if( version == 4 )
1713                 {
1714                     real_audio_private_v4 * v4 = (real_audio_private_v4*) priv;
1715                     p_tk->fmt.audio.i_channels = hton16(v4->channels);
1716                     p_tk->fmt.audio.i_bitspersample = hton16(v4->sample_size);
1717                     p_tk->fmt.audio.i_rate = hton16(v4->sample_rate);
1718                 }
1719                 else if( version == 5 )
1720                 {
1721                     real_audio_private_v5 * v5 = (real_audio_private_v5*) priv;
1722                     p_tk->fmt.audio.i_channels = hton16(v5->channels);
1723                     p_tk->fmt.audio.i_bitspersample = hton16(v5->sample_size);
1724                     p_tk->fmt.audio.i_rate = hton16(v5->sample_rate);
1725                 }
1726                 msg_Dbg(&sys.demuxer, "%d channels %d bits %d Hz",p_tk->fmt.audio.i_channels, p_tk->fmt.audio.i_bitspersample, p_tk->fmt.audio.i_rate);
1727
1728                 fill_extra_data( p_tk, p_tk->fmt.i_codec == VLC_CODEC_RA_288 ? 0 : 78);
1729             }
1730         }
1731     }
1732     else if( !strncmp( p_tk->psz_codec, "A_QUICKTIME", 11 ) )
1733     {
1734         p_tk->fmt.i_cat = AUDIO_ES;
1735         if ( !strncmp( p_tk->psz_codec+11, "/QDM2", 5 ) )
1736             p_tk->fmt.i_codec = VLC_CODEC_QDM2;
1737         else if( !strncmp( p_tk->psz_codec+11, "/QDMC", 5 ) )
1738             p_tk->fmt.i_codec = VLC_FOURCC('Q','D','M','C');
1739         else if( p_tk->i_extra_data >= 8)
1740             p_tk->fmt.i_codec = VLC_FOURCC(p_tk->p_extra_data[4],
1741                                            p_tk->p_extra_data[5],
1742                                            p_tk->p_extra_data[6],
1743                                            p_tk->p_extra_data[7]);
1744         fill_extra_data( p_tk, 0 );
1745     }
1746     else if( !strcmp( p_tk->psz_codec, "S_KATE" ) )
1747     {
1748         p_tk->fmt.i_codec = VLC_CODEC_KATE;
1749         p_tk->fmt.subs.psz_encoding = strdup( "UTF-8" );
1750
1751         fill_extra_data( p_tk, 0 );
1752     }
1753     else if( !strcmp( p_tk->psz_codec, "S_TEXT/ASCII" ) )
1754     {
1755         p_fmt->i_codec = VLC_CODEC_SUBT;
1756         p_fmt->subs.psz_encoding = strdup( "ASCII" );
1757     }
1758     else if( !strcmp( p_tk->psz_codec, "S_TEXT/UTF8" ) )
1759     {
1760         p_tk->fmt.i_codec = VLC_CODEC_SUBT;
1761         p_tk->fmt.subs.psz_encoding = strdup( "UTF-8" );
1762     }
1763     else if( !strcmp( p_tk->psz_codec, "S_TEXT/USF" ) )
1764     {
1765         p_tk->fmt.i_codec = VLC_FOURCC( 'u', 's', 'f', ' ' );
1766         p_tk->fmt.subs.psz_encoding = strdup( "UTF-8" );
1767         if( p_tk->i_extra_data )
1768             fill_extra_data( p_tk, 0 );
1769     }
1770     else if( !strcmp( p_tk->psz_codec, "S_TEXT/SSA" ) ||
1771              !strcmp( p_tk->psz_codec, "S_TEXT/ASS" ) ||
1772              !strcmp( p_tk->psz_codec, "S_SSA" ) ||
1773              !strcmp( p_tk->psz_codec, "S_ASS" ))
1774     {
1775         p_tk->fmt.i_codec = VLC_CODEC_SSA;
1776         p_tk->fmt.subs.psz_encoding = strdup( "UTF-8" );
1777         if( p_tk->i_extra_data )
1778             fill_extra_data( p_tk, 0 );
1779     }
1780     else if( !strcmp( p_tk->psz_codec, "S_VOBSUB" ) )
1781     {
1782         p_tk->fmt.i_codec = VLC_CODEC_SPU;
1783         p_tk->b_no_duration = true;
1784         if( p_tk->i_extra_data )
1785         {
1786             char *psz_start;
1787             char *psz_buf = (char *)malloc( p_tk->i_extra_data + 1);
1788             if( psz_buf != NULL )
1789             {
1790                 memcpy( psz_buf, p_tk->p_extra_data , p_tk->i_extra_data );
1791                 psz_buf[p_tk->i_extra_data] = '\0';
1792
1793                 psz_start = strstr( psz_buf, "size:" );
1794                 if( psz_start &&
1795                     vobsub_size_parse( psz_start,
1796                                        &p_tk->fmt.subs.spu.i_original_frame_width,
1797                                        &p_tk->fmt.subs.spu.i_original_frame_height ) == VLC_SUCCESS )
1798                 {
1799                     msg_Dbg( &sys.demuxer, "original frame size vobsubs: %dx%d",
1800                              p_tk->fmt.subs.spu.i_original_frame_width,
1801                              p_tk->fmt.subs.spu.i_original_frame_height );
1802                 }
1803                 else
1804                 {
1805                     msg_Warn( &sys.demuxer, "reading original frame size for vobsub failed" );
1806                 }
1807
1808                 psz_start = strstr( psz_buf, "palette:" );
1809                 if( psz_start &&
1810                     vobsub_palette_parse( psz_start, &p_tk->fmt.subs.spu.palette[1] ) == VLC_SUCCESS )
1811                 {
1812                     p_tk->fmt.subs.spu.palette[0] =  0xBeef;
1813                     msg_Dbg( &sys.demuxer, "vobsub palette read" );
1814                 }
1815                 else
1816                 {
1817                     msg_Warn( &sys.demuxer, "reading original palette failed" );
1818                 }
1819                 free( psz_buf );
1820             }
1821         }
1822     }
1823     else if( !strcmp( p_tk->psz_codec, "S_HDMV/PGS" ) )
1824     {
1825         p_tk->fmt.i_codec = VLC_CODEC_BD_PG;
1826     }
1827     else if( !strcmp( p_tk->psz_codec, "B_VOBBTN" ) )
1828     {
1829         p_tk->fmt.i_cat = NAV_ES;
1830     }
1831     else
1832     {
1833         msg_Err( &sys.demuxer, "unknown codec id=`%s'", p_tk->psz_codec );
1834         p_tk->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1835     }
1836     return 0;
1837 }