Unified · Split
| @@ -116,6 +116,7 @@ static int push_samples(AVFilterContext *ctx, int nb_samples) · 115 unmodified lines | |||
| 116 | return ret; | 116 | return ret; |
| 117 | 117 | ||
| 118 | if (s->current_sample >= s->nb_samples) { | 118 | if (s->current_sample >= s->nb_samples) { |
| 119 | s->duration = s->pts; | ||
| 119 | s->current_sample = 0; | 120 | s->current_sample = 0; |
| 120 | 121 | ||
| 121 | if (s->loop > 0) | 122 | if (s->loop > 0) |
| @@ -205,13 +206,55 @@ static int arequest_frame(AVFilterLink *outlink) · 83 unmodified lines | |||
| 205 | ret = push_samples(ctx, 1024); | 206 | ret = push_samples(ctx, 1024); |
| 206 | } | 207 | } |
| 207 | 208 | ||
| 208 | if (ret == AVERROR_EOF && s->nb_samples > 0 && s->loop != 0) { | 209 | if (s->eof && s->nb_samples > 0 && s->loop != 0) { |
| 209 | ret = push_samples(ctx, outlink->sample_rate); | 210 | ret = push_samples(ctx, 1024); |
| 210 | } | 211 | } |
| 211 | 212 | ||
| 212 | return ret; | 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 | static const AVOption aloop_options[] = { | 258 | static const AVOption aloop_options[] = { |
| 216 | { "loop", "number of loops", OFFSET(loop), AV_OPT_TYPE_INT, {.i64 = 0 }, -1, INT_MAX, AFLAGS }, | 259 | { "loop", "number of loops", OFFSET(loop), AV_OPT_TYPE_INT, {.i64 = 0 }, -1, INT_MAX, AFLAGS }, |
| 217 | { "size", "max number of samples to loop", OFFSET(size), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT32_MAX, AFLAGS }, | 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 | .name = "default", | 269 | .name = "default", |
| 227 | .type = AVMEDIA_TYPE_AUDIO, | 270 | .type = AVMEDIA_TYPE_AUDIO, |
| 228 | .filter_frame = afilter_frame, | ||
| 229 | .config_props = aconfig_input, | 271 | .config_props = aconfig_input, |
| 230 | }, | 272 | }, |
| 231 | { NULL } | 273 | { NULL } |
| @@ -235,7 +277,6 @@ static const AVFilterPad aoutputs[] = { · 3 unmodified lines | |||
| 235 | { | 277 | { |
| 236 | .name = "default", | 278 | .name = "default", |
| 237 | .type = AVMEDIA_TYPE_AUDIO, | 279 | .type = AVMEDIA_TYPE_AUDIO, |
| 238 | .request_frame = arequest_frame, | ||
| 239 | }, | 280 | }, |
| 240 | { NULL } | 281 | { NULL } |
| 241 | }; | 282 | }; |
| @@ -245,6 +286,7 @@ AVFilter ff_af_aloop = { · 3 unmodified lines | |||
| 245 | .description = NULL_IF_CONFIG_SMALL("Loop audio samples."), | 286 | .description = NULL_IF_CONFIG_SMALL("Loop audio samples."), |
| 246 | .priv_size = sizeof(LoopContext), | 287 | .priv_size = sizeof(LoopContext), |
| 247 | .priv_class = &aloop_class, | 288 | .priv_class = &aloop_class, |
| 289 | .activate = aactivate, | ||
| 248 | .uninit = auninit, | 290 | .uninit = auninit, |
| 249 | .inputs = ainputs, | 291 | .inputs = ainputs, |
| 250 | .outputs = aoutputs, | 292 | .outputs = aoutputs, |