diff --git a/libavfilter/af_agate.c b/libavfilter/af_agate.c index 328e25ba84..f4fcabef93 100644 --- a/libavfilter/af_agate.c +++ b/libavfilter/af_agate.c @@ -29,6 +29,7 @@ #include "libavutil/opt.h" #include "avfilter.h" #include "audio.h" +#include "filters.h" #include "formats.h" #include "hermite.h" @@ -265,71 +266,76 @@ AVFilter ff_af_agate = { #define sidechaingate_options options AVFILTER_DEFINE_CLASS(sidechaingate); -static int scfilter_frame(AVFilterLink *link, AVFrame *frame) +static int activate(AVFilterContext *ctx) { - AVFilterContext *ctx = link->dst; AudioGateContext *s = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - AVFrame *out, *in[2] = { NULL }; + AVFrame *out = NULL, *in[2] = { NULL }; + int ret, i, status, nb_samples; double *dst; - int nb_samples; - int i; + int64_t pts; - for (i = 0; i < 2; i++) - if (link == ctx->inputs[i]) - break; - av_assert0(i < 2); - av_audio_fifo_write(s->fifo[i], (void **)frame->extended_data, - frame->nb_samples); - av_frame_free(&frame); + if ((ret = ff_inlink_consume_frame(ctx->inputs[0], &in[0])) > 0) { + av_audio_fifo_write(s->fifo[0], (void **)in[0]->extended_data, + in[0]->nb_samples); + av_frame_free(&in[0]); + } + if (ret < 0) + return ret; + if ((ret = ff_inlink_consume_frame(ctx->inputs[1], &in[1])) > 0) { + av_audio_fifo_write(s->fifo[1], (void **)in[1]->extended_data, + in[1]->nb_samples); + av_frame_free(&in[1]); + } + if (ret < 0) + return ret; nb_samples = FFMIN(av_audio_fifo_size(s->fifo[0]), av_audio_fifo_size(s->fifo[1])); - if (!nb_samples) - return 0; - - out = ff_get_audio_buffer(outlink, nb_samples); - if (!out) - return AVERROR(ENOMEM); - for (i = 0; i < 2; i++) { - in[i] = ff_get_audio_buffer(ctx->inputs[i], nb_samples); - if (!in[i]) { - av_frame_free(&in[0]); - av_frame_free(&in[1]); - av_frame_free(&out); + if (nb_samples) { + out = ff_get_audio_buffer(ctx->outputs[0], nb_samples); + if (!out) return AVERROR(ENOMEM); + for (i = 0; i < 2; i++) { + in[i] = ff_get_audio_buffer(ctx->inputs[i], nb_samples); + if (!in[i]) { + av_frame_free(&in[0]); + av_frame_free(&in[1]); + av_frame_free(&out); + return AVERROR(ENOMEM); + } + av_audio_fifo_read(s->fifo[i], (void **)in[i]->data, nb_samples); } - av_audio_fifo_read(s->fifo[i], (void **)in[i]->data, nb_samples); + + dst = (double *)out->data[0]; + out->pts = s->pts; + s->pts += nb_samples; + + gate(s, (double *)in[0]->data[0], dst, + (double *)in[1]->data[0], nb_samples, + s->level_in, s->level_sc, + ctx->inputs[0], ctx->inputs[1]); + + av_frame_free(&in[0]); + av_frame_free(&in[1]); + + ret = ff_filter_frame(ctx->outputs[0], out); + if (ret < 0) + return ret; } - - dst = (double *)out->data[0]; - out->pts = s->pts; - s->pts += nb_samples; - - gate(s, (double *)in[0]->data[0], dst, - (double *)in[1]->data[0], nb_samples, - s->level_in, s->level_sc, - ctx->inputs[0], ctx->inputs[1]); - - av_frame_free(&in[0]); - av_frame_free(&in[1]); - - return ff_filter_frame(outlink, out); -} - -static int screquest_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - AudioGateContext *s = ctx->priv; - int i; - - /* get a frame on each input */ - for (i = 0; i < 2; i++) { - AVFilterLink *inlink = ctx->inputs[i]; - if (!av_audio_fifo_size(s->fifo[i])) - return ff_request_frame(inlink); + if (ff_inlink_acknowledge_status(ctx->inputs[0], &status, &pts)) { + ff_outlink_set_status(ctx->outputs[0], status, pts); + return 0; + } else if (ff_inlink_acknowledge_status(ctx->inputs[1], &status, &pts)) { + ff_outlink_set_status(ctx->outputs[0], status, pts); + return 0; + } else { + if (ff_outlink_frame_wanted(ctx->outputs[0])) { + if (!av_audio_fifo_size(s->fifo[0])) + ff_inlink_request_frame(ctx->inputs[0]); + if (!av_audio_fifo_size(s->fifo[1])) + ff_inlink_request_frame(ctx->inputs[1]); + } + return 0; } - - return 0; } static int scquery_formats(AVFilterContext *ctx) @@ -408,11 +414,9 @@ static const AVFilterPad sidechaingate_inputs[] = { { .name = "main", .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = scfilter_frame, },{ .name = "sidechain", .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = scfilter_frame, }, { NULL } }; @@ -422,7 +426,6 @@ static const AVFilterPad sidechaingate_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_AUDIO, .config_props = scconfig_output, - .request_frame = screquest_frame, }, { NULL } }; @@ -433,6 +436,7 @@ AVFilter ff_af_sidechaingate = { .priv_size = sizeof(AudioGateContext), .priv_class = &sidechaingate_class, .query_formats = scquery_formats, + .activate = activate, .uninit = uninit, .inputs = sidechaingate_inputs, .outputs = sidechaingate_outputs,