Unified · Split
| @@ -116,6 +116,7 @@ static int push_samples(AVFilterContext *ctx, int nb_samples) · 115 unmodified lines | ||
| 116 | 116 | return ret; |
| 117 | 117 | |
| 118 | 118 | if (s->current_sample >= s->nb_samples) { |
| 119 | + s->duration = s->pts; | |
| 119 | 120 | s->current_sample = 0; |
| 120 | 121 | |
| 121 | 122 | if (s->loop > 0) |
| @@ -205,13 +206,55 @@ static int arequest_frame(AVFilterLink *outlink) · 83 unmodified lines | ||
| 205 | 206 | ret = push_samples(ctx, 1024); |
| 206 | 207 | } |
| 207 | 208 | |
| 208 | − if (ret == AVERROR_EOF && s->nb_samples > 0 && s->loop != 0) { | |
| 209 | − ret = push_samples(ctx, outlink->sample_rate); | |
| 209 | + if (s->eof && s->nb_samples > 0 && s->loop != 0) { | |
| 210 | + ret = push_samples(ctx, 1024); | |
| 210 | 211 | } |
| 211 | 212 | |
| 212 | 213 | return ret; |
| 213 | 214 | } |
| 214 | 215 | |
| 216 | +static int aactivate(AVFilterContext *ctx) | |
| 217 | +{ | |
| 218 | + AVFilterLink *inlink = ctx->inputs[0]; | |
| 219 | + AVFilterLink *outlink = ctx->outputs[0]; | |
| 220 | + LoopContext *s = ctx->priv; | |
| 221 | + AVFrame *frame = NULL; | |
| 222 | + int ret, status; | |
| 223 | + int64_t pts; | |
| 224 | + | |
| 225 | + FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink); | |
| 226 | + | |
| 227 | + if (!s->eof && (s->nb_samples < s->size || !s->loop || !s->size)) { | |
| 228 | + ret = ff_inlink_consume_frame(inlink, &frame); | |
| 229 | + if (ret < 0) | |
| 230 | + return ret; | |
| 231 | + if (ret > 0) | |
| 232 | + return afilter_frame(inlink, frame); | |
| 233 | + } | |
| 234 | + | |
| 235 | + if (!s->eof && ff_inlink_acknowledge_status(inlink, &status, &pts)) { | |
| 236 | + if (status == AVERROR_EOF) { | |
| 237 | + s->size = s->nb_samples; | |
| 238 | + s->eof = 1; | |
| 239 | + } | |
| 240 | + } | |
| 241 | + | |
| 242 | + if (s->eof && (!s->loop || !s->size)) { | |
| 243 | + ff_outlink_set_status(outlink, AVERROR_EOF, s->duration); | |
| 244 | + return 0; | |
| 245 | + } | |
| 246 | + | |
| 247 | + if (!s->eof && (!s->size || | |
| 248 | + (s->nb_samples < s->size) || | |
| 249 | + (s->nb_samples >= s->size && s->loop == 0))) { | |
| 250 | + FF_FILTER_FORWARD_WANTED(outlink, inlink); | |
| 251 | + } else if (s->loop && s->nb_samples == s->size) { | |
| 252 | + return arequest_frame(outlink); | |
| 253 | + } | |
| 254 | + | |
| 255 | + return FFERROR_NOT_READY; | |
| 256 | +} | |
| 257 | + | |
| 215 | 258 | static const AVOption aloop_options[] = { |
| 216 | 259 | { "loop", "number of loops", OFFSET(loop), AV_OPT_TYPE_INT, {.i64 = 0 }, -1, INT_MAX, AFLAGS }, |
| 217 | 260 | { "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[] = { · 7 unmodified lines | ||
| 225 | 268 | { |
| 226 | 269 | .name = "default", |
| 227 | 270 | .type = AVMEDIA_TYPE_AUDIO, |
| 228 | − .filter_frame = afilter_frame, | |
| 229 | 271 | .config_props = aconfig_input, |
| 230 | 272 | }, |
| 231 | 273 | { NULL } |
| @@ -235,7 +277,6 @@ static const AVFilterPad aoutputs[] = { · 3 unmodified lines | ||
| 235 | 277 | { |
| 236 | 278 | .name = "default", |
| 237 | 279 | .type = AVMEDIA_TYPE_AUDIO, |
| 238 | − .request_frame = arequest_frame, | |
| 239 | 280 | }, |
| 240 | 281 | { NULL } |
| 241 | 282 | }; |
| @@ -245,6 +286,7 @@ AVFilter ff_af_aloop = { · 3 unmodified lines | ||
| 245 | 286 | .description = NULL_IF_CONFIG_SMALL("Loop audio samples."), |
| 246 | 287 | .priv_size = sizeof(LoopContext), |
| 247 | 288 | .priv_class = &aloop_class, |
| 289 | + .activate = aactivate, | |
| 248 | 290 | .uninit = auninit, |
| 249 | 291 | .inputs = ainputs, |
| 250 | 292 | .outputs = aoutputs, |