#define INT64_MAX 9223372036854775807LL
#endif
#define MAX_RETRY 1000
+// max pts/curr_pos drift allowed before correction (in seconds)
+#define AUDIO_PTS_TOLERANCE 0.04
#include "asset.h"
#include "bccmodels.h"
int FFAudioStream::decode_frame(AVFrame *frame)
{
int first_frame = seeked; seeked = 0;
+ frame->best_effort_timestamp = AV_NOPTS_VALUE;
int ret = avcodec_receive_frame(avctx, frame);
if( ret < 0 ) {
if( first_frame || ret == AVERROR(EAGAIN) ) return 0;
return -1;
}
int64_t pkt_ts = frame->best_effort_timestamp;
- if( pkt_ts != AV_NOPTS_VALUE )
- curr_pos = ffmpeg->to_secs(pkt_ts - nudge, st->time_base) * sample_rate + 0.5;
+ if( pkt_ts != AV_NOPTS_VALUE ) {
+ double ts = ffmpeg->to_secs(pkt_ts - nudge, st->time_base);
+ double t = (double)curr_pos / sample_rate;
+// some time_base clocks are very grainy, too grainy for audio (clicks, pops)
+ if( fabs(ts - t) > AUDIO_PTS_TOLERANCE )
+ curr_pos = ts * sample_rate + 0.5;
+ }
return 1;
}
if( pos == curr_pos ) return 0;
reset_history(); mbsz = 0;
// guarentee preload > 1sec samples
- if( seek(pos-sample_rate, sample_rate) < 0 ) return -1;
+ if( (pos-=sample_rate) < 0 ) pos = 0;
+ if( seek(pos, sample_rate) < 0 ) return -1;
return 1;
}