@ -2731,6 +2731,72 @@ static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0 ;
}
static int mov_read_uuid ( MOVContext * c , AVIOContext * pb , MOVAtom atom )
{
int ret ;
uint8_t uuid [ 16 ] ;
static const uint8_t uuid_isml_manifest [ ] = {
0xa5 , 0xd4 , 0x0b , 0x30 , 0xe8 , 0x14 , 0x11 , 0xdd ,
0xba , 0x2f , 0x08 , 0x00 , 0x20 , 0x0c , 0x9a , 0x66
} ;
if ( atom . size < sizeof ( uuid ) | | atom . size = = INT64_MAX )
return AVERROR_INVALIDDATA ;
ret = avio_read ( pb , uuid , sizeof ( uuid ) ) ;
if ( ret < 0 ) {
return ret ;
} else if ( ret ! = sizeof ( uuid ) ) {
return AVERROR_INVALIDDATA ;
}
if ( ! memcmp ( uuid , uuid_isml_manifest , sizeof ( uuid ) ) ) {
uint8_t * buffer , * ptr ;
char * endptr ;
size_t len = atom . size - sizeof ( uuid ) ;
if ( len < 4 ) {
return AVERROR_INVALIDDATA ;
}
ret = avio_skip ( pb , 4 ) ; // zeroes
len - = 4 ;
buffer = av_mallocz ( len + 1 ) ;
if ( ! buffer ) {
return AVERROR ( ENOMEM ) ;
}
ret = avio_read ( pb , buffer , len ) ;
if ( ret < 0 ) {
av_free ( buffer ) ;
return ret ;
} else if ( ret ! = len ) {
av_free ( buffer ) ;
return AVERROR_INVALIDDATA ;
}
ptr = buffer ;
while ( ( ptr = av_stristr ( ptr , " systemBitrate= \" " ) ) ! = NULL ) {
ptr + = sizeof ( " systemBitrate= \" " ) - 1 ;
c - > bitrates_count + + ;
c - > bitrates = av_realloc_f ( c - > bitrates , c - > bitrates_count , sizeof ( * c - > bitrates ) ) ;
if ( ! c - > bitrates ) {
c - > bitrates_count = 0 ;
av_free ( buffer ) ;
return AVERROR ( ENOMEM ) ;
}
errno = 0 ;
ret = strtol ( ptr , & endptr , 10 ) ;
if ( ret < 0 | | errno | | * endptr ! = ' " ' ) {
c - > bitrates [ c - > bitrates_count - 1 ] = 0 ;
} else {
c - > bitrates [ c - > bitrates_count - 1 ] = ret ;
}
}
av_free ( buffer ) ;
}
return 0 ;
}
static const MOVParseTableEntry mov_default_parse_table [ ] = {
{ MKTAG ( ' A ' , ' C ' , ' L ' , ' R ' ) , mov_read_avid } ,
{ MKTAG ( ' A ' , ' P ' , ' R ' , ' G ' ) , mov_read_avid } ,
@ -2794,6 +2860,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG ( ' c ' , ' h ' , ' a ' , ' n ' ) , mov_read_chan } , /* channel layout */
{ MKTAG ( ' d ' , ' v ' , ' c ' , ' 1 ' ) , mov_read_dvc1 } ,
{ MKTAG ( ' s ' , ' b ' , ' g ' , ' p ' ) , mov_read_sbgp } ,
{ MKTAG ( ' u ' , ' u ' , ' i ' , ' d ' ) , mov_read_uuid } ,
{ 0 , NULL }
} ;
@ -3110,6 +3177,7 @@ static int mov_read_close(AVFormatContext *s)
}
av_freep ( & mov - > trex_data ) ;
av_freep ( & mov - > bitrates ) ;
return 0 ;
}
@ -3222,6 +3290,12 @@ static int mov_read_header(AVFormatContext *s)
}
}
for ( i = 0 ; i < mov - > bitrates_count & & i < s - > nb_streams ; i + + ) {
if ( mov - > bitrates [ i ] ) {
s - > streams [ i ] - > codec - > bit_rate = mov - > bitrates [ i ] ;
}
}
return 0 ;
}