Multi-input or multi-output filters should use activate now.
Unified · Split
| @@ -179,8 +179,6 @@ static const AVOption filt_name##_options[] = { \ · 178 unmodified lines | ||
| 179 | 179 | { NULL } \ |
| 180 | 180 | } |
| 181 | 181 | |
| 182 | −static int request_frame(AVFilterLink *outlink); | |
| 183 | − | |
| 184 | 182 | static av_cold int init(AVFilterContext *ctx) |
| 185 | 183 | { |
| 186 | 184 | SelectContext *select = ctx->priv; |
| @@ -201,7 +199,6 @@ static av_cold int init(AVFilterContext *ctx) · 14 unmodified lines | ||
| 201 | 199 | if (!pad.name) |
| 202 | 200 | return AVERROR(ENOMEM); |
| 203 | 201 | pad.type = ctx->filter->inputs[0].type; |
| 204 | − pad.request_frame = request_frame; | |
| 205 | 202 | if ((ret = ff_append_outpad_free_name(ctx, &pad)) < 0) |
| 206 | 203 | return ret; |
| 207 | 204 | } |
| @@ -349,7 +346,7 @@ static void select_frame(AVFilterContext *ctx, AVFrame *frame) · 141 unmodified lines | ||
| 349 | 346 | if (isnan(select->var_values[VAR_START_T])) |
| 350 | 347 | select->var_values[VAR_START_T] = TS2D(frame->pts) * av_q2d(inlink->time_base); |
| 351 | 348 | |
| 352 | − select->var_values[VAR_N ] = inl->frame_count_out; | |
| 349 | + select->var_values[VAR_N ] = inl->frame_count_out - 1; | |
| 353 | 350 | select->var_values[VAR_PTS] = TS2D(frame->pts); |
| 354 | 351 | select->var_values[VAR_T ] = TS2D(frame->pts) * av_q2d(inlink->time_base); |
| 355 | 352 | select->var_values[VAR_KEY] = !!(frame->flags & AV_FRAME_FLAG_KEY); |
| @@ -428,24 +425,35 @@ static void select_frame(AVFilterContext *ctx, AVFrame *frame) · 72 unmodified lines | ||
| 428 | 425 | select->var_values[VAR_PREV_T] = select->var_values[VAR_T]; |
| 429 | 426 | } |
| 430 | 427 | |
| 431 | −static int filter_frame(AVFilterLink *inlink, AVFrame *frame) | |
| 428 | +static int activate(AVFilterContext *ctx) | |
| 432 | 429 | { |
| 433 | − AVFilterContext *ctx = inlink->dst; | |
| 434 | 430 | SelectContext *select = ctx->priv; |
| 431 | + AVFilterLink *inlink = ctx->inputs[0]; | |
| 432 | + AVFrame *in; | |
| 433 | + int nb_eofs = 0; | |
| 434 | + int ret; | |
| 435 | 435 | |
| 436 | − select_frame(ctx, frame); | |
| 437 | − if (select->select) | |
| 438 | − return ff_filter_frame(ctx->outputs[select->select_out], frame); | |
| 436 | + for (int i = 0; i < ctx->nb_outputs; i++) | |
| 437 | + nb_eofs += ff_outlink_get_status(ctx->outputs[i]) == AVERROR_EOF; | |
| 439 | 438 | |
| 440 | − av_frame_free(&frame); | |
| 441 | − return 0; | |
| 442 | −} | |
| 439 | + if (nb_eofs == ctx->nb_outputs) { | |
| 440 | + ff_inlink_set_status(inlink, AVERROR_EOF); | |
| 441 | + return 0; | |
| 442 | + } | |
| 443 | 443 | |
| 444 | −static int request_frame(AVFilterLink *outlink) | |
| 445 | −{ | |
| 446 | − AVFilterLink *inlink = outlink->src->inputs[0]; | |
| 447 | − int ret = ff_request_frame(inlink); | |
| 448 | − return ret; | |
| 444 | + while ((ret = ff_inlink_consume_frame(inlink, &in))) { | |
| 445 | + if (ret < 0) | |
| 446 | + return ret; | |
| 447 | + select_frame(ctx, in); | |
| 448 | + if (select->select && !ff_outlink_get_status(ctx->outputs[select->select_out])) | |
| 449 | + return ff_filter_frame(ctx->outputs[select->select_out], in); | |
| 450 | + av_frame_free(&in); | |
| 451 | + }; | |
| 452 | + | |
| 453 | + FF_FILTER_FORWARD_STATUS_ALL(inlink, ctx); | |
| 454 | + FF_FILTER_FORWARD_WANTED_ANY(ctx, inlink); | |
| 455 | + | |
| 456 | + return FFERROR_NOT_READY; | |
| 449 | 457 | } |
| 450 | 458 | |
| 451 | 459 | static av_cold void uninit(AVFilterContext *ctx) |
| @@ -486,7 +494,6 @@ static const AVFilterPad avfilter_af_aselect_inputs[] = { · 34 unmodified lines | ||
| 486 | 494 | .name = "default", |
| 487 | 495 | .type = AVMEDIA_TYPE_AUDIO, |
| 488 | 496 | .config_props = config_input, |
| 489 | − .filter_frame = filter_frame, | |
| 490 | 497 | }, |
| 491 | 498 | }; |
| 492 | 499 | |
| @@ -542,7 +549,6 @@ static const AVFilterPad avfilter_vf_select_inputs[] = { · 49 unmodified lines | ||
| 542 | 549 | .name = "default", |
| 543 | 550 | .type = AVMEDIA_TYPE_VIDEO, |
| 544 | 551 | .config_props = config_input, |
| 545 | − .filter_frame = filter_frame, | |
| 546 | 552 | }, |
| 547 | 553 | }; |
| 548 | 554 | |
| @@ -553,6 +559,7 @@ const FFFilter ff_vf_select = { · 4 unmodified lines | ||
| 553 | 559 | .p.flags = AVFILTER_FLAG_DYNAMIC_OUTPUTS | AVFILTER_FLAG_METADATA_ONLY, |
| 554 | 560 | .init = select_init, |
| 555 | 561 | .uninit = uninit, |
| 562 | + .activate = activate, | |
| 556 | 563 | .priv_size = sizeof(SelectContext), |
| 557 | 564 | FILTER_INPUTS(avfilter_vf_select_inputs), |
| 558 | 565 | FILTER_QUERY_FUNC2(query_formats), |