#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;
}
case BC_YUV422P:
usz /= 2;
case BC_YUV444P:
+ case BC_GBRP:
// override av_image_fill_arrays() for planar types
ipic->data[0] = frame->get_y(); ipic->linesize[0] = ysz;
ipic->data[1] = frame->get_u(); ipic->linesize[1] = usz;
case BC_YUV422P:
usz /= 2;
case BC_YUV444P:
+ case BC_GBRP:
// override av_image_fill_arrays() for planar types
opic->data[0] = frame->get_y(); opic->linesize[0] = ysz;
opic->data[1] = frame->get_u(); opic->linesize[1] = usz;
if( !frame ) {
fprintf(stderr,"FFMPEG::scan: ");
fprintf(stderr,_("av_frame_alloc failed\n"));
+ fprintf(stderr,"FFMPEG::scan:file=%s\n", file_base->asset->path);
return -1;
}
}
fprintf(stderr,"FFMPEG::scan: ");
fprintf(stderr,_("codec open failed\n"));
+ fprintf(stderr,"FFMPEG::scan:file=%s\n", file_base->asset->path);
avcodec_free_context(&avctx);
}