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