[FFmpeg-devel] [PATCH] lavfi/vf_libplacebo: eliminate LibplaceboInput.link

Anton Khirnov anton at khirnov.net
Tue Nov 5 11:28:28 EET 2024


Setting it was broken in 8160178dfc0e6bdaacf80dec58e595a9d595eedc, 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 at gmail.com>
---
 libavfilter/vf_libplacebo.c | 41 ++++++++++++++++++-------------------
 1 file changed, 20 insertions(+), 21 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 77219b830a..8f1787c123 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -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:
-- 
2.43.0



More information about the ffmpeg-devel mailing list