@ -3992,7 +3992,20 @@ static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
static int mov_read_chap ( MOVContext * c , AVIOContext * pb , MOVAtom atom )
{
c - > chapter_track = avio_rb32 ( pb ) ;
unsigned i , num ;
void * new_tracks ;
num = atom . size / 4 ;
if ( ! ( new_tracks = av_malloc_array ( num , sizeof ( int ) ) ) )
return AVERROR ( ENOMEM ) ;
av_free ( c - > chapter_tracks ) ;
c - > chapter_tracks = new_tracks ;
c - > nb_chapter_tracks = num ;
for ( i = 0 ; i < num & & ! pb - > eof_reached ; i + + )
c - > chapter_tracks [ i ] = avio_rb32 ( pb ) ;
return 0 ;
}
@ -5055,25 +5068,50 @@ static int mov_probe(AVProbeData *p)
static void mov_read_chapters ( AVFormatContext * s )
{
MOVContext * mov = s - > priv_data ;
AVStream * st = NULL ;
AVStream * st ;
MOVStreamContext * sc ;
int64_t cur_pos ;
int i ;
int i , j ;
int chapter_track ;
for ( j = 0 ; j < mov - > nb_chapter_tracks ; j + + ) {
chapter_track = mov - > chapter_tracks [ j ] ;
st = NULL ;
for ( i = 0 ; i < s - > nb_streams ; i + + )
if ( s - > streams [ i ] - > id = = mov - > chapter_track ) {
if ( s - > streams [ i ] - > id = = chapter_track ) {
st = s - > streams [ i ] ;
break ;
}
if ( ! st ) {
av_log ( s , AV_LOG_ERROR , " Referenced QT chapter track not found \n " ) ;
return ;
continue ;
}
st - > discard = AVDISCARD_ALL ;
sc = st - > priv_data ;
cur_pos = avio_tell ( sc - > pb ) ;
if ( st - > codecpar - > codec_type = = AVMEDIA_TYPE_VIDEO ) {
st - > disposition | = AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS ;
if ( st - > nb_index_entries ) {
// Retrieve the first frame, if possible
AVPacket pkt ;
AVIndexEntry * sample = & st - > index_entries [ 0 ] ;
if ( avio_seek ( sc - > pb , sample - > pos , SEEK_SET ) ! = sample - > pos ) {
av_log ( s , AV_LOG_ERROR , " Failed to retrieve first frame \n " ) ;
goto finish ;
}
if ( av_get_packet ( sc - > pb , & pkt , sample - > size ) < 0 )
goto finish ;
st - > attached_pic = pkt ;
st - > attached_pic . stream_index = st - > index ;
st - > attached_pic . flags | = AV_PKT_FLAG_KEY ;
}
} else {
st - > codecpar - > codec_type = AVMEDIA_TYPE_DATA ;
st - > codecpar - > codec_id = AV_CODEC_ID_BIN_DATA ;
st - > discard = AVDISCARD_ALL ;
for ( i = 0 ; i < st - > nb_index_entries ; i + + ) {
AVIndexEntry * sample = & st - > index_entries [ i ] ;
int64_t end = i + 1 < st - > nb_index_entries ? st - > index_entries [ i + 1 ] . timestamp : st - > duration ;
@ -5122,8 +5160,10 @@ static void mov_read_chapters(AVFormatContext *s)
avpriv_new_chapter ( s , i , st - > time_base , sample - > timestamp , end , title ) ;
av_freep ( & title ) ;
}
}
finish :
avio_seek ( sc - > pb , cur_pos , SEEK_SET ) ;
}
}
static int parse_timecode_in_framenum_format ( AVFormatContext * s , AVStream * st ,
@ -5446,7 +5486,7 @@ static int mov_read_header(AVFormatContext *s)
av_log ( mov - > fc , AV_LOG_TRACE , " on_parse_exit_offset=% " PRId64 " \n " , avio_tell ( pb ) ) ;
if ( pb - > seekable ) {
if ( mov - > chapter_track > 0 & & ! mov - > ignore_chapters )
if ( mov - > nb_ chapter_tracks > 0 & & ! mov - > ignore_chapters )
mov_read_chapters ( s ) ;
for ( i = 0 ; i < s - > nb_streams ; i + + )
if ( s - > streams [ i ] - > codecpar - > codec_tag = = AV_RL32 ( " tmcd " ) ) {