static int request_frame(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; AudioEchoContext *s = ctx->priv; int ret; ret = ff_request_frame(ctx->inputs[0]); if (ret == AVERROR_EOF && !ctx->is_disabled && s->fade_out) { int nb_samples = FFMIN(s->fade_out, 2048); AVFrame *frame; frame = ff_get_audio_buffer(outlink, nb_samples); if (!frame) return AVERROR(ENOMEM); s->fade_out -= nb_samples; av_samples_set_silence(frame->extended_data, 0, frame->nb_samples, outlink->channels, frame->format); s->echo_samples(s, s->delayptrs, frame->data, frame->data, frame->nb_samples, outlink->channels); frame->pts = s->next_pts; if (s->next_pts != AV_NOPTS_VALUE) s->next_pts += av_rescale_q(nb_samples, (AVRational){1, outlink->sample_rate}, outlink->time_base); return ff_filter_frame(outlink, frame); } return ret; }
static int filter_frame(AVFilterLink *inlink, AVFrame *frame) { AVFilterContext *ctx = inlink->dst; AudioEchoContext *s = ctx->priv; AVFrame *out_frame; #ifdef IDE_COMPILE AVRational tmp; #endif if (av_frame_is_writable(frame)) { out_frame = frame; } else { out_frame = ff_get_audio_buffer(inlink, frame->nb_samples); if (!out_frame) return AVERROR(ENOMEM); av_frame_copy_props(out_frame, frame); } s->echo_samples(s, s->delayptrs, frame->extended_data, out_frame->extended_data, frame->nb_samples, inlink->channels); #ifdef IDE_COMPILE tmp.num = 1; tmp.den = inlink->sample_rate; s->next_pts = frame->pts + av_rescale_q(frame->nb_samples, tmp, inlink->time_base); #else s->next_pts = frame->pts + av_rescale_q(frame->nb_samples, (AVRational){1, inlink->sample_rate}, inlink->time_base); #endif if (frame != out_frame) av_frame_free(&frame); return ff_filter_frame(ctx->outputs[0], out_frame); }