From 315a4496ea1690deb28b2de84032b2eb13019657 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 17 Nov 2019 16:20:58 +0100 Subject: [PATCH] avfilter/f_loop: switch aloop to activate --- libavfilter/f_loop.c | 50 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/libavfilter/f_loop.c b/libavfilter/f_loop.c index 879db621ef..0a029f0104 100644 --- a/libavfilter/f_loop.c +++ b/libavfilter/f_loop.c @@ -116,6 +116,7 @@ static int push_samples(AVFilterContext *ctx, int nb_samples) return ret; if (s->current_sample >= s->nb_samples) { + s->duration = s->pts; s->current_sample = 0; if (s->loop > 0) @@ -205,13 +206,55 @@ static int arequest_frame(AVFilterLink *outlink) ret = push_samples(ctx, 1024); } - if (ret == AVERROR_EOF && s->nb_samples > 0 && s->loop != 0) { - ret = push_samples(ctx, outlink->sample_rate); + if (s->eof && s->nb_samples > 0 && s->loop != 0) { + ret = push_samples(ctx, 1024); } return ret; } +static int aactivate(AVFilterContext *ctx) +{ + AVFilterLink *inlink = ctx->inputs[0]; + AVFilterLink *outlink = ctx->outputs[0]; + LoopContext *s = ctx->priv; + AVFrame *frame = NULL; + int ret, status; + int64_t pts; + + FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink); + + if (!s->eof && (s->nb_samples < s->size || !s->loop || !s->size)) { + ret = ff_inlink_consume_frame(inlink, &frame); + if (ret < 0) + return ret; + if (ret > 0) + return afilter_frame(inlink, frame); + } + + if (!s->eof && ff_inlink_acknowledge_status(inlink, &status, &pts)) { + if (status == AVERROR_EOF) { + s->size = s->nb_samples; + s->eof = 1; + } + } + + if (s->eof && (!s->loop || !s->size)) { + ff_outlink_set_status(outlink, AVERROR_EOF, s->duration); + return 0; + } + + if (!s->eof && (!s->size || + (s->nb_samples < s->size) || + (s->nb_samples >= s->size && s->loop == 0))) { + FF_FILTER_FORWARD_WANTED(outlink, inlink); + } else if (s->loop && s->nb_samples == s->size) { + return arequest_frame(outlink); + } + + return FFERROR_NOT_READY; +} + static const AVOption aloop_options[] = { { "loop", "number of loops", OFFSET(loop), AV_OPT_TYPE_INT, {.i64 = 0 }, -1, INT_MAX, AFLAGS }, { "size", "max number of samples to loop", OFFSET(size), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT32_MAX, AFLAGS }, @@ -225,7 +268,6 @@ static const AVFilterPad ainputs[] = { { .name = "default", .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = afilter_frame, .config_props = aconfig_input, }, { NULL } @@ -235,7 +277,6 @@ static const AVFilterPad aoutputs[] = { { .name = "default", .type = AVMEDIA_TYPE_AUDIO, - .request_frame = arequest_frame, }, { NULL } }; @@ -245,6 +286,7 @@ AVFilter ff_af_aloop = { .description = NULL_IF_CONFIG_SMALL("Loop audio samples."), .priv_size = sizeof(LoopContext), .priv_class = &aloop_class, + .activate = aactivate, .uninit = auninit, .inputs = ainputs, .outputs = aoutputs,