1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-11-26 19:01:44 +02:00

lavfi/vf_libplacebo: eliminate LibplaceboInput.link

Setting it was broken in 8160178dfc, since
links are not yet set up during init. It is also redundant, as the
struct also stores the input index.

Reported-By: llyyr <llyyr.public@gmail.com>
This commit is contained in:
Anton Khirnov 2024-11-05 10:25:37 +01:00
parent 2bbbf36fe2
commit 3e9b0f7c01

View File

@ -143,7 +143,6 @@ typedef struct LibplaceboInput {
pl_queue queue;
enum pl_queue_status qstatus;
struct pl_frame_mix mix; ///< temporary storage
AVFilterLink *link;
AVFifo *out_pts; ///< timestamps of wanted output frames
int64_t status_pts;
int status;
@ -593,8 +592,7 @@ static void unlock_queue(void *priv, uint32_t qf, uint32_t qidx)
}
#endif
static int input_init(AVFilterContext *avctx, AVFilterLink *link,
LibplaceboInput *input, int idx)
static int input_init(AVFilterContext *avctx, LibplaceboInput *input, int idx)
{
LibplaceboContext *s = avctx->priv;
@ -603,7 +601,6 @@ static int input_init(AVFilterContext *avctx, AVFilterLink *link,
return AVERROR(ENOMEM);
input->queue = pl_queue_create(s->gpu);
input->renderer = pl_renderer_create(s->log, s->gpu);
input->link = link;
input->idx = idx;
return 0;
@ -690,7 +687,7 @@ static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwct
if (!s->inputs)
return AVERROR(ENOMEM);
for (int i = 0; i < s->nb_inputs; i++)
RET(input_init(avctx, avctx->inputs[i], &s->inputs[i], i));
RET(input_init(avctx, &s->inputs[i], i));
/* fall through */
fail:
@ -756,6 +753,7 @@ static void update_crops(AVFilterContext *ctx, LibplaceboInput *in,
{
FilterLink *outl = ff_filter_link(ctx->outputs[0]);
LibplaceboContext *s = ctx->priv;
const AVFilterLink *inlink = ctx->inputs[in->idx];
const AVFrame *ref = ref_frame(&in->mix);
for (int i = 0; i < in->mix.num_frames; i++) {
@ -763,15 +761,15 @@ static void update_crops(AVFilterContext *ctx, LibplaceboInput *in,
// own the entire pl_queue, and hence, the pointed-at frames.
struct pl_frame *image = (struct pl_frame *) in->mix.frames[i];
const AVFrame *src = pl_get_mapped_avframe(image);
double image_pts = src->pts * av_q2d(in->link->time_base);
double image_pts = src->pts * av_q2d(inlink->time_base);
/* Update dynamic variables */
s->var_values[VAR_IN_IDX] = s->var_values[VAR_IDX] = in->idx;
s->var_values[VAR_IN_W] = s->var_values[VAR_IW] = in->link->w;
s->var_values[VAR_IN_H] = s->var_values[VAR_IH] = in->link->h;
s->var_values[VAR_A] = (double) in->link->w / in->link->h;
s->var_values[VAR_SAR] = in->link->sample_aspect_ratio.num ?
av_q2d(in->link->sample_aspect_ratio) : 1.0;
s->var_values[VAR_IN_W] = s->var_values[VAR_IW] = inlink->w;
s->var_values[VAR_IN_H] = s->var_values[VAR_IH] = inlink->h;
s->var_values[VAR_A] = (double) inlink->w / inlink->h;
s->var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ?
av_q2d(inlink->sample_aspect_ratio) : 1.0;
s->var_values[VAR_IN_T] = s->var_values[VAR_T] = image_pts;
s->var_values[VAR_OUT_T] = s->var_values[VAR_OT] = target_pts;
s->var_values[VAR_N] = outl->frame_count_out;
@ -809,7 +807,7 @@ static void update_crops(AVFilterContext *ctx, LibplaceboInput *in,
target->crop.y1 = target->crop.y0 + s->var_values[VAR_POS_H];
if (s->normalize_sar) {
float aspect = pl_rect2df_aspect(&image->crop);
aspect *= av_q2d(in->link->sample_aspect_ratio);
aspect *= av_q2d(inlink->sample_aspect_ratio);
pl_rect2df_aspect_set(&target->crop, aspect, s->pad_crop_ratio);
}
}
@ -899,7 +897,7 @@ static int output_frame(AVFilterContext *ctx, int64_t pts)
opts->params.blend_params = NULL;
for (int i = 0; i < s->nb_inputs; i++) {
LibplaceboInput *in = &s->inputs[i];
FilterLink *il = ff_filter_link(in->link);
FilterLink *il = ff_filter_link(ctx->inputs[in->idx]);
FilterLink *ol = ff_filter_link(outlink);
int high_fps = av_cmp_q(il->frame_rate, ol->frame_rate) >= 0;
if (in->qstatus != PL_QUEUE_OK)
@ -960,14 +958,15 @@ static int handle_input(AVFilterContext *ctx, LibplaceboInput *input)
int ret, status;
LibplaceboContext *s = ctx->priv;
AVFilterLink *outlink = ctx->outputs[0];
AVFilterLink *inlink = ctx->inputs[input->idx];
AVFrame *in;
int64_t pts;
while ((ret = ff_inlink_consume_frame(input->link, &in)) > 0) {
while ((ret = ff_inlink_consume_frame(inlink, &in)) > 0) {
in->opaque = s;
pl_queue_push(input->queue, &(struct pl_source_frame) {
.pts = in->pts * av_q2d(input->link->time_base),
.duration = in->duration * av_q2d(input->link->time_base),
.pts = in->pts * av_q2d(inlink->time_base),
.duration = in->duration * av_q2d(inlink->time_base),
.first_field = pl_field_from_avframe(in),
.frame_data = in,
.map = map_frame,
@ -977,7 +976,7 @@ static int handle_input(AVFilterContext *ctx, LibplaceboInput *input)
if (!s->fps.num) {
/* Internally queue an output frame for the same PTS */
pts = av_rescale_q(in->pts, input->link->time_base, outlink->time_base);
pts = av_rescale_q(in->pts, inlink->time_base, outlink->time_base);
av_fifo_write(input->out_pts, &pts, 1);
}
}
@ -985,8 +984,8 @@ static int handle_input(AVFilterContext *ctx, LibplaceboInput *input)
if (ret < 0)
return ret;
if (!input->status && ff_inlink_acknowledge_status(input->link, &status, &pts)) {
pts = av_rescale_q_rnd(pts, input->link->time_base, outlink->time_base,
if (!input->status && ff_inlink_acknowledge_status(inlink, &status, &pts)) {
pts = av_rescale_q_rnd(pts, inlink->time_base, outlink->time_base,
AV_ROUND_UP);
pl_queue_push(input->queue, NULL); /* Signal EOF to pl_queue */
input->status = status;
@ -1035,7 +1034,7 @@ static int libplacebo_activate(AVFilterContext *ctx)
if (av_fifo_peek(in->out_pts, &pts, 1, 0) >= 0) {
out_pts = FFMIN(out_pts, pts);
} else if (!in->status) {
ff_inlink_request_frame(in->link);
ff_inlink_request_frame(ctx->inputs[in->idx]);
retry = true;
}
}
@ -1061,7 +1060,7 @@ static int libplacebo_activate(AVFilterContext *ctx)
switch (in->qstatus) {
case PL_QUEUE_MORE:
ff_inlink_request_frame(in->link);
ff_inlink_request_frame(ctx->inputs[in->idx]);
retry = true;
break;
case PL_QUEUE_OK: