@ -3130,6 +3130,62 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0 ;
}
static int mov_read_sgpd ( MOVContext * c , AVIOContext * pb , MOVAtom atom )
{
AVStream * st ;
MOVStreamContext * sc ;
uint8_t version ;
uint32_t grouping_type ;
uint32_t default_length ;
av_unused uint32_t default_group_description_index ;
uint32_t entry_count ;
if ( c - > fc - > nb_streams < 1 )
return 0 ;
st = c - > fc - > streams [ c - > fc - > nb_streams - 1 ] ;
sc = st - > priv_data ;
version = avio_r8 ( pb ) ; /* version */
avio_rb24 ( pb ) ; /* flags */
grouping_type = avio_rl32 ( pb ) ;
/*
* This function only supports " sync " boxes , but the code is able to parse
* other boxes ( such as " tscl " , " tsas " and " stsa " )
*/
if ( grouping_type ! = MKTAG ( ' s ' , ' y ' , ' n ' , ' c ' ) )
return 0 ;
default_length = version > = 1 ? avio_rb32 ( pb ) : 0 ;
default_group_description_index = version > = 2 ? avio_rb32 ( pb ) : 0 ;
entry_count = avio_rb32 ( pb ) ;
av_freep ( & sc - > sgpd_sync ) ;
sc - > sgpd_sync_count = entry_count ;
sc - > sgpd_sync = av_calloc ( entry_count , sizeof ( * sc - > sgpd_sync ) ) ;
if ( ! sc - > sgpd_sync )
return AVERROR ( ENOMEM ) ;
for ( uint32_t i = 0 ; i < entry_count & & ! pb - > eof_reached ; i + + ) {
uint32_t description_length = default_length ;
if ( version > = 1 & & default_length = = 0 )
description_length = avio_rb32 ( pb ) ;
if ( grouping_type = = MKTAG ( ' s ' , ' y ' , ' n ' , ' c ' ) ) {
const uint8_t nal_unit_type = avio_r8 ( pb ) & 0x3f ;
sc - > sgpd_sync [ i ] = nal_unit_type ;
description_length - = 1 ;
}
avio_skip ( pb , description_length ) ;
}
if ( pb - > eof_reached ) {
av_log ( c - > fc , AV_LOG_WARNING , " reached eof, corrupted SGPD atom \n " ) ;
return AVERROR_EOF ;
}
return 0 ;
}
static int mov_read_sbgp ( MOVContext * c , AVIOContext * pb , MOVAtom atom )
{
AVStream * st ;
@ -4375,6 +4431,7 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
av_freep ( & sc - > elst_data ) ;
av_freep ( & sc - > rap_group ) ;
av_freep ( & sc - > sync_group ) ;
av_freep ( & sc - > sgpd_sync ) ;
return 0 ;
}
@ -7255,6 +7312,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG ( ' c ' , ' m ' , ' o ' , ' v ' ) , mov_read_cmov } ,
{ MKTAG ( ' c ' , ' h ' , ' a ' , ' n ' ) , mov_read_chan } , /* channel layout */
{ MKTAG ( ' d ' , ' v ' , ' c ' , ' 1 ' ) , mov_read_dvc1 } ,
{ MKTAG ( ' s ' , ' g ' , ' p ' , ' d ' ) , mov_read_sgpd } ,
{ MKTAG ( ' s ' , ' b ' , ' g ' , ' p ' ) , mov_read_sbgp } ,
{ MKTAG ( ' h ' , ' v ' , ' c ' , ' C ' ) , mov_read_glbl } ,
{ MKTAG ( ' u ' , ' u ' , ' i ' , ' d ' ) , mov_read_uuid } ,
@ -7715,6 +7773,7 @@ static int mov_read_close(AVFormatContext *s)
av_freep ( & sc - > elst_data ) ;
av_freep ( & sc - > rap_group ) ;
av_freep ( & sc - > sync_group ) ;
av_freep ( & sc - > sgpd_sync ) ;
av_freep ( & sc - > display_matrix ) ;
av_freep ( & sc - > index_ranges ) ;