| @@ -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, | |||