X-Git-Url: http://git.cinelerra-gg.org/git/?p=goodguy%2Fhistory.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fffmpeg.C;h=65e0c780e793cfaa82b04cd3860cafbe8cb98066;hp=541c5f0a4cd0bc4a4ec809408e930076ad2f1177;hb=2ce5f3585284c78107b6eab879ee4e94686ff41a;hpb=4a028c75bea81ad0f03a8004eb076dfff718a469 diff --git a/cinelerra-5.1/cinelerra/ffmpeg.C b/cinelerra-5.1/cinelerra/ffmpeg.C index 541c5f0a..65e0c780 100644 --- a/cinelerra-5.1/cinelerra/ffmpeg.C +++ b/cinelerra-5.1/cinelerra/ffmpeg.C @@ -15,6 +15,8 @@ #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" @@ -758,6 +760,7 @@ int FFAudioStream::load_history(uint8_t **data, int len) 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; @@ -766,8 +769,13 @@ int FFAudioStream::decode_frame(AVFrame *frame) 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; } @@ -845,7 +853,8 @@ int FFAudioStream::audio_seek(int64_t pos) 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; } @@ -1114,6 +1123,7 @@ int FFVideoConvert::convert_picture_vframe(VFrame *frame, AVFrame *ip, AVFrame * 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; @@ -1214,6 +1224,7 @@ int FFVideoConvert::convert_vframe_picture(VFrame *frame, AVFrame *op, AVFrame * 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; @@ -2992,6 +3003,7 @@ int FFMPEG::scan(IndexState *index_state, int64_t *scan_position, int *canceled) 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; } @@ -3037,6 +3049,7 @@ int FFMPEG::scan(IndexState *index_state, int64_t *scan_position, int *canceled) } 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); }