@ -1767,7 +1767,10 @@ static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
static int mov_read_ares ( MOVContext * c , AVIOContext * pb , MOVAtom atom )
{
if ( c - > fc - > nb_streams > = 1 ) {
AVCodecParameters * par = c - > fc - > streams [ c - > fc - > nb_streams - 1 ] - > codecpar ;
AVStream * const st = c - > fc - > streams [ c - > fc - > nb_streams - 1 ] ;
FFStream * const sti = ffstream ( st ) ;
AVCodecParameters * par = st - > codecpar ;
if ( par - > codec_tag = = MKTAG ( ' A ' , ' V ' , ' i ' , ' n ' ) & &
par - > codec_id = = AV_CODEC_ID_H264 & &
atom . size > 11 ) {
@ -1794,8 +1797,7 @@ static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0 ;
den * = 2 ;
case 1 :
c - > fc - > streams [ c - > fc - > nb_streams - 1 ] - > internal - > display_aspect_ratio . num = num ;
c - > fc - > streams [ c - > fc - > nb_streams - 1 ] - > internal - > display_aspect_ratio . den = den ;
sti - > display_aspect_ratio = ( AVRational ) { num , den } ;
default :
return 0 ;
}
@ -2198,7 +2200,7 @@ static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
switch ( st - > codecpar - > codec_id ) {
case AV_CODEC_ID_MP2 :
case AV_CODEC_ID_MP3 :
st - > internal - > need_parsing = AVSTREAM_PARSE_FULL ;
ffstream ( st ) - > need_parsing = AVSTREAM_PARSE_FULL ;
break ;
}
}
@ -2368,6 +2370,8 @@ static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
static int mov_finalize_stsd_codec ( MOVContext * c , AVIOContext * pb ,
AVStream * st , MOVStreamContext * sc )
{
FFStream * const sti = ffstream ( st ) ;
if ( st - > codecpar - > codec_type = = AVMEDIA_TYPE_AUDIO & &
! st - > codecpar - > sample_rate & & sc - > time_scale > 1 )
st - > codecpar - > sample_rate = sc - > time_scale ;
@ -2436,10 +2440,10 @@ static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
case AV_CODEC_ID_VC1 :
case AV_CODEC_ID_VP8 :
case AV_CODEC_ID_VP9 :
st - > internal - > need_parsing = AVSTREAM_PARSE_FULL ;
sti - > need_parsing = AVSTREAM_PARSE_FULL ;
break ;
case AV_CODEC_ID_AV1 :
st - > internal - > need_parsing = AVSTREAM_PARSE_HEADERS ;
sti - > need_parsing = AVSTREAM_PARSE_HEADERS ;
break ;
default :
break ;
@ -2768,12 +2772,14 @@ static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
static int mov_read_stss ( MOVContext * c , AVIOContext * pb , MOVAtom atom )
{
AVStream * st ;
FFStream * sti ;
MOVStreamContext * sc ;
unsigned int i , entries ;
if ( c - > fc - > nb_streams < 1 )
return 0 ;
st = c - > fc - > streams [ c - > fc - > nb_streams - 1 ] ;
sti = ffstream ( st ) ;
sc = st - > priv_data ;
avio_r8 ( pb ) ; /* version */
@ -2785,8 +2791,8 @@ static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if ( ! entries ) {
sc - > keyframe_absent = 1 ;
if ( ! st - > internal - > need_parsing & & st - > codecpar - > codec_type = = AVMEDIA_TYPE_VIDEO )
st - > internal - > need_parsing = AVSTREAM_PARSE_HEADERS ;
if ( ! sti - > need_parsing & & st - > codecpar - > codec_type = = AVMEDIA_TYPE_VIDEO )
sti - > need_parsing = AVSTREAM_PARSE_HEADERS ;
return 0 ;
}
if ( sc - > keyframes )
@ -3191,8 +3197,9 @@ static int find_prev_closest_index(AVStream *st,
int64_t * ctts_sample )
{
MOVStreamContext * msc = st - > priv_data ;
AVIndexEntry * e_keep = st - > internal - > index_entries ;
int nb_keep = st - > internal - > nb_index_entries ;
FFStream * const sti = ffstream ( st ) ;
AVIndexEntry * e_keep = sti - > index_entries ;
int nb_keep = sti - > nb_index_entries ;
int64_t i = 0 ;
int64_t index_ctts_count ;
@ -3205,8 +3212,8 @@ static int find_prev_closest_index(AVStream *st,
timestamp_pts - = msc - > dts_shift ;
}
st - > internal - > index_entries = e_old ;
st - > internal - > nb_index_entries = nb_old ;
sti - > index_entries = e_old ;
sti - > nb_index_entries = nb_old ;
* index = av_index_search_timestamp ( st , timestamp_pts , flag | AVSEEK_FLAG_BACKWARD ) ;
// Keep going backwards in the index entries until the timestamp is the same.
@ -3259,14 +3266,14 @@ static int find_prev_closest_index(AVStream *st,
}
/* restore AVStream state*/
st - > internal - > index_entries = e_keep ;
st - > internal - > nb_index_entries = nb_keep ;
sti - > index_entries = e_keep ;
sti - > nb_index_entries = nb_keep ;
return * index > = 0 ? 0 : - 1 ;
}
/**
* Add index entry with the given values , to the end of st - > internal - > index_entries .
* Returns the new size st - > internal - > index_entries if successful , else returns - 1.
* Add index entry with the given values , to the end of ffstream ( st ) - > index_entries .
* Returns the new size ffstream ( st ) - > index_entries if successful , else returns - 1.
*
* This function is similar to ff_add_index_entry in libavformat / utils . c
* except that here we are always unconditionally adding an index entry to
@ -3278,29 +3285,30 @@ static int find_prev_closest_index(AVStream *st,
static int64_t add_index_entry ( AVStream * st , int64_t pos , int64_t timestamp ,
int size , int distance , int flags )
{
FFStream * const sti = ffstream ( st ) ;
AVIndexEntry * entries , * ie ;
int64_t index = - 1 ;
const size_t min_size_needed = ( st - > internal - > nb_index_entries + 1 ) * sizeof ( AVIndexEntry ) ;
const size_t min_size_needed = ( sti - > nb_index_entries + 1 ) * sizeof ( AVIndexEntry ) ;
// Double the allocation each time, to lower memory fragmentation.
// Another difference from ff_add_index_entry function.
const size_t requested_size =
min_size_needed > st - > internal - > index_entries_allocated_size ?
FFMAX ( min_size_needed , 2 * st - > internal - > index_entries_allocated_size ) :
min_size_needed > sti - > index_entries_allocated_size ?
FFMAX ( min_size_needed , 2 * sti - > index_entries_allocated_size ) :
min_size_needed ;
if ( st - > internal - > nb_index_entries + 1U > = UINT_MAX / sizeof ( AVIndexEntry ) )
if ( sti - > nb_index_entries + 1U > = UINT_MAX / sizeof ( AVIndexEntry ) )
return - 1 ;
entries = av_fast_realloc ( st - > internal - > index_entries ,
& st - > internal - > index_entries_allocated_size ,
entries = av_fast_realloc ( sti - > index_entries ,
& sti - > index_entries_allocated_size ,
requested_size ) ;
if ( ! entries )
return - 1 ;
st - > internal - > index_entries = entries ;
sti - > index_entries = entries ;
index = st - > internal - > nb_index_entries + + ;
index = sti - > nb_index_entries + + ;
ie = & entries [ index ] ;
ie - > pos = pos ;
@ -3318,11 +3326,12 @@ static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
static void fix_index_entry_timestamps ( AVStream * st , int end_index , int64_t end_ts ,
int64_t * frame_duration_buffer ,
int frame_duration_buffer_size ) {
FFStream * const sti = ffstream ( st ) ;
int i = 0 ;
av_assert0 ( end_index > = 0 & & end_index < = st - > internal - > nb_index_entries ) ;
av_assert0 ( end_index > = 0 & & end_index < = sti - > nb_index_entries ) ;
for ( i = 0 ; i < frame_duration_buffer_size ; i + + ) {
end_ts - = frame_duration_buffer [ frame_duration_buffer_size - 1 - i ] ;
st - > internal - > index_entries [ end_index - 1 - i ] . timestamp = end_ts ;
sti - > index_entries [ end_index - 1 - i ] . timestamp = end_ts ;
}
}
@ -3361,7 +3370,7 @@ static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, uns
static void mov_estimate_video_delay ( MOVContext * c , AVStream * st )
{
MOVStreamContext * msc = st - > priv_data ;
int ind ;
FFStream * const sti = ffstream ( st ) ;
int ctts_ind = 0 ;
int ctts_sample = 0 ;
int64_t pts_buf [ MAX_REORDER_DELAY + 1 ] ; // Circular buffer to sort pts.
@ -3374,14 +3383,14 @@ static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
if ( st - > codecpar - > video_delay < = 0 & & msc - > ctts_data & &
st - > codecpar - > codec_id = = AV_CODEC_ID_H264 ) {
st - > codecpar - > video_delay = 0 ;
for ( ind = 0 ; ind < st - > internal - > nb_index_entries & & ctts_ind < msc - > ctts_count ; + + ind ) {
for ( int ind = 0 ; ind < sti - > nb_index_entries & & ctts_ind < msc - > ctts_count ; + + ind ) {
// Point j to the last elem of the buffer and insert the current pts there.
j = buf_start ;
buf_start = ( buf_start + 1 ) ;
if ( buf_start = = MAX_REORDER_DELAY + 1 )
buf_start = 0 ;
pts_buf [ j ] = st - > internal - > index_entries [ ind ] . timestamp + msc - > ctts_data [ ctts_ind ] . duration ;
pts_buf [ j ] = sti - > index_entries [ ind ] . timestamp + msc - > ctts_data [ ctts_ind ] . duration ;
// The timestamps that are already in the sorted buffer, and are greater than the
// current pts, are exactly the timestamps that need to be buffered to output PTS
@ -3461,7 +3470,7 @@ static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
}
/**
* Fix st - > internal - > index_entries , so that it contains only the entries ( and the entries
* Fix ffstream ( st ) - > index_entries , so that it contains only the entries ( and the entries
* which are needed to decode them ) that fall in the edit list time ranges .
* Also fixes the timestamps of the index entries to match the timeline
* specified the edit lists .
@ -3469,8 +3478,9 @@ static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
static void mov_fix_index ( MOVContext * mov , AVStream * st )
{
MOVStreamContext * msc = st - > priv_data ;
AVIndexEntry * e_old = st - > internal - > index_entries ;
int nb_old = st - > internal - > nb_index_entries ;
FFStream * const sti = ffstream ( st ) ;
AVIndexEntry * e_old = sti - > index_entries ;
int nb_old = sti - > nb_index_entries ;
const AVIndexEntry * e_old_end = e_old + nb_old ;
const AVIndexEntry * current = NULL ;
MOVStts * ctts_data_old = msc - > ctts_data ;
@ -3497,7 +3507,6 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
int first_non_zero_audio_edit = - 1 ;
int packet_skip_samples = 0 ;
MOVIndexRange * current_index_range ;
int i ;
int found_keyframe_after_edit = 0 ;
int found_non_empty_edit = 0 ;
@ -3515,9 +3524,9 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
current_index_range = msc - > index_ranges - 1 ;
// Clean AVStream from traces of old index
st - > internal - > index_entries = NULL ;
st - > internal - > index_entries_allocated_size = 0 ;
st - > internal - > nb_index_entries = 0 ;
sti - > index_entries = NULL ;
sti - > index_entries_allocated_size = 0 ;
sti - > nb_index_entries = 0 ;
// Clean ctts fields of MOVStreamContext
msc - > ctts_data = NULL ;
@ -3562,7 +3571,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
}
if ( first_non_zero_audio_edit > 0 )
st - > internal - > skip_samples = msc - > start_pad = 0 ;
sti - > skip_samples = msc - > start_pad = 0 ;
}
// While reordering frame index according to edit list we must handle properly
@ -3637,7 +3646,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
curr_cts < edit_list_media_time & & curr_cts + frame_duration > edit_list_media_time & &
first_non_zero_audio_edit > 0 ) {
packet_skip_samples = edit_list_media_time - curr_cts ;
st - > internal - > skip_samples + = packet_skip_samples ;
sti - > skip_samples + = packet_skip_samples ;
// Shift the index entry timestamp by packet_skip_samples to be correct.
edit_list_dts_counter - = packet_skip_samples ;
@ -3646,7 +3655,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
// Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
// discarded packets.
if ( frame_duration_buffer ) {
fix_index_entry_timestamps ( st , st - > internal - > nb_index_entries , edit_list_dts_counter ,
fix_index_entry_timestamps ( st , sti - > nb_index_entries , edit_list_dts_counter ,
frame_duration_buffer , num_discarded_begin ) ;
av_freep ( & frame_duration_buffer ) ;
}
@ -3670,7 +3679,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
// Increment skip_samples for the first non-zero audio edit list
if ( st - > codecpar - > codec_type = = AVMEDIA_TYPE_AUDIO & &
first_non_zero_audio_edit > 0 & & st - > codecpar - > codec_id ! = AV_CODEC_ID_VORBIS ) {
st - > internal - > skip_samples + = frame_duration ;
sti - > skip_samples + = frame_duration ;
}
}
}
@ -3685,7 +3694,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
// Make timestamps strictly monotonically increasing by rewriting timestamps for
// discarded packets.
if ( frame_duration_buffer ) {
fix_index_entry_timestamps ( st , st - > internal - > nb_index_entries , edit_list_dts_counter ,
fix_index_entry_timestamps ( st , sti - > nb_index_entries , edit_list_dts_counter ,
frame_duration_buffer , num_discarded_begin ) ;
av_freep ( & frame_duration_buffer ) ;
}
@ -3746,9 +3755,8 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
if ( st - > codecpar - > codec_type = = AVMEDIA_TYPE_VIDEO ) {
if ( msc - > min_corrected_pts > 0 ) {
av_log ( mov - > fc , AV_LOG_DEBUG , " Offset DTS by % " PRId64 " to make first pts zero. \n " , msc - > min_corrected_pts ) ;
for ( i = 0 ; i < st - > internal - > nb_index_entries ; + + i ) {
st - > internal - > index_entries [ i ] . timestamp - = msc - > min_corrected_pts ;
}
for ( int i = 0 ; i < sti - > nb_index_entries ; + + i )
sti - > index_entries [ i ] . timestamp - = msc - > min_corrected_pts ;
}
}
// Start time should be equal to zero or the duration of any empty edits.
@ -3756,7 +3764,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
// Update av stream length, if it ends up shorter than the track's media duration
st - > duration = FFMIN ( st - > duration , edit_list_dts_entry_end - start_dts ) ;
msc - > start_pad = st - > internal - > skip_samples ;
msc - > start_pad = sti - > skip_samples ;
// Free the old index and the old CTTS structures
av_free ( e_old ) ;
@ -3773,6 +3781,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
static void mov_build_index ( MOVContext * mov , AVStream * st )
{
MOVStreamContext * sc = st - > priv_data ;
FFStream * const sti = ffstream ( st ) ;
int64_t current_offset ;
int64_t current_dts = 0 ;
unsigned int stts_index = 0 ;
@ -3844,17 +3853,17 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
current_dts - = sc - > dts_shift ;
last_dts = current_dts ;
if ( ! sc - > sample_count | | st - > internal - > nb_index_entries )
if ( ! sc - > sample_count | | sti - > nb_index_entries )
return ;
if ( sc - > sample_count > = UINT_MAX / sizeof ( * st - > internal - > index_entries ) - st - > internal - > nb_index_entries )
if ( sc - > sample_count > = UINT_MAX / sizeof ( * sti - > index_entries ) - sti - > nb_index_entries )
return ;
if ( av_reallocp_array ( & st - > internal - > index_entries ,
st - > internal - > nb_index_entries + sc - > sample_count ,
sizeof ( * st - > internal - > index_entries ) ) < 0 ) {
st - > internal - > nb_index_entries = 0 ;
if ( av_reallocp_array ( & sti - > index_entries ,
sti - > nb_index_entries + sc - > sample_count ,
sizeof ( * sti - > index_entries ) ) < 0 ) {
sti - > nb_index_entries = 0 ;
return ;
}
st - > internal - > index_entries_allocated_size = ( st - > internal - > nb_index_entries + sc - > sample_count ) * sizeof ( * st - > internal - > index_entries ) ;
sti - > index_entries_allocated_size = ( sti - > nb_index_entries + sc - > sample_count ) * sizeof ( * sti - > index_entries ) ;
if ( ctts_data_old ) {
// Expand ctts entries such that we have a 1-1 mapping with samples
@ -3937,7 +3946,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
av_log ( mov - > fc , AV_LOG_ERROR , " Sample size %u is too large \n " , sample_size ) ;
return ;
}
e = & st - > internal - > index_entries [ st - > internal - > nb_index_entries + + ] ;
e = & sti - > index_entries [ sti - > nb_index_entries + + ] ;
e - > pos = current_offset ;
e - > timestamp = current_dts ;
e - > size = sample_size ;
@ -3946,7 +3955,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
av_log ( mov - > fc , AV_LOG_TRACE , " AVIndex stream %d, sample %u, offset % " PRIx64 " , dts % " PRId64 " , "
" size %u, distance %u, keyframe %d \n " , st - > index , current_sample ,
current_offset , current_dts , sample_size , distance , keyframe ) ;
if ( st - > codecpar - > codec_type = = AVMEDIA_TYPE_VIDEO & & st - > internal - > nb_index_entries < 100 )
if ( st - > codecpar - > codec_type = = AVMEDIA_TYPE_VIDEO & & sti - > nb_index_entries < 100 )
ff_rfps_add_frame ( mov - > fc , st , current_dts ) ;
}
@ -4018,15 +4027,15 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
}
av_log ( mov - > fc , AV_LOG_TRACE , " chunk count %u \n " , total ) ;
if ( total > = UINT_MAX / sizeof ( * st - > internal - > index_entries ) - st - > internal - > nb_index_entries )
if ( total > = UINT_MAX / sizeof ( * sti - > index_entries ) - sti - > nb_index_entries )
return ;
if ( av_reallocp_array ( & st - > internal - > index_entries ,
st - > internal - > nb_index_entries + total ,
sizeof ( * st - > internal - > index_entries ) ) < 0 ) {
st - > internal - > nb_index_entries = 0 ;
if ( av_reallocp_array ( & sti - > index_entries ,
sti - > nb_index_entries + total ,
sizeof ( * sti - > index_entries ) ) < 0 ) {
sti - > nb_index_entries = 0 ;
return ;
}
st - > internal - > index_entries_allocated_size = ( st - > internal - > nb_index_entries + total ) * sizeof ( * st - > internal - > index_entries ) ;
sti - > index_entries_allocated_size = ( sti - > nb_index_entries + total ) * sizeof ( * sti - > index_entries ) ;
// populate index
for ( i = 0 ; i < sc - > chunk_count ; i + + ) {
@ -4061,7 +4070,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
}
}
if ( st - > internal - > nb_index_entries > = total ) {
if ( sti - > nb_index_entries > = total ) {
av_log ( mov - > fc , AV_LOG_ERROR , " wrong chunk count %u \n " , total ) ;
return ;
}
@ -4069,7 +4078,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
av_log ( mov - > fc , AV_LOG_ERROR , " Sample size %u is too large \n " , size ) ;
return ;
}
e = & st - > internal - > index_entries [ st - > internal - > nb_index_entries + + ] ;
e = & sti - > index_entries [ sti - > nb_index_entries + + ] ;
e - > pos = current_offset ;
e - > timestamp = current_dts ;
e - > size = size ;
@ -4092,8 +4101,8 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
}
// Update start time of the stream.
if ( st - > start_time = = AV_NOPTS_VALUE & & st - > codecpar - > codec_type = = AVMEDIA_TYPE_VIDEO & & st - > internal - > nb_index_entries > 0 ) {
st - > start_time = st - > internal - > index_entries [ 0 ] . timestamp + sc - > dts_shift ;
if ( st - > start_time = = AV_NOPTS_VALUE & & st - > codecpar - > codec_type = = AVMEDIA_TYPE_VIDEO & & sti - > nb_index_entries > 0 ) {
st - > start_time = sti - > index_entries [ 0 ] . timestamp + sc - > dts_shift ;
if ( sc - > ctts_data ) {
st - > start_time + = sc - > ctts_data [ 0 ] . duration ;
}
@ -4328,7 +4337,7 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
& & sc - > stts_count > 3
& & sc - > stts_count * 10 > st - > nb_frames
& & sc - > time_scale = = st - > codecpar - > sample_rate ) {
st - > internal - > need_parsing = AVSTREAM_PARSE_FULL ;
ffstream ( st ) - > need_parsing = AVSTREAM_PARSE_FULL ;
}
/* Do not need those anymore. */
av_freep ( & sc - > chunk_offsets ) ;
@ -4740,6 +4749,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
MOVFragment * frag = & c - > fragment ;
AVStream * st = NULL ;
FFStream * sti = NULL ;
MOVStreamContext * sc ;
MOVStts * ctts_data ;
uint64_t offset ;
@ -4762,6 +4772,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
for ( i = 0 ; i < c - > fc - > nb_streams ; i + + ) {
if ( c - > fc - > streams [ i ] - > id = = frag - > track_id ) {
st = c - > fc - > streams [ i ] ;
sti = ffstream ( st ) ;
break ;
}
}
@ -4779,7 +4790,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
// A valid index_entry means the trun for the fragment was read
// and it's samples are in index_entries at the given position.
// New index entries will be inserted before the index_entry found.
index_entry_pos = st - > internal - > nb_index_entries ;
index_entry_pos = sti - > nb_index_entries ;
for ( i = c - > frag_index . current + 1 ; i < c - > frag_index . nb_items ; i + + ) {
frag_stream_info = get_frag_stream_info ( & c - > frag_index , i , frag - > track_id ) ;
if ( frag_stream_info & & frag_stream_info - > index_entry > = 0 ) {
@ -4788,7 +4799,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
break ;
}
}
av_assert0 ( index_entry_pos < = st - > internal - > nb_index_entries ) ;
av_assert0 ( index_entry_pos < = sti - > nb_index_entries ) ;
avio_r8 ( pb ) ; /* version */
flags = avio_rb24 ( pb ) ;
@ -4839,22 +4850,22 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
av_log ( c - > fc , AV_LOG_TRACE , " first sample flags 0x%x \n " , first_sample_flags ) ;
// realloc space for new index entries
if ( ( uint64_t ) st - > internal - > nb_index_entries + entries > = UINT_MAX / sizeof ( AVIndexEntry ) ) {
entries = UINT_MAX / sizeof ( AVIndexEntry ) - st - > internal - > nb_index_entries ;
if ( ( uint64_t ) sti - > nb_index_entries + entries > = UINT_MAX / sizeof ( AVIndexEntry ) ) {
entries = UINT_MAX / sizeof ( AVIndexEntry ) - sti - > nb_index_entries ;
av_log ( c - > fc , AV_LOG_ERROR , " Failed to add index entry \n " ) ;
}
if ( entries = = 0 )
return 0 ;
requested_size = ( st - > internal - > nb_index_entries + entries ) * sizeof ( AVIndexEntry ) ;
new_entries = av_fast_realloc ( st - > internal - > index_entries ,
& st - > internal - > index_entries_allocated_size ,
requested_size = ( sti - > nb_index_entries + entries ) * sizeof ( AVIndexEntry ) ;
new_entries = av_fast_realloc ( sti - > index_entries ,
& sti - > index_entries_allocated_size ,
requested_size ) ;
if ( ! new_entries )
return AVERROR ( ENOMEM ) ;
st - > internal - > index_entries = new_entries ;
sti - > index_entries = new_entries ;
requested_size = ( st - > internal - > nb_index_entries + entries ) * sizeof ( * sc - > ctts_data ) ;
requested_size = ( sti - > nb_index_entries + entries ) * sizeof ( * sc - > ctts_data ) ;
old_ctts_allocated_size = sc - > ctts_allocated_size ;
ctts_data = av_fast_realloc ( sc - > ctts_data , & sc - > ctts_allocated_size ,
requested_size ) ;
@ -4868,12 +4879,12 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
memset ( ( uint8_t * ) ( sc - > ctts_data ) + old_ctts_allocated_size , 0 ,
sc - > ctts_allocated_size - old_ctts_allocated_size ) ;
if ( index_entry_pos < st - > internal - > nb_index_entries ) {
if ( index_entry_pos < sti - > nb_index_entries ) {
// Make hole in index_entries and ctts_data for new samples
memmove ( st - > internal - > index_entries + index_entry_pos + entries ,
st - > internal - > index_entries + index_entry_pos ,
sizeof ( * st - > internal - > index_entries ) *
( st - > internal - > nb_index_entries - index_entry_pos ) ) ;
memmove ( sti - > index_entries + index_entry_pos + entries ,
sti - > index_entries + index_entry_pos ,
sizeof ( * sti - > index_entries ) *
( sti - > nb_index_entries - index_entry_pos ) ) ;
memmove ( sc - > ctts_data + index_entry_pos + entries ,
sc - > ctts_data + index_entry_pos ,
sizeof ( * sc - > ctts_data ) * ( sc - > ctts_count - index_entry_pos ) ) ;
@ -4882,15 +4893,15 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
}
}
st - > internal - > nb_index_entries + = entries ;
sc - > ctts_count = st - > internal - > nb_index_entries ;
sti - > nb_index_entries + = entries ;
sc - > ctts_count = sti - > nb_index_entries ;
// Record the index_entry position in frag_index of this fragment
if ( frag_stream_info )
frag_stream_info - > index_entry = index_entry_pos ;
if ( index_entry_pos > 0 )
prev_dts = st - > internal - > index_entries [ index_entry_pos - 1 ] . timestamp ;
prev_dts = sti - > index_entries [ index_entry_pos - 1 ] . timestamp ;
for ( i = 0 ; i < entries & & ! pb - > eof_reached ; i + + ) {
unsigned sample_size = frag - > size ;
@ -4939,11 +4950,11 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if ( prev_dts > = dts )
index_entry_flags | = AVINDEX_DISCARD_FRAME ;
st - > internal - > index_entries [ index_entry_pos ] . pos = offset ;
st - > internal - > index_entries [ index_entry_pos ] . timestamp = dts ;
st - > internal - > index_entries [ index_entry_pos ] . size = sample_size ;
st - > internal - > index_entries [ index_entry_pos ] . min_distance = distance ;
st - > internal - > index_entries [ index_entry_pos ] . flags = index_entry_flags ;
sti - > index_entries [ index_entry_pos ] . pos = offset ;
sti - > index_entries [ index_entry_pos ] . timestamp = dts ;
sti - > index_entries [ index_entry_pos ] . size = sample_size ;
sti - > index_entries [ index_entry_pos ] . min_distance = distance ;
sti - > index_entries [ index_entry_pos ] . flags = index_entry_flags ;
sc - > ctts_data [ index_entry_pos ] . count = 1 ;
sc - > ctts_data [ index_entry_pos ] . duration = ctts_duration ;
@ -4972,16 +4983,16 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
// EOF found before reading all entries. Fix the hole this would
// leave in index_entries and ctts_data
int gap = entries - i ;
memmove ( st - > internal - > index_entries + index_entry_pos ,
st - > internal - > index_entries + index_entry_pos + gap ,
sizeof ( * st - > internal - > index_entries ) *
( st - > internal - > nb_index_entries - ( index_entry_pos + gap ) ) ) ;
memmove ( sti - > index_entries + index_entry_pos ,
sti - > index_entries + index_entry_pos + gap ,
sizeof ( * sti - > index_entries ) *
( sti - > nb_index_entries - ( index_entry_pos + gap ) ) ) ;
memmove ( sc - > ctts_data + index_entry_pos ,
sc - > ctts_data + index_entry_pos + gap ,
sizeof ( * sc - > ctts_data ) *
( sc - > ctts_count - ( index_entry_pos + gap ) ) ) ;
st - > internal - > nb_index_entries - = gap ;
sti - > nb_index_entries - = gap ;
sc - > ctts_count - = gap ;
if ( index_entry_pos < sc - > current_sample ) {
sc - > current_sample - = gap ;
@ -4994,11 +5005,11 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
// fragment that overlap with AVINDEX_DISCARD_FRAME
prev_dts = AV_NOPTS_VALUE ;
if ( index_entry_pos > 0 )
prev_dts = st - > internal - > index_entries [ index_entry_pos - 1 ] . timestamp ;
for ( i = index_entry_pos ; i < st - > internal - > nb_index_entries ; i + + ) {
if ( prev_dts < st - > internal - > index_entries [ i ] . timestamp )
prev_dts = sti - > index_entries [ index_entry_pos - 1 ] . timestamp ;
for ( int i = index_entry_pos ; i < sti - > nb_index_entries ; i + + ) {
if ( prev_dts < sti - > index_entries [ i ] . timestamp )
break ;
st - > internal - > index_entries [ i ] . flags | = AVINDEX_DISCARD_FRAME ;
sti - > index_entries [ i ] . flags | = AVINDEX_DISCARD_FRAME ;
}
// If a hole was created to insert the new index_entries into,
@ -7156,15 +7167,15 @@ static int mov_probe(const AVProbeData *p)
static void mov_read_chapters ( AVFormatContext * s )
{
MOVContext * mov = s - > priv_data ;
AVStream * st ;
MOVStreamContext * sc ;
int64_t cur_pos ;
int i , j ;
int chapter_track ;
for ( j = 0 ; j < mov - > nb_chapter_tracks ; j + + ) {
AVStream * st = NULL ;
FFStream * sti = NULL ;
chapter_track = mov - > chapter_tracks [ j ] ;
st = NULL ;
for ( i = 0 ; i < s - > nb_streams ; i + + )
if ( s - > streams [ i ] - > id = = chapter_track ) {
st = s - > streams [ i ] ;
@ -7174,15 +7185,16 @@ static void mov_read_chapters(AVFormatContext *s)
av_log ( s , AV_LOG_ERROR , " Referenced QT chapter track not found \n " ) ;
continue ;
}
sti = ffstream ( st ) ;
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 - > internal - > nb_index_entries ) {
if ( sti - > nb_index_entries ) {
// Retrieve the first frame, if possible
AVIndexEntry * sample = & st - > internal - > index_entries [ 0 ] ;
AVIndexEntry * sample = & sti - > 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 ;
@ -7195,9 +7207,9 @@ static void mov_read_chapters(AVFormatContext *s)
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 - > internal - > nb_index_entries ; i + + ) {
AVIndexEntry * sample = & st - > internal - > index_entries [ i ] ;
int64_t end = i + 1 < st - > internal - > nb_index_entries ? st - > internal - > index_entries [ i + 1 ] . timestamp : st - > duration ;
for ( int i = 0 ; i < sti - > nb_index_entries ; i + + ) {
AVIndexEntry * sample = & sti - > index_entries [ i ] ;
int64_t end = i + 1 < sti - > nb_index_entries ? sti - > index_entries [ i + 1 ] . timestamp : st - > duration ;
uint8_t * title ;
uint16_t ch ;
int len , title_len ;
@ -7266,14 +7278,15 @@ static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
static int mov_read_rtmd_track ( AVFormatContext * s , AVStream * st )
{
MOVStreamContext * sc = st - > priv_data ;
FFStream * const sti = ffstream ( st ) ;
char buf [ AV_TIMECODE_STR_SIZE ] ;
int64_t cur_pos = avio_tell ( sc - > pb ) ;
int hh , mm , ss , ff , drop ;
if ( ! st - > internal - > nb_index_entries )
if ( ! sti - > nb_index_entries )
return - 1 ;
avio_seek ( sc - > pb , st - > internal - > index_entries - > pos , SEEK_SET ) ;
avio_seek ( sc - > pb , sti - > index_entries - > pos , SEEK_SET ) ;
avio_skip ( s - > pb , 13 ) ;
hh = avio_r8 ( s - > pb ) ;
mm = avio_r8 ( s - > pb ) ;
@ -7291,14 +7304,15 @@ static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
static int mov_read_timecode_track ( AVFormatContext * s , AVStream * st )
{
MOVStreamContext * sc = st - > priv_data ;
FFStream * const sti = ffstream ( st ) ;
int flags = 0 ;
int64_t cur_pos = avio_tell ( sc - > pb ) ;
uint32_t value ;
if ( ! st - > internal - > nb_index_entries )
if ( ! sti - > nb_index_entries )
return - 1 ;
avio_seek ( sc - > pb , st - > internal - > index_entries - > pos , SEEK_SET ) ;
avio_seek ( sc - > pb , sti - > index_entries - > pos , SEEK_SET ) ;
value = avio_rb32 ( s - > pb ) ;
if ( sc - > tmcd_flags & 0x0001 ) flags | = AV_TIMECODE_FLAG_DROPFRAME ;
@ -7616,11 +7630,12 @@ static int mov_read_header(AVFormatContext *s)
for ( i = 0 ; i < s - > nb_streams ; i + + ) {
AVStream * st = s - > streams [ i ] ;
FFStream * const sti = ffstream ( st ) ;
MOVStreamContext * sc = st - > priv_data ;
fix_timescale ( mov , sc ) ;
if ( st - > codecpar - > codec_type = = AVMEDIA_TYPE_AUDIO & &
st - > codecpar - > codec_id = = AV_CODEC_ID_AAC ) {
st - > internal - > skip_samples = sc - > start_pad ;
sti - > skip_samples = sc - > start_pad ;
}
if ( st - > codecpar - > codec_type = = AVMEDIA_TYPE_VIDEO & & sc - > nb_frames_for_fps > 0 & & sc - > duration_for_fps > 0 )
av_reduce ( & st - > avg_frame_rate . num , & st - > avg_frame_rate . den ,
@ -7639,7 +7654,7 @@ static int mov_read_header(AVFormatContext *s)
mov - > handbrake_version < = 1000000 * 0 + 1000 * 10 + 2 & & // 0.10.2
st - > codecpar - > codec_id = = AV_CODEC_ID_MP3 ) {
av_log ( s , AV_LOG_VERBOSE , " Forcing full parsing for mp3 stream \n " ) ;
st - > internal - > need_parsing = AVSTREAM_PARSE_FULL ;
sti - > need_parsing = AVSTREAM_PARSE_FULL ;
}
}
@ -7756,9 +7771,10 @@ static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
int i ;
for ( i = 0 ; i < s - > nb_streams ; i + + ) {
AVStream * avst = s - > streams [ i ] ;
FFStream * const avsti = ffstream ( avst ) ;
MOVStreamContext * msc = avst - > priv_data ;
if ( msc - > pb & & msc - > current_sample < avst - > internal - > nb_index_entries ) {
AVIndexEntry * current_sample = & avst - > internal - > index_entries [ msc - > current_sample ] ;
if ( msc - > pb & & msc - > current_sample < avsti - > nb_index_entries ) {
AVIndexEntry * current_sample = & avsti - > index_entries [ msc - > current_sample ] ;
int64_t dts = av_rescale ( current_sample - > timestamp , AV_TIME_BASE , msc - > time_scale ) ;
av_log ( s , AV_LOG_TRACE , " stream %d, sample %d, dts % " PRId64 " \n " , i , msc - > current_sample , dts ) ;
if ( ! sample | | ( ! ( s - > pb - > seekable & AVIO_SEEKABLE_NORMAL ) & & current_sample - > pos < sample - > pos ) | |
@ -7940,9 +7956,9 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
sc - > has_palette = 0 ;
}
}
if ( st - > codecpar - > codec_id = = AV_CODEC_ID_MP3 & & ! st - > internal - > need_parsing & & pkt - > size > 4 ) {
if ( st - > codecpar - > codec_id = = AV_CODEC_ID_MP3 & & ! ffstream ( st ) - > need_parsing & & pkt - > size > 4 ) {
if ( ff_mpa_check_header ( AV_RB32 ( pkt - > data ) ) < 0 )
st - > internal - > need_parsing = AVSTREAM_PARSE_FULL ;
ffstream ( st ) - > need_parsing = AVSTREAM_PARSE_FULL ;
}
}
@ -7961,8 +7977,8 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
sc - > ctts_sample = 0 ;
}
} else {
int64_t next_dts = ( sc - > current_sample < st - > internal - > nb_index_entries ) ?
st - > internal - > index_entries [ sc - > current_sample ] . timestamp : st - > duration ;
int64_t next_dts = ( sc - > current_sample < ffstream ( st ) - > nb_index_entries ) ?
ffstream ( st ) - > index_entries [ sc - > current_sample ] . timestamp : st - > duration ;
if ( next_dts > = pkt - > dts )
pkt - > duration = next_dts - pkt - > dts ;
@ -8030,6 +8046,7 @@ static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp
static int mov_seek_stream ( AVFormatContext * s , AVStream * st , int64_t timestamp , int flags )
{
MOVStreamContext * sc = st - > priv_data ;
FFStream * const sti = ffstream ( st ) ;
int sample , time_sample , ret ;
unsigned int i ;
@ -8043,7 +8060,7 @@ static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp,
sample = av_index_search_timestamp ( st , timestamp , flags ) ;
av_log ( s , AV_LOG_TRACE , " stream %d, timestamp % " PRId64 " , sample %d \n " , st - > index , timestamp , sample ) ;
if ( sample < 0 & & st - > internal - > nb_index_entries & & timestamp < st - > internal - > index_entries [ 0 ] . timestamp )
if ( sample < 0 & & sti - > nb_index_entries & & timestamp < sti - > index_entries [ 0 ] . timestamp )
sample = 0 ;
if ( sample < 0 ) /* not sure what to do */
return AVERROR_INVALIDDATA ;
@ -8084,8 +8101,9 @@ static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp,
static int64_t mov_get_skip_samples ( AVStream * st , int sample )
{
MOVStreamContext * sc = st - > priv_data ;
int64_t first_ts = st - > internal - > index_entries [ 0 ] . timestamp ;
int64_t ts = st - > internal - > index_entries [ sample ] . timestamp ;
FFStream * const sti = ffstream ( st ) ;
int64_t first_ts = sti - > index_entries [ 0 ] . timestamp ;
int64_t ts = sti - > index_entries [ sample ] . timestamp ;
int64_t off ;
if ( st - > codecpar - > codec_type ! = AVMEDIA_TYPE_AUDIO )
@ -8101,6 +8119,7 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
{
MOVContext * mc = s - > priv_data ;
AVStream * st ;
FFStream * sti ;
int sample ;
int i ;
@ -8108,18 +8127,20 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
return AVERROR_INVALIDDATA ;
st = s - > streams [ stream_index ] ;
sti = ffstream ( st ) ;
sample = mov_seek_stream ( s , st , sample_time , flags ) ;
if ( sample < 0 )
return sample ;
if ( mc - > seek_individually ) {
/* adjust seek timestamp to found sample timestamp */
int64_t seek_timestamp = st - > internal - > index_entries [ sample ] . timestamp ;
st - > internal - > skip_samples = mov_get_skip_samples ( st , sample ) ;
int64_t seek_timestamp = sti - > index_entries [ sample ] . timestamp ;
sti - > skip_samples = mov_get_skip_samples ( st , sample ) ;
for ( i = 0 ; i < s - > nb_streams ; i + + ) {
AVStream * const st = s - > streams [ i ] ;
FFStream * const sti = ffstream ( st ) ;
int64_t timestamp ;
st = s - > streams [ i ] ;
if ( stream_index = = i )
continue ;
@ -8127,7 +8148,7 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
timestamp = av_rescale_q ( seek_timestamp , s - > streams [ stream_index ] - > time_base , st - > time_base ) ;
sample = mov_seek_stream ( s , st , timestamp , flags ) ;
if ( sample > = 0 )
st - > internal - > skip_samples = mov_get_skip_samples ( st , sample ) ;
sti - > skip_samples = mov_get_skip_samples ( st , sample ) ;
}
} else {
for ( i = 0 ; i < s - > nb_streams ; i + + ) {