1 /*****************************************************************************
2 * mkv.cpp : matroska demuxer
3 *****************************************************************************
4 * Copyright (C) 2003-2010 the VideoLAN team
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * Steve Lhomme <steve.lhomme@free.fr>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 #include "matroska_segment.hpp"
27 #include "chapters.hpp"
31 #include "Ebml_parser.hpp"
33 /*****************************************************************************
34 * Some functions to manipulate memory
35 *****************************************************************************/
36 static inline char * ToUTF8( const UTFstring
&u
)
38 return strdup( u
.GetUTF8().c_str() );
41 /*****************************************************************************
43 *****************************************************************************/
44 void matroska_segment_c::ParseSeekHead( KaxSeekHead
*seekhead
)
52 stream_Control( sys
.demuxer
.s
, STREAM_CAN_SEEK
, &b_seekable
);
56 ep
= new EbmlParser( &es
, seekhead
, &sys
.demuxer
);
58 while( ( l
= ep
->Get() ) != NULL
)
60 if( MKV_IS_ID( l
, KaxSeek
) )
62 EbmlId id
= EBML_ID(EbmlVoid
);
66 msg_Dbg( &sys
.demuxer
, "| | + Seek" );
69 while( ( l
= ep
->Get() ) != NULL
)
71 if( MKV_IS_ID( l
, KaxSeekID
) )
73 KaxSeekID
&sid
= *(KaxSeekID
*)l
;
74 sid
.ReadData( es
.I_O() );
75 id
= EbmlId( sid
.GetBuffer(), sid
.GetSize() );
77 else if( MKV_IS_ID( l
, KaxSeekPosition
) )
79 KaxSeekPosition
&spos
= *(KaxSeekPosition
*)l
;
80 spos
.ReadData( es
.I_O() );
81 i_pos
= (int64_t)segment
->GetGlobalPosition( uint64( spos
) );
85 /* Many mkvmerge files hit this case. It seems to be a broken SeekHead */
86 msg_Dbg( &sys
.demuxer
, "| | + Unknown (%s)", typeid(*l
).name() );
93 if( id
== EBML_ID(KaxCues
) )
95 msg_Dbg( &sys
.demuxer
, "| - cues at %"PRId64
, i_pos
);
96 LoadSeekHeadItem( EBML_INFO(KaxCues
), i_pos
);
98 else if( id
== EBML_ID(KaxInfo
) )
100 msg_Dbg( &sys
.demuxer
, "| - info at %"PRId64
, i_pos
);
101 LoadSeekHeadItem( EBML_INFO(KaxInfo
), i_pos
);
103 else if( id
== EBML_ID(KaxChapters
) )
105 msg_Dbg( &sys
.demuxer
, "| - chapters at %"PRId64
, i_pos
);
106 LoadSeekHeadItem( EBML_INFO(KaxChapters
), i_pos
);
108 else if( id
== EBML_ID(KaxTags
) )
110 msg_Dbg( &sys
.demuxer
, "| - tags at %"PRId64
, i_pos
);
111 LoadSeekHeadItem( EBML_INFO(KaxTags
), i_pos
);
113 else if( id
== EBML_ID(KaxSeekHead
) )
115 msg_Dbg( &sys
.demuxer
, "| - chained seekhead at %"PRId64
, i_pos
);
116 LoadSeekHeadItem( EBML_INFO(KaxSeekHead
), i_pos
);
118 else if( id
== EBML_ID(KaxTracks
) )
120 msg_Dbg( &sys
.demuxer
, "| - tracks at %"PRId64
, i_pos
);
121 LoadSeekHeadItem( EBML_INFO(KaxTracks
), i_pos
);
123 else if( id
== EBML_ID(KaxAttachments
) )
125 msg_Dbg( &sys
.demuxer
, "| - attachments at %"PRId64
, i_pos
);
126 LoadSeekHeadItem( EBML_INFO(KaxAttachments
), i_pos
);
130 msg_Dbg( &sys
.demuxer
, "| - unknown seekhead reference at %"PRId64
, i_pos
);
135 msg_Dbg( &sys
.demuxer
, "| | + ParseSeekHead Unknown (%s)", typeid(*l
).name() );
142 * Helper function to print the mkv parse tree
144 static void MkvTree( demux_t
& demuxer
, int i_level
, const char *psz_format
, ... )
149 msg_Err( &demuxer
, "MKV tree is too deep" );
152 va_start( args
, psz_format
);
153 static const char psz_foo
[] = "| | | | | | | | | |";
154 char *psz_foo2
= (char*)malloc( i_level
* 4 + 3 + strlen( psz_format
) );
155 strncpy( psz_foo2
, psz_foo
, 4 * i_level
);
156 psz_foo2
[ 4 * i_level
] = '+';
157 psz_foo2
[ 4 * i_level
+ 1 ] = ' ';
158 strcpy( &psz_foo2
[ 4 * i_level
+ 2 ], psz_format
);
159 msg_GenericVa( &demuxer
,VLC_MSG_DBG
, "mkv", psz_foo2
, args
);
165 /*****************************************************************************
167 *****************************************************************************/
168 void matroska_segment_c::ParseTrackEntry( KaxTrackEntry
*m
)
170 bool bSupported
= true;
173 mkv_track_t
*tk
= new mkv_track_t();
174 memset( tk
, 0, sizeof( mkv_track_t
) );
176 es_format_Init( &tk
->fmt
, UNKNOWN_ES
, 0 );
177 tk
->fmt
.psz_language
= strdup("English");
178 tk
->fmt
.psz_description
= NULL
;
180 tk
->b_default
= true;
181 tk
->b_enabled
= true;
182 tk
->b_silent
= false;
183 tk
->i_number
= tracks
.size() - 1;
184 tk
->i_extra_data
= 0;
185 tk
->p_extra_data
= NULL
;
186 tk
->psz_codec
= NULL
;
187 tk
->b_dts_only
= false;
188 tk
->i_default_duration
= 0;
189 tk
->f_timecodescale
= 1.0;
191 tk
->b_inited
= false;
193 tk
->p_data_init
= NULL
;
195 tk
->psz_codec_name
= NULL
;
196 tk
->psz_codec_settings
= NULL
;
197 tk
->psz_codec_info_url
= NULL
;
198 tk
->psz_codec_download_url
= NULL
;
200 tk
->i_compression_type
= MATROSKA_COMPRESSION_NONE
;
201 tk
->p_compression_data
= NULL
;
203 msg_Dbg( &sys
.demuxer
, "| | + Track Entry" );
205 for( size_t i
= 0; i
< m
->ListSize(); i
++ )
207 EbmlElement
*l
= (*m
)[i
];
209 if( MKV_IS_ID( l
, KaxTrackNumber
) )
211 KaxTrackNumber
&tnum
= *(KaxTrackNumber
*)l
;
213 tk
->i_number
= uint32( tnum
);
214 msg_Dbg( &sys
.demuxer
, "| | | + Track Number=%u", uint32( tnum
) );
216 else if( MKV_IS_ID( l
, KaxTrackUID
) )
218 KaxTrackUID
&tuid
= *(KaxTrackUID
*)l
;
220 msg_Dbg( &sys
.demuxer
, "| | | + Track UID=%u", uint32( tuid
) );
222 else if( MKV_IS_ID( l
, KaxTrackType
) )
224 const char *psz_type
;
225 KaxTrackType
&ttype
= *(KaxTrackType
*)l
;
227 switch( uint8(ttype
) )
231 tk
->fmt
.i_cat
= AUDIO_ES
;
235 tk
->fmt
.i_cat
= VIDEO_ES
;
238 psz_type
= "subtitle";
239 tk
->fmt
.i_cat
= SPU_ES
;
242 psz_type
= "buttons";
243 tk
->fmt
.i_cat
= SPU_ES
;
246 psz_type
= "unknown";
247 tk
->fmt
.i_cat
= UNKNOWN_ES
;
251 msg_Dbg( &sys
.demuxer
, "| | | + Track Type=%s", psz_type
);
253 else if( MKV_IS_ID( l
, KaxTrackFlagEnabled
) ) // UNUSED
255 KaxTrackFlagEnabled
&fenb
= *(KaxTrackFlagEnabled
*)l
;
257 // tk->b_enabled = uint32( fenb );
258 msg_Dbg( &sys
.demuxer
, "| | | + Track Enabled=%u", uint32( fenb
) );
260 else if( MKV_IS_ID( l
, KaxTrackFlagDefault
) )
262 KaxTrackFlagDefault
&fdef
= *(KaxTrackFlagDefault
*)l
;
264 tk
->b_default
= uint32( fdef
);
265 msg_Dbg( &sys
.demuxer
, "| | | + Track Default=%u", uint32( fdef
) );
267 else if( MKV_IS_ID( l
, KaxTrackFlagForced
) ) // UNUSED
269 KaxTrackFlagForced
&ffor
= *(KaxTrackFlagForced
*)l
;
271 msg_Dbg( &sys
.demuxer
, "| | | + Track Forced=%u", uint32( ffor
) );
273 else if( MKV_IS_ID( l
, KaxTrackFlagLacing
) ) // UNUSED
275 KaxTrackFlagLacing
&lac
= *(KaxTrackFlagLacing
*)l
;
277 msg_Dbg( &sys
.demuxer
, "| | | + Track Lacing=%d", uint32( lac
) );
279 else if( MKV_IS_ID( l
, KaxTrackMinCache
) ) // UNUSED
281 KaxTrackMinCache
&cmin
= *(KaxTrackMinCache
*)l
;
283 msg_Dbg( &sys
.demuxer
, "| | | + Track MinCache=%d", uint32( cmin
) );
285 else if( MKV_IS_ID( l
, KaxTrackMaxCache
) ) // UNUSED
287 KaxTrackMaxCache
&cmax
= *(KaxTrackMaxCache
*)l
;
289 msg_Dbg( &sys
.demuxer
, "| | | + Track MaxCache=%d", uint32( cmax
) );
291 else if( MKV_IS_ID( l
, KaxTrackDefaultDuration
) )
293 KaxTrackDefaultDuration
&defd
= *(KaxTrackDefaultDuration
*)l
;
295 tk
->i_default_duration
= uint64(defd
);
296 msg_Dbg( &sys
.demuxer
, "| | | + Track Default Duration=%"PRId64
, uint64(defd
) );
298 else if( MKV_IS_ID( l
, KaxTrackTimecodeScale
) )
300 KaxTrackTimecodeScale
&ttcs
= *(KaxTrackTimecodeScale
*)l
;
302 tk
->f_timecodescale
= float( ttcs
);
303 msg_Dbg( &sys
.demuxer
, "| | | + Track TimeCodeScale=%f", tk
->f_timecodescale
);
305 else if( MKV_IS_ID( l
, KaxMaxBlockAdditionID
) ) // UNUSED
307 KaxMaxBlockAdditionID
&mbl
= *(KaxMaxBlockAdditionID
*)l
;
309 msg_Dbg( &sys
.demuxer
, "| | | + Track Max BlockAdditionID=%d", uint32( mbl
) );
311 else if( MKV_IS_ID( l
, KaxTrackName
) )
313 KaxTrackName
&tname
= *(KaxTrackName
*)l
;
315 tk
->fmt
.psz_description
= ToUTF8( UTFstring( tname
) );
316 msg_Dbg( &sys
.demuxer
, "| | | + Track Name=%s", tk
->fmt
.psz_description
);
318 else if( MKV_IS_ID( l
, KaxTrackLanguage
) )
320 KaxTrackLanguage
&lang
= *(KaxTrackLanguage
*)l
;
322 free( tk
->fmt
.psz_language
);
323 tk
->fmt
.psz_language
= strdup( string( lang
).c_str() );
324 msg_Dbg( &sys
.demuxer
,
325 "| | | + Track Language=`%s'", tk
->fmt
.psz_language
);
327 else if( MKV_IS_ID( l
, KaxCodecID
) )
329 KaxCodecID
&codecid
= *(KaxCodecID
*)l
;
331 tk
->psz_codec
= strdup( string( codecid
).c_str() );
332 msg_Dbg( &sys
.demuxer
, "| | | + Track CodecId=%s", string( codecid
).c_str() );
334 else if( MKV_IS_ID( l
, KaxCodecPrivate
) )
336 KaxCodecPrivate
&cpriv
= *(KaxCodecPrivate
*)l
;
338 tk
->i_extra_data
= cpriv
.GetSize();
339 if( tk
->i_extra_data
> 0 )
341 tk
->p_extra_data
= (uint8_t*)malloc( tk
->i_extra_data
);
342 memcpy( tk
->p_extra_data
, cpriv
.GetBuffer(), tk
->i_extra_data
);
344 msg_Dbg( &sys
.demuxer
, "| | | + Track CodecPrivate size=%"PRId64
, cpriv
.GetSize() );
346 else if( MKV_IS_ID( l
, KaxCodecName
) )
348 KaxCodecName
&cname
= *(KaxCodecName
*)l
;
350 tk
->psz_codec_name
= ToUTF8( UTFstring( cname
) );
351 msg_Dbg( &sys
.demuxer
, "| | | + Track Codec Name=%s", tk
->psz_codec_name
);
354 else if( MKV_IS_ID( l
, KaxCodecDecodeAll
) ) // UNUSED
356 KaxCodecDecodeAll
&cdall
= *(KaxCodecDecodeAll
*)l
;
358 msg_Dbg( &sys
.demuxer
, "| | | + Track Codec Decode All=%u", uint8( cdall
) );
360 else if( MKV_IS_ID( l
, KaxTrackOverlay
) ) // UNUSED
362 KaxTrackOverlay
&tovr
= *(KaxTrackOverlay
*)l
;
364 msg_Dbg( &sys
.demuxer
, "| | | + Track Overlay=%u", uint32( tovr
) );
366 else if( MKV_IS_ID( l
, KaxContentEncodings
) )
368 EbmlMaster
*cencs
= static_cast<EbmlMaster
*>(l
);
369 MkvTree( sys
.demuxer
, 3, "Content Encodings" );
370 if ( cencs
->ListSize() > 1 )
372 msg_Err( &sys
.demuxer
, "Multiple Compression method not supported" );
375 for( size_t j
= 0; j
< cencs
->ListSize(); j
++ )
377 EbmlElement
*l2
= (*cencs
)[j
];
378 if( MKV_IS_ID( l2
, KaxContentEncoding
) )
380 MkvTree( sys
.demuxer
, 4, "Content Encoding" );
381 EbmlMaster
*cenc
= static_cast<EbmlMaster
*>(l2
);
382 for( size_t k
= 0; k
< cenc
->ListSize(); k
++ )
384 EbmlElement
*l3
= (*cenc
)[k
];
385 if( MKV_IS_ID( l3
, KaxContentEncodingOrder
) )
387 KaxContentEncodingOrder
&encord
= *(KaxContentEncodingOrder
*)l3
;
388 MkvTree( sys
.demuxer
, 5, "Order: %i", uint32( encord
) );
390 else if( MKV_IS_ID( l3
, KaxContentEncodingScope
) )
392 KaxContentEncodingScope
&encscope
= *(KaxContentEncodingScope
*)l3
;
393 MkvTree( sys
.demuxer
, 5, "Scope: %i", uint32( encscope
) );
395 else if( MKV_IS_ID( l3
, KaxContentEncodingType
) )
397 KaxContentEncodingType
&enctype
= *(KaxContentEncodingType
*)l3
;
398 MkvTree( sys
.demuxer
, 5, "Type: %i", uint32( enctype
) );
400 else if( MKV_IS_ID( l3
, KaxContentCompression
) )
402 EbmlMaster
*compr
= static_cast<EbmlMaster
*>(l3
);
403 MkvTree( sys
.demuxer
, 5, "Content Compression" );
404 //Default compression type is 0 (Zlib)
405 tk
->i_compression_type
= MATROSKA_COMPRESSION_ZLIB
;
406 for( size_t n
= 0; n
< compr
->ListSize(); n
++ )
408 EbmlElement
*l4
= (*compr
)[n
];
409 if( MKV_IS_ID( l4
, KaxContentCompAlgo
) )
411 KaxContentCompAlgo
&compalg
= *(KaxContentCompAlgo
*)l4
;
412 MkvTree( sys
.demuxer
, 6, "Compression Algorithm: %i", uint32(compalg
) );
413 tk
->i_compression_type
= uint32( compalg
);
414 if ( ( tk
->i_compression_type
!= MATROSKA_COMPRESSION_ZLIB
) &&
415 ( tk
->i_compression_type
!= MATROSKA_COMPRESSION_HEADER
) )
417 msg_Err( &sys
.demuxer
, "Track Compression method %d not supported", tk
->i_compression_type
);
421 else if( MKV_IS_ID( l4
, KaxContentCompSettings
) )
423 tk
->p_compression_data
= new KaxContentCompSettings( *(KaxContentCompSettings
*)l4
);
427 MkvTree( sys
.demuxer
, 6, "Unknown (%s)", typeid(*l4
).name() );
431 // ContentEncryption Unsupported
434 MkvTree( sys
.demuxer
, 5, "Unknown (%s)", typeid(*l3
).name() );
440 MkvTree( sys
.demuxer
, 4, "Unknown (%s)", typeid(*l2
).name() );
444 // else if( MKV_IS_ID( l, KaxCodecSettings) ) DEPRECATED by matroska
446 // KaxCodecSettings &cset = *(KaxCodecSettings*)l;
448 // tk->psz_codec_settings = ToUTF8( UTFstring( cset ) );
449 // msg_Dbg( &sys.demuxer, "| | | + Track Codec Settings=%s", tk->psz_codec_settings );
451 // else if( MKV_IS_ID( l, KaxCodecInfoURL) ) DEPRECATED by matroska
453 // KaxCodecInfoURL &ciurl = *(KaxCodecInfoURL*)l;
455 // tk->psz_codec_info_url = strdup( string( ciurl ).c_str() );
456 // msg_Dbg( &sys.demuxer, "| | | + Track Codec Info URL=%s", tk->psz_codec_info_url );
458 // else if( MKV_IS_ID( l, KaxCodecDownloadURL) ) DEPRECATED by matroska
460 // KaxCodecDownloadURL &cdurl = *(KaxCodecDownloadURL*)l;
462 // tk->psz_codec_download_url = strdup( string( cdurl ).c_str() );
463 // msg_Dbg( &sys.demuxer, "| | | + Track Codec Info URL=%s", tk->psz_codec_download_url );
465 else if( MKV_IS_ID( l
, KaxTrackVideo
) )
467 EbmlMaster
*tkv
= static_cast<EbmlMaster
*>(l
);
468 unsigned int i_crop_right
= 0, i_crop_left
= 0, i_crop_top
= 0, i_crop_bottom
= 0;
469 unsigned int i_display_unit
= 0, i_display_width
= 0, i_display_height
= 0;
471 msg_Dbg( &sys
.demuxer
, "| | | + Track Video" );
474 tk
->fmt
.video
.i_frame_rate_base
= (unsigned int)(tk
->i_default_duration
/ 1000);
475 tk
->fmt
.video
.i_frame_rate
= 1000000;
477 for( unsigned int j
= 0; j
< tkv
->ListSize(); j
++ )
479 EbmlElement
*l
= (*tkv
)[j
];
480 if( MKV_IS_ID( l
, KaxVideoFlagInterlaced
) ) // UNUSED
482 KaxVideoFlagInterlaced
&fint
= *(KaxVideoFlagInterlaced
*)l
;
484 msg_Dbg( &sys
.demuxer
, "| | | | + Track Video Interlaced=%u", uint8( fint
) );
486 else if( MKV_IS_ID( l
, KaxVideoStereoMode
) ) // UNUSED
488 KaxVideoStereoMode
&stereo
= *(KaxVideoStereoMode
*)l
;
490 msg_Dbg( &sys
.demuxer
, "| | | | + Track Video Stereo Mode=%u", uint8( stereo
) );
492 else if( MKV_IS_ID( l
, KaxVideoPixelWidth
) )
494 KaxVideoPixelWidth
&vwidth
= *(KaxVideoPixelWidth
*)l
;
496 tk
->fmt
.video
.i_width
+= uint16( vwidth
);
497 msg_Dbg( &sys
.demuxer
, "| | | | + width=%d", uint16( vwidth
) );
499 else if( MKV_IS_ID( l
, KaxVideoPixelHeight
) )
501 KaxVideoPixelWidth
&vheight
= *(KaxVideoPixelWidth
*)l
;
503 tk
->fmt
.video
.i_height
+= uint16( vheight
);
504 msg_Dbg( &sys
.demuxer
, "| | | | + height=%d", uint16( vheight
) );
506 else if( MKV_IS_ID( l
, KaxVideoDisplayWidth
) )
508 KaxVideoDisplayWidth
&vwidth
= *(KaxVideoDisplayWidth
*)l
;
510 i_display_width
= uint16( vwidth
);
511 msg_Dbg( &sys
.demuxer
, "| | | | + display width=%d", uint16( vwidth
) );
513 else if( MKV_IS_ID( l
, KaxVideoDisplayHeight
) )
515 KaxVideoDisplayWidth
&vheight
= *(KaxVideoDisplayWidth
*)l
;
517 i_display_height
= uint16( vheight
);
518 msg_Dbg( &sys
.demuxer
, "| | | | + display height=%d", uint16( vheight
) );
520 else if( MKV_IS_ID( l
, KaxVideoPixelCropBottom
) )
522 KaxVideoPixelCropBottom
&cropval
= *(KaxVideoPixelCropBottom
*)l
;
524 i_crop_bottom
= uint16( cropval
);
525 msg_Dbg( &sys
.demuxer
, "| | | | + crop pixel bottom=%d", uint16( cropval
) );
527 else if( MKV_IS_ID( l
, KaxVideoPixelCropTop
) )
529 KaxVideoPixelCropTop
&cropval
= *(KaxVideoPixelCropTop
*)l
;
531 i_crop_top
= uint16( cropval
);
532 msg_Dbg( &sys
.demuxer
, "| | | | + crop pixel top=%d", uint16( cropval
) );
534 else if( MKV_IS_ID( l
, KaxVideoPixelCropRight
) )
536 KaxVideoPixelCropRight
&cropval
= *(KaxVideoPixelCropRight
*)l
;
538 i_crop_right
= uint16( cropval
);
539 msg_Dbg( &sys
.demuxer
, "| | | | + crop pixel right=%d", uint16( cropval
) );
541 else if( MKV_IS_ID( l
, KaxVideoPixelCropLeft
) )
543 KaxVideoPixelCropLeft
&cropval
= *(KaxVideoPixelCropLeft
*)l
;
545 i_crop_left
= uint16( cropval
);
546 msg_Dbg( &sys
.demuxer
, "| | | | + crop pixel left=%d", uint16( cropval
) );
548 else if( MKV_IS_ID( l
, KaxVideoDisplayUnit
) )
550 KaxVideoDisplayUnit
&vdmode
= *(KaxVideoDisplayUnit
*)l
;
552 i_display_unit
= uint8( vdmode
);
553 msg_Dbg( &sys
.demuxer
, "| | | | + Track Video Display Unit=%s",
554 i_display_unit
== 0 ? "pixels" : ( i_display_unit
== 1 ? "centimeters": "inches" ) );
556 else if( MKV_IS_ID( l
, KaxVideoAspectRatio
) ) // UNUSED
558 KaxVideoAspectRatio
&ratio
= *(KaxVideoAspectRatio
*)l
;
560 msg_Dbg( &sys
.demuxer
, " | | | + Track Video Aspect Ratio Type=%u", uint8( ratio
) );
562 // ColourSpace UNUSED
563 else if( MKV_IS_ID( l
, KaxVideoFrameRate
) )
565 KaxVideoFrameRate
&vfps
= *(KaxVideoFrameRate
*)l
;
567 tk
->f_fps
= float( vfps
);
568 msg_Dbg( &sys
.demuxer
, " | | | + fps=%f", float( vfps
) );
570 // else if( MKV_IS_ID( l, KaxVideoGamma) ) //DEPRECATED by Matroska
572 // KaxVideoGamma &gamma = *(KaxVideoGamma*)l;
574 // msg_Dbg( &sys.demuxer, " | | | + gamma=%f", float( gamma ) );
578 msg_Dbg( &sys
.demuxer
, "| | | | + Unknown (%s)", typeid(*l
).name() );
581 if( i_display_height
&& i_display_width
)
583 tk
->fmt
.video
.i_sar_num
= i_display_width
* tk
->fmt
.video
.i_height
;
584 tk
->fmt
.video
.i_sar_den
= i_display_height
* tk
->fmt
.video
.i_width
;
586 if( i_crop_left
|| i_crop_right
|| i_crop_top
|| i_crop_bottom
)
588 tk
->fmt
.video
.i_visible_width
= tk
->fmt
.video
.i_width
;
589 tk
->fmt
.video
.i_visible_height
= tk
->fmt
.video
.i_height
;
590 tk
->fmt
.video
.i_x_offset
= i_crop_left
;
591 tk
->fmt
.video
.i_y_offset
= i_crop_top
;
592 tk
->fmt
.video
.i_visible_width
-= i_crop_left
+ i_crop_right
;
593 tk
->fmt
.video
.i_visible_height
-= i_crop_top
+ i_crop_bottom
;
595 /* FIXME: i_display_* allows you to not only set DAR, but also a zoom factor.
596 we do not support this atm */
598 else if( MKV_IS_ID( l
, KaxTrackAudio
) )
600 EbmlMaster
*tka
= static_cast<EbmlMaster
*>(l
);
602 msg_Dbg( &sys
.demuxer
, "| | | + Track Audio" );
604 for( unsigned int j
= 0; j
< tka
->ListSize(); j
++ )
606 EbmlElement
*l
= (*tka
)[j
];
608 if( MKV_IS_ID( l
, KaxAudioSamplingFreq
) )
610 KaxAudioSamplingFreq
&afreq
= *(KaxAudioSamplingFreq
*)l
;
612 tk
->i_original_rate
= tk
->fmt
.audio
.i_rate
= (int)float( afreq
);
613 msg_Dbg( &sys
.demuxer
, "| | | | + afreq=%d", tk
->fmt
.audio
.i_rate
);
615 else if( MKV_IS_ID( l
, KaxAudioOutputSamplingFreq
) )
617 KaxAudioOutputSamplingFreq
&afreq
= *(KaxAudioOutputSamplingFreq
*)l
;
619 tk
->fmt
.audio
.i_rate
= (int)float( afreq
);
620 msg_Dbg( &sys
.demuxer
, "| | | | + aoutfreq=%d", tk
->fmt
.audio
.i_rate
);
622 else if( MKV_IS_ID( l
, KaxAudioChannels
) )
624 KaxAudioChannels
&achan
= *(KaxAudioChannels
*)l
;
626 tk
->fmt
.audio
.i_channels
= uint8( achan
);
627 msg_Dbg( &sys
.demuxer
, "| | | | + achan=%u", uint8( achan
) );
629 else if( MKV_IS_ID( l
, KaxAudioBitDepth
) )
631 KaxAudioBitDepth
&abits
= *(KaxAudioBitDepth
*)l
;
633 tk
->fmt
.audio
.i_bitspersample
= uint8( abits
);
634 msg_Dbg( &sys
.demuxer
, "| | | | + abits=%u", uint8( abits
) );
638 msg_Dbg( &sys
.demuxer
, "| | | | + Unknown (%s)", typeid(*l
).name() );
644 msg_Dbg( &sys
.demuxer
, "| | | + Unknown (%s)",
651 tracks
.push_back( tk
);
655 msg_Err( &sys
.demuxer
, "Track Entry %d not supported", tk
->i_number
);
660 /*****************************************************************************
662 *****************************************************************************/
663 void matroska_segment_c::ParseTracks( KaxTracks
*tracks
)
666 int i_upper_level
= 0;
668 /* Master elements */
669 tracks
->Read( es
, EBML_CONTEXT(tracks
), i_upper_level
, el
, true );
671 for( size_t i
= 0; i
< tracks
->ListSize(); i
++ )
673 EbmlElement
*l
= (*tracks
)[i
];
675 if( MKV_IS_ID( l
, KaxTrackEntry
) )
677 ParseTrackEntry( static_cast<KaxTrackEntry
*>(l
) );
681 msg_Dbg( &sys
.demuxer
, "| | + Unknown (%s)", typeid(*l
).name() );
686 /*****************************************************************************
688 *****************************************************************************/
689 void matroska_segment_c::ParseInfo( KaxInfo
*info
)
693 int i_upper_level
= 0;
695 /* Master elements */
696 m
= static_cast<EbmlMaster
*>(info
);
697 m
->Read( es
, EBML_CONTEXT(info
), i_upper_level
, el
, true );
699 for( size_t i
= 0; i
< m
->ListSize(); i
++ )
701 EbmlElement
*l
= (*m
)[i
];
703 if( MKV_IS_ID( l
, KaxSegmentUID
) )
705 if ( p_segment_uid
== NULL
)
706 p_segment_uid
= new KaxSegmentUID(*static_cast<KaxSegmentUID
*>(l
));
708 msg_Dbg( &sys
.demuxer
, "| | + UID=%d", *(uint32
*)p_segment_uid
->GetBuffer() );
710 else if( MKV_IS_ID( l
, KaxPrevUID
) )
712 if ( p_prev_segment_uid
== NULL
)
713 p_prev_segment_uid
= new KaxPrevUID(*static_cast<KaxPrevUID
*>(l
));
715 msg_Dbg( &sys
.demuxer
, "| | + PrevUID=%d", *(uint32
*)p_prev_segment_uid
->GetBuffer() );
717 else if( MKV_IS_ID( l
, KaxNextUID
) )
719 if ( p_next_segment_uid
== NULL
)
720 p_next_segment_uid
= new KaxNextUID(*static_cast<KaxNextUID
*>(l
));
722 msg_Dbg( &sys
.demuxer
, "| | + NextUID=%d", *(uint32
*)p_next_segment_uid
->GetBuffer() );
724 else if( MKV_IS_ID( l
, KaxTimecodeScale
) )
726 KaxTimecodeScale
&tcs
= *(KaxTimecodeScale
*)l
;
728 i_timescale
= uint64(tcs
);
730 msg_Dbg( &sys
.demuxer
, "| | + TimecodeScale=%"PRId64
,
733 else if( MKV_IS_ID( l
, KaxDuration
) )
735 KaxDuration
&dur
= *(KaxDuration
*)l
;
737 i_duration
= mtime_t( double( dur
) );
739 msg_Dbg( &sys
.demuxer
, "| | + Duration=%"PRId64
,
742 else if( MKV_IS_ID( l
, KaxMuxingApp
) )
744 KaxMuxingApp
&mapp
= *(KaxMuxingApp
*)l
;
746 psz_muxing_application
= ToUTF8( UTFstring( mapp
) );
748 msg_Dbg( &sys
.demuxer
, "| | + Muxing Application=%s",
749 psz_muxing_application
);
751 else if( MKV_IS_ID( l
, KaxWritingApp
) )
753 KaxWritingApp
&wapp
= *(KaxWritingApp
*)l
;
755 psz_writing_application
= ToUTF8( UTFstring( wapp
) );
757 msg_Dbg( &sys
.demuxer
, "| | + Writing Application=%s",
758 psz_writing_application
);
760 else if( MKV_IS_ID( l
, KaxSegmentFilename
) )
762 KaxSegmentFilename
&sfn
= *(KaxSegmentFilename
*)l
;
764 psz_segment_filename
= ToUTF8( UTFstring( sfn
) );
766 msg_Dbg( &sys
.demuxer
, "| | + Segment Filename=%s",
767 psz_segment_filename
);
769 else if( MKV_IS_ID( l
, KaxTitle
) )
771 KaxTitle
&title
= *(KaxTitle
*)l
;
773 psz_title
= ToUTF8( UTFstring( title
) );
775 msg_Dbg( &sys
.demuxer
, "| | + Title=%s", psz_title
);
777 else if( MKV_IS_ID( l
, KaxSegmentFamily
) )
779 KaxSegmentFamily
*uid
= static_cast<KaxSegmentFamily
*>(l
);
781 families
.push_back( new KaxSegmentFamily(*uid
) );
783 msg_Dbg( &sys
.demuxer
, "| | + family=%d", *(uint32
*)uid
->GetBuffer() );
785 else if( MKV_IS_ID( l
, KaxDateUTC
) )
787 KaxDateUTC
&date
= *(KaxDateUTC
*)l
;
792 i_date
= date
.GetEpochDate();
793 if( gmtime_r( &i_date
, &tmres
) &&
794 strftime( buffer
, sizeof(buffer
), "%a %b %d %H:%M:%S %Y",
797 psz_date_utc
= strdup( buffer
);
798 msg_Dbg( &sys
.demuxer
, "| | + Date=%s", buffer
);
801 else if( MKV_IS_ID( l
, KaxChapterTranslate
) )
803 KaxChapterTranslate
*p_trans
= static_cast<KaxChapterTranslate
*>( l
);
804 chapter_translation_c
*p_translate
= new chapter_translation_c();
806 p_trans
->Read( es
, EBML_CONTEXT(p_trans
), i_upper_level
, el
, true );
807 for( size_t j
= 0; j
< p_trans
->ListSize(); j
++ )
809 EbmlElement
*l
= (*p_trans
)[j
];
811 if( MKV_IS_ID( l
, KaxChapterTranslateEditionUID
) )
813 p_translate
->editions
.push_back( uint64( *static_cast<KaxChapterTranslateEditionUID
*>( l
) ) );
815 else if( MKV_IS_ID( l
, KaxChapterTranslateCodec
) )
817 p_translate
->codec_id
= uint32( *static_cast<KaxChapterTranslateCodec
*>( l
) );
819 else if( MKV_IS_ID( l
, KaxChapterTranslateID
) )
821 p_translate
->p_translated
= new KaxChapterTranslateID( *static_cast<KaxChapterTranslateID
*>( l
) );
825 translations
.push_back( p_translate
);
829 msg_Dbg( &sys
.demuxer
, "| | + Unknown (%s)", typeid(*l
).name() );
833 double f_dur
= double(i_duration
) * double(i_timescale
) / 1000000.0;
834 i_duration
= mtime_t(f_dur
);
838 /*****************************************************************************
840 *****************************************************************************/
841 void matroska_segment_c::ParseChapterAtom( int i_level
, KaxChapterAtom
*ca
, chapter_item_c
& chapters
)
843 msg_Dbg( &sys
.demuxer
, "| | | + ChapterAtom (level=%d)", i_level
);
844 for( size_t i
= 0; i
< ca
->ListSize(); i
++ )
846 EbmlElement
*l
= (*ca
)[i
];
848 if( MKV_IS_ID( l
, KaxChapterUID
) )
850 chapters
.i_uid
= uint64_t(*(KaxChapterUID
*)l
);
851 msg_Dbg( &sys
.demuxer
, "| | | | + ChapterUID: %"PRIu64
"", chapters
.i_uid
);
853 else if( MKV_IS_ID( l
, KaxChapterFlagHidden
) )
855 KaxChapterFlagHidden
&flag
=*(KaxChapterFlagHidden
*)l
;
856 chapters
.b_display_seekpoint
= uint8( flag
) == 0;
858 msg_Dbg( &sys
.demuxer
, "| | | | + ChapterFlagHidden: %s", chapters
.b_display_seekpoint
? "no":"yes" );
860 else if( MKV_IS_ID( l
, KaxChapterSegmentUID
) )
862 chapters
.p_segment_uid
= new KaxChapterSegmentUID( *static_cast<KaxChapterSegmentUID
*>(l
) );
863 msg_Dbg( &sys
.demuxer
, "| | | | + ChapterSegmentUID= %u", *(uint32
*)chapters
.p_segment_uid
->GetBuffer() );
865 else if( MKV_IS_ID( l
, KaxChapterSegmentEditionUID
) )
867 chapters
.p_segment_edition_uid
= new KaxChapterSegmentEditionUID( *static_cast<KaxChapterSegmentEditionUID
*>(l
) );
868 msg_Dbg( &sys
.demuxer
, "| | | | + ChapterSegmentEditionUID= %u",
869 #if LIBMATROSKA_VERSION < 0x010300
870 *(uint32
*)chapters
.p_segment_edition_uid
->GetBuffer()
872 *(uint32
*)chapters
.p_segment_edition_uid
876 else if( MKV_IS_ID( l
, KaxChapterTimeStart
) )
878 KaxChapterTimeStart
&start
=*(KaxChapterTimeStart
*)l
;
879 chapters
.i_start_time
= uint64( start
) / INT64_C(1000);
881 msg_Dbg( &sys
.demuxer
, "| | | | + ChapterTimeStart: %"PRId64
"", chapters
.i_start_time
);
883 else if( MKV_IS_ID( l
, KaxChapterTimeEnd
) )
885 KaxChapterTimeEnd
&end
=*(KaxChapterTimeEnd
*)l
;
886 chapters
.i_end_time
= uint64( end
) / INT64_C(1000);
888 msg_Dbg( &sys
.demuxer
, "| | | | + ChapterTimeEnd: %"PRId64
"", chapters
.i_end_time
);
890 else if( MKV_IS_ID( l
, KaxChapterDisplay
) )
892 EbmlMaster
*cd
= static_cast<EbmlMaster
*>(l
);
894 msg_Dbg( &sys
.demuxer
, "| | | | + ChapterDisplay" );
895 for( size_t j
= 0; j
< cd
->ListSize(); j
++ )
897 EbmlElement
*l
= (*cd
)[j
];
899 if( MKV_IS_ID( l
, KaxChapterString
) )
901 KaxChapterString
&name
=*(KaxChapterString
*)l
;
902 for ( int k
= 0; k
< i_level
; k
++)
903 chapters
.psz_name
+= '+';
904 chapters
.psz_name
+= ' ';
905 char *psz_tmp_utf8
= ToUTF8( UTFstring( name
) );
906 chapters
.psz_name
+= psz_tmp_utf8
;
907 chapters
.b_user_display
= true;
909 msg_Dbg( &sys
.demuxer
, "| | | | | + ChapterString '%s'", psz_tmp_utf8
);
910 free( psz_tmp_utf8
);
912 else if( MKV_IS_ID( l
, KaxChapterLanguage
) )
914 KaxChapterLanguage
&lang
=*(KaxChapterLanguage
*)l
;
915 const char *psz
= string( lang
).c_str();
917 msg_Dbg( &sys
.demuxer
, "| | | | | + ChapterLanguage '%s'", psz
);
919 else if( MKV_IS_ID( l
, KaxChapterCountry
) )
921 KaxChapterCountry
&ct
=*(KaxChapterCountry
*)l
;
922 const char *psz
= string( ct
).c_str();
924 msg_Dbg( &sys
.demuxer
, "| | | | | + ChapterCountry '%s'", psz
);
928 else if( MKV_IS_ID( l
, KaxChapterProcess
) )
930 msg_Dbg( &sys
.demuxer
, "| | | | + ChapterProcess" );
932 KaxChapterProcess
*cp
= static_cast<KaxChapterProcess
*>(l
);
933 chapter_codec_cmds_c
*p_ccodec
= NULL
;
935 for( size_t j
= 0; j
< cp
->ListSize(); j
++ )
937 EbmlElement
*k
= (*cp
)[j
];
939 if( MKV_IS_ID( k
, KaxChapterProcessCodecID
) )
941 KaxChapterProcessCodecID
*p_codec_id
= static_cast<KaxChapterProcessCodecID
*>( k
);
942 if ( uint32(*p_codec_id
) == 0 )
943 p_ccodec
= new matroska_script_codec_c( sys
);
944 else if ( uint32(*p_codec_id
) == 1 )
945 p_ccodec
= new dvd_chapter_codec_c( sys
);
950 if ( p_ccodec
!= NULL
)
952 for( size_t j
= 0; j
< cp
->ListSize(); j
++ )
954 EbmlElement
*k
= (*cp
)[j
];
956 if( MKV_IS_ID( k
, KaxChapterProcessPrivate
) )
958 KaxChapterProcessPrivate
* p_private
= static_cast<KaxChapterProcessPrivate
*>( k
);
959 p_ccodec
->SetPrivate( *p_private
);
961 else if( MKV_IS_ID( k
, KaxChapterProcessCommand
) )
963 p_ccodec
->AddCommand( *static_cast<KaxChapterProcessCommand
*>( k
) );
966 chapters
.codecs
.push_back( p_ccodec
);
969 else if( MKV_IS_ID( l
, KaxChapterAtom
) )
971 chapter_item_c
*new_sub_chapter
= new chapter_item_c();
972 ParseChapterAtom( i_level
+1, static_cast<KaxChapterAtom
*>(l
), *new_sub_chapter
);
973 new_sub_chapter
->p_parent
= &chapters
;
974 chapters
.sub_chapters
.push_back( new_sub_chapter
);
979 /*****************************************************************************
981 *****************************************************************************/
982 void matroska_segment_c::ParseAttachments( KaxAttachments
*attachments
)
985 int i_upper_level
= 0;
987 attachments
->Read( es
, EBML_CONTEXT(attachments
), i_upper_level
, el
, true );
989 KaxAttached
*attachedFile
= FindChild
<KaxAttached
>( *attachments
);
991 while( attachedFile
&& ( attachedFile
->GetSize() > 0 ) )
993 KaxFileData
&img_data
= GetChild
<KaxFileData
>( *attachedFile
);
994 attachment_c
*new_attachment
= new attachment_c( ToUTF8( UTFstring( GetChild
<KaxFileName
>( *attachedFile
) ) ),
995 GetChild
<KaxMimeType
>( *attachedFile
),
996 img_data
.GetSize() );
998 msg_Dbg( &sys
.demuxer
, "| | - %s (%s)", new_attachment
->fileName(), new_attachment
->mimeType() );
1000 if( new_attachment
->init() )
1002 memcpy( new_attachment
->p_data
, img_data
.GetBuffer(), img_data
.GetSize() );
1003 sys
.stored_attachments
.push_back( new_attachment
);
1007 delete new_attachment
;
1010 attachedFile
= &GetNextChild
<KaxAttached
>( *attachments
, *attachedFile
);
1014 /*****************************************************************************
1016 *****************************************************************************/
1017 void matroska_segment_c::ParseChapters( KaxChapters
*chapters
)
1020 int i_upper_level
= 0;
1022 /* Master elements */
1023 chapters
->Read( es
, EBML_CONTEXT(chapters
), i_upper_level
, el
, true );
1025 for( size_t i
= 0; i
< chapters
->ListSize(); i
++ )
1027 EbmlElement
*l
= (*chapters
)[i
];
1029 if( MKV_IS_ID( l
, KaxEditionEntry
) )
1031 chapter_edition_c
*p_edition
= new chapter_edition_c();
1033 EbmlMaster
*E
= static_cast<EbmlMaster
*>(l
);
1034 msg_Dbg( &sys
.demuxer
, "| | + EditionEntry" );
1035 for( size_t j
= 0; j
< E
->ListSize(); j
++ )
1037 EbmlElement
*l
= (*E
)[j
];
1039 if( MKV_IS_ID( l
, KaxChapterAtom
) )
1041 chapter_item_c
*new_sub_chapter
= new chapter_item_c();
1042 ParseChapterAtom( 0, static_cast<KaxChapterAtom
*>(l
), *new_sub_chapter
);
1043 p_edition
->sub_chapters
.push_back( new_sub_chapter
);
1045 else if( MKV_IS_ID( l
, KaxEditionUID
) )
1047 p_edition
->i_uid
= uint64(*static_cast<KaxEditionUID
*>( l
));
1049 else if( MKV_IS_ID( l
, KaxEditionFlagOrdered
) )
1051 p_edition
->b_ordered
= var_InheritBool( &sys
.demuxer
, "mkv-use-ordered-chapters" ) ? (uint8(*static_cast<KaxEditionFlagOrdered
*>( l
)) != 0) : 0;
1053 else if( MKV_IS_ID( l
, KaxEditionFlagDefault
) )
1055 if (uint8(*static_cast<KaxEditionFlagDefault
*>( l
)) != 0)
1056 i_default_edition
= stored_editions
.size();
1058 else if( MKV_IS_ID( l
, KaxEditionFlagHidden
) )
1060 // FIXME to implement
1064 msg_Dbg( &sys
.demuxer
, "| | | + Unknown (%s)", typeid(*l
).name() );
1067 stored_editions
.push_back( p_edition
);
1071 msg_Dbg( &sys
.demuxer
, "| | + Unknown (%s)", typeid(*l
).name() );
1076 void matroska_segment_c::ParseCluster( )
1080 int i_upper_level
= 0;
1082 /* Master elements */
1083 m
= static_cast<EbmlMaster
*>( cluster
);
1084 m
->Read( es
, EBML_CONTEXT(cluster
), i_upper_level
, el
, true );
1086 for( unsigned int i
= 0; i
< m
->ListSize(); i
++ )
1088 EbmlElement
*l
= (*m
)[i
];
1090 if( MKV_IS_ID( l
, KaxClusterTimecode
) )
1092 KaxClusterTimecode
&ctc
= *(KaxClusterTimecode
*)l
;
1094 cluster
->InitTimecode( uint64( ctc
), i_timescale
);
1099 i_start_time
= cluster
->GlobalTimecode() / 1000;