X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Faf_aecho.c;h=4e45ab9a8b649af9c7ed3c745ee736707fb73671;hb=3f27021143f1bc6a55be5bac37f4c2d3c742e023;hp=b9ac18d3a462b8aa4d5d8a33e30844d511185f6e;hpb=b1b0e532583e26f18ba27f3cc8775dbd62f3bc2b;p=ffmpeg diff --git a/libavfilter/af_aecho.c b/libavfilter/af_aecho.c index b9ac18d3a46..4e45ab9a8b6 100644 --- a/libavfilter/af_aecho.c +++ b/libavfilter/af_aecho.c @@ -24,6 +24,7 @@ #include "libavutil/samplefmt.h" #include "avfilter.h" #include "audio.h" +#include "filters.h" #include "internal.h" typedef struct AudioEchoContext { @@ -36,6 +37,7 @@ typedef struct AudioEchoContext { uint8_t **delayptrs; int max_samples, fade_out; int *samples; + int eof; int64_t next_pts; void (*echo_samples)(struct AudioEchoContext *ctx, uint8_t **delayptrs, @@ -78,7 +80,7 @@ static void fill_items(char *item_str, int *nb_items, float *items) char *tstr = av_strtok(p, "|", &saveptr); p = NULL; if (tstr) - new_nb_items += sscanf(tstr, "%f", &items[new_nb_items]) == 1; + new_nb_items += av_sscanf(tstr, "%f", &items[new_nb_items]) == 1; } *nb_items = new_nb_items; @@ -302,42 +304,65 @@ static int request_frame(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; AudioEchoContext *s = ctx->priv; - int ret; + int nb_samples = FFMIN(s->fade_out, 2048); + AVFrame *frame = ff_get_audio_buffer(outlink, nb_samples); - ret = ff_request_frame(ctx->inputs[0]); + if (!frame) + return AVERROR(ENOMEM); + s->fade_out -= nb_samples; - if (ret == AVERROR_EOF && !ctx->is_disabled && s->fade_out) { - int nb_samples = FFMIN(s->fade_out, 2048); - AVFrame *frame; + av_samples_set_silence(frame->extended_data, 0, + frame->nb_samples, + outlink->channels, + frame->format); - frame = ff_get_audio_buffer(outlink, nb_samples); - if (!frame) - return AVERROR(ENOMEM); - s->fade_out -= nb_samples; + s->echo_samples(s, s->delayptrs, frame->extended_data, frame->extended_data, + frame->nb_samples, outlink->channels); - av_samples_set_silence(frame->extended_data, 0, - frame->nb_samples, - outlink->channels, - frame->format); + 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); - s->echo_samples(s, s->delayptrs, frame->extended_data, frame->extended_data, - frame->nb_samples, outlink->channels); + return ff_filter_frame(outlink, frame); +} + +static int activate(AVFilterContext *ctx) +{ + AVFilterLink *inlink = ctx->inputs[0]; + AVFilterLink *outlink = ctx->outputs[0]; + AudioEchoContext *s = ctx->priv; + AVFrame *in; + int ret, status; + int64_t pts; - 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); + FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink); - return ff_filter_frame(outlink, frame); + ret = ff_inlink_consume_frame(inlink, &in); + if (ret < 0) + return ret; + if (ret > 0) + return filter_frame(inlink, in); + + if (!s->eof && ff_inlink_acknowledge_status(inlink, &status, &pts)) { + if (status == AVERROR_EOF) + s->eof = 1; } - return ret; + if (s->eof && s->fade_out <= 0) { + ff_outlink_set_status(outlink, AVERROR_EOF, s->next_pts); + return 0; + } + + if (!s->eof) + FF_FILTER_FORWARD_WANTED(outlink, inlink); + + return request_frame(outlink); } static const AVFilterPad aecho_inputs[] = { { .name = "default", .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, }, { NULL } }; @@ -345,20 +370,20 @@ static const AVFilterPad aecho_inputs[] = { static const AVFilterPad aecho_outputs[] = { { .name = "default", - .request_frame = request_frame, .config_props = config_output, .type = AVMEDIA_TYPE_AUDIO, }, { NULL } }; -AVFilter ff_af_aecho = { +const AVFilter ff_af_aecho = { .name = "aecho", .description = NULL_IF_CONFIG_SMALL("Add echoing to the audio."), .query_formats = query_formats, .priv_size = sizeof(AudioEchoContext), .priv_class = &aecho_class, .init = init, + .activate = activate, .uninit = uninit, .inputs = aecho_inputs, .outputs = aecho_outputs,