Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case
@ 2023-06-16  9:29 Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 02/22] lavfi/vf_libplacebo: move input-specific state to struct Niklas Haas
                   ` (20 more replies)
  0 siblings, 21 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

If the input queue is EOF, then the s->status check should already have
covered it, and prevented the code from getting this far.

If we still hit this case for some reason, it's probably a bug. Better
to hit the AVERROR_BUG branch.
---
 libavfilter/vf_libplacebo.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 242c8a13f5..a048424cec 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -949,9 +949,6 @@ static int libplacebo_activate(AVFilterContext *ctx)
             if (!s->fps.num)
                 av_fifo_drain2(s->out_pts, 1);
             return output_frame_mix(ctx, &mix, pts);
-        case PL_QUEUE_EOF:
-            ff_outlink_set_status(outlink, AVERROR_EOF, pts);
-            return 0;
         case PL_QUEUE_ERR:
             return AVERROR_EXTERNAL;
         }
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 02/22] lavfi/vf_libplacebo: move input-specific state to struct
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 03/22] lavfi/vf_libplacebo: move input handling to separate function Niklas Haas
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

In anticipation of a refactor which will enable multiple input support.

Note: the renderer is also input-specific because it maintains a frame
cache, HDR peak detection state and mixing cache, all of which are tied
to a specific input stream.
---
 libavfilter/vf_libplacebo.c | 80 ++++++++++++++++++++++++-------------
 1 file changed, 52 insertions(+), 28 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index a048424cec..10fd432745 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -113,6 +113,16 @@ enum var_name {
     VAR_VARS_NB
 };
 
+/* per-input dynamic filter state */
+typedef struct LibplaceboInput {
+    pl_renderer renderer;
+    pl_queue queue;
+    AVFilterLink *link;
+    AVFifo *out_pts; ///< timestamps of wanted output frames
+    int64_t status_pts;
+    int status;
+} LibplaceboInput;
+
 typedef struct LibplaceboContext {
     /* lavfi vulkan*/
     FFVulkanContext vkctx;
@@ -121,14 +131,10 @@ typedef struct LibplaceboContext {
     pl_log log;
     pl_vulkan vulkan;
     pl_gpu gpu;
-    pl_renderer renderer;
-    pl_queue queue;
     pl_tex tex[4];
 
-    /* filter state */
-    AVFifo *out_pts; ///< timestamps of wanted output frames
-    int64_t status_pts;
-    int status;
+    /* input state */
+    LibplaceboInput input;
 
     /* settings */
     char *out_format_string;
@@ -536,8 +542,6 @@ static int libplacebo_init(AVFilterContext *avctx)
     RET(av_expr_parse(&s->pos_h_pexpr, s->pos_h_expr, var_names,
                       NULL, NULL, NULL, NULL, 0, s));
 
-    /* Initialize dynamic filter state */
-    s->out_pts = av_fifo_alloc2(1, sizeof(int64_t), AV_FIFO_FLAG_AUTO_GROW);
     if (strcmp(s->fps_string, "none") != 0)
         RET(av_parse_video_rate(&s->fps, s->fps_string));
 
@@ -564,6 +568,28 @@ static void unlock_queue(void *priv, uint32_t qf, uint32_t qidx)
 }
 #endif
 
+static int input_init(AVFilterContext *avctx, AVFilterLink *link,
+                      LibplaceboInput *input)
+{
+    LibplaceboContext *s = avctx->priv;
+
+    input->out_pts = av_fifo_alloc2(1, sizeof(int64_t), AV_FIFO_FLAG_AUTO_GROW);
+    if (!input->out_pts)
+        return AVERROR(ENOMEM);
+    input->queue = pl_queue_create(s->gpu);
+    input->renderer = pl_renderer_create(s->log, s->gpu);
+    input->link = link;
+
+    return 0;
+}
+
+static void input_uninit(LibplaceboInput *input)
+{
+    pl_renderer_destroy(&input->renderer);
+    pl_queue_destroy(&input->queue);
+    av_fifo_freep2(&input->out_pts);
+}
+
 static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwctx)
 {
     int err = 0;
@@ -620,10 +646,7 @@ static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwct
         goto fail;
     }
 
-    /* Create the renderer */
     s->gpu = s->vulkan->gpu;
-    s->renderer = pl_renderer_create(s->log, s->gpu);
-    s->queue = pl_queue_create(s->gpu);
 
     /* Parse the user shaders, if requested */
     if (s->shader_bin_len)
@@ -634,6 +657,9 @@ static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwct
         RET(parse_shader(avctx, buf, buf_len));
     }
 
+    /* Initialize inputs */
+    RET(input_init(avctx, avctx->inputs[0], &s->input));
+
     /* fall through */
 fail:
     if (buf)
@@ -649,8 +675,7 @@ static void libplacebo_uninit(AVFilterContext *avctx)
         pl_tex_destroy(s->gpu, &s->tex[i]);
     for (int i = 0; i < s->num_hooks; i++)
         pl_mpv_user_shader_destroy(&s->hooks[i]);
-    pl_renderer_destroy(&s->renderer);
-    pl_queue_destroy(&s->queue);
+    input_uninit(&s->input);
     pl_vulkan_destroy(&s->vulkan);
     pl_log_destroy(&s->log);
     ff_vk_uninit(&s->vkctx);
@@ -664,7 +689,6 @@ static void libplacebo_uninit(AVFilterContext *avctx)
     av_expr_free(s->pos_y_pexpr);
     av_expr_free(s->pos_w_pexpr);
     av_expr_free(s->pos_h_pexpr);
-    av_fifo_freep2(&s->out_pts);
 }
 
 static int libplacebo_process_command(AVFilterContext *ctx, const char *cmd,
@@ -826,7 +850,7 @@ static int output_frame_mix(AVFilterContext *ctx,
     }
 
     update_crops(ctx, mix, &target, ref_sig, out->pts * av_q2d(outlink->time_base));
-    pl_render_image_mix(s->renderer, mix, &target, &s->params);
+    pl_render_image_mix(s->input.renderer, mix, &target, &s->params);
 
     if (outdesc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
         pl_unmap_avframe(s->gpu, &target);
@@ -886,7 +910,7 @@ static int libplacebo_activate(AVFilterContext *ctx)
 
     while ((ret = ff_inlink_consume_frame(inlink, &in)) > 0) {
         in->opaque = s;
-        pl_queue_push(s->queue, &(struct pl_source_frame) {
+        pl_queue_push(s->input.queue, &(struct pl_source_frame) {
             .pts         = in->pts * av_q2d(inlink->time_base),
             .duration    = in->duration * av_q2d(inlink->time_base),
             .first_field = pl_field_from_avframe(in),
@@ -899,19 +923,19 @@ static int libplacebo_activate(AVFilterContext *ctx)
         if (!s->fps.num) {
             /* Internally queue an output frame for the same PTS */
             av_assert1(!av_cmp_q(inlink->time_base, outlink->time_base));
-            av_fifo_write(s->out_pts, &in->pts, 1);
+            av_fifo_write(s->input.out_pts, &in->pts, 1);
         }
     }
 
     if (ret < 0)
         return ret;
 
-    if (!s->status && ff_inlink_acknowledge_status(inlink, &status, &pts)) {
+    if (!s->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(s->queue, NULL); /* Signal EOF to pl_queue */
-        s->status = status;
-        s->status_pts = pts;
+        pl_queue_push(s->input.queue, NULL); /* Signal EOF to pl_queue */
+        s->input.status = status;
+        s->input.status_pts = pts;
     }
 
     if (ff_outlink_frame_wanted(outlink)) {
@@ -920,22 +944,22 @@ static int libplacebo_activate(AVFilterContext *ctx)
 
         if (s->fps.num) {
             pts = outlink->frame_count_out;
-        } else if (av_fifo_peek(s->out_pts, &pts, 1, 0) < 0) {
+        } else if (av_fifo_peek(s->input.out_pts, &pts, 1, 0) < 0) {
             /* No frames queued */
-            if (s->status) {
-                pts = s->status_pts;
+            if (s->input.status) {
+                pts = s->input.status_pts;
             } else {
                 ff_inlink_request_frame(inlink);
                 return 0;
             }
         }
 
-        if (s->status && pts >= s->status_pts) {
-            ff_outlink_set_status(outlink, s->status, s->status_pts);
+        if (s->input.status && pts >= s->input.status_pts) {
+            ff_outlink_set_status(outlink, s->input.status, s->input.status_pts);
             return 0;
         }
 
-        ret = pl_queue_update(s->queue, &mix, pl_queue_params(
+        ret = pl_queue_update(s->input.queue, &mix, pl_queue_params(
             .pts            = pts * av_q2d(outlink->time_base),
             .radius         = pl_frame_mix_radius(&s->params),
             .vsync_duration = av_q2d(av_inv_q(outlink->frame_rate)),
@@ -947,7 +971,7 @@ static int libplacebo_activate(AVFilterContext *ctx)
             return 0;
         case PL_QUEUE_OK:
             if (!s->fps.num)
-                av_fifo_drain2(s->out_pts, 1);
+                av_fifo_drain2(s->input.out_pts, 1);
             return output_frame_mix(ctx, &mix, pts);
         case PL_QUEUE_ERR:
             return AVERROR_EXTERNAL;
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 03/22] lavfi/vf_libplacebo: move input handling to separate function
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 02/22] lavfi/vf_libplacebo: move input-specific state to struct Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 04/22] lavfi/vf_libplacebo: cosmetic Niklas Haas
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

To be re-used once we support more than one input.
---
 libavfilter/vf_libplacebo.c | 45 ++++++++++++++++++++++++-------------
 1 file changed, 29 insertions(+), 16 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 10fd432745..879a3a0508 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -896,23 +896,19 @@ static void discard_frame(const struct pl_source_frame *src)
     av_frame_free(&avframe);
 }
 
-static int libplacebo_activate(AVFilterContext *ctx)
+static int handle_input(AVFilterContext *ctx, LibplaceboInput *input)
 {
     int ret, status;
     LibplaceboContext *s = ctx->priv;
-    AVFilterLink *inlink = ctx->inputs[0];
     AVFilterLink *outlink = ctx->outputs[0];
     AVFrame *in;
     int64_t pts;
 
-    FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
-    pl_log_level_update(s->log, get_log_level());
-
-    while ((ret = ff_inlink_consume_frame(inlink, &in)) > 0) {
+    while ((ret = ff_inlink_consume_frame(input->link, &in)) > 0) {
         in->opaque = s;
-        pl_queue_push(s->input.queue, &(struct pl_source_frame) {
-            .pts         = in->pts * av_q2d(inlink->time_base),
-            .duration    = in->duration * av_q2d(inlink->time_base),
+        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),
             .first_field = pl_field_from_avframe(in),
             .frame_data  = in,
             .map         = map_frame,
@@ -922,22 +918,39 @@ static int libplacebo_activate(AVFilterContext *ctx)
 
         if (!s->fps.num) {
             /* Internally queue an output frame for the same PTS */
-            av_assert1(!av_cmp_q(inlink->time_base, outlink->time_base));
-            av_fifo_write(s->input.out_pts, &in->pts, 1);
+            pts = av_rescale_q(in->pts, input->link->time_base, outlink->time_base);
+            av_fifo_write(input->out_pts, &pts, 1);
         }
     }
 
     if (ret < 0)
         return ret;
 
-    if (!s->input.status && ff_inlink_acknowledge_status(inlink, &status, &pts)) {
-        pts = av_rescale_q_rnd(pts, inlink->time_base, outlink->time_base,
+    if (!input->status && ff_inlink_acknowledge_status(input->link, &status, &pts)) {
+        pts = av_rescale_q_rnd(pts, input->link->time_base, outlink->time_base,
                                AV_ROUND_UP);
-        pl_queue_push(s->input.queue, NULL); /* Signal EOF to pl_queue */
-        s->input.status = status;
-        s->input.status_pts = pts;
+        pl_queue_push(input->queue, NULL); /* Signal EOF to pl_queue */
+        input->status = status;
+        input->status_pts = pts;
     }
 
+    return 0;
+}
+
+static int libplacebo_activate(AVFilterContext *ctx)
+{
+    int ret;
+    LibplaceboContext *s = ctx->priv;
+    AVFilterLink *inlink = ctx->inputs[0];
+    AVFilterLink *outlink = ctx->outputs[0];
+    int64_t pts;
+
+    FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
+    pl_log_level_update(s->log, get_log_level());
+
+    if ((ret = handle_input(ctx, &s->input)) < 0)
+        return ret;
+
     if (ff_outlink_frame_wanted(outlink)) {
         struct pl_frame_mix mix;
         enum pl_queue_status ret;
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 04/22] lavfi/vf_libplacebo: cosmetic
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 02/22] lavfi/vf_libplacebo: move input-specific state to struct Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 03/22] lavfi/vf_libplacebo: move input handling to separate function Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 05/22] lavfi/vf_libplacebo: move temporary vars into per-input struct Niklas Haas
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

Assign local variable 'in' for 's->input' and replace 'inlink' by
'in->link' to avoid hard-coding ID 0 in more than one place.
---
 libavfilter/vf_libplacebo.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 879a3a0508..beddd2f796 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -941,14 +941,14 @@ static int libplacebo_activate(AVFilterContext *ctx)
 {
     int ret;
     LibplaceboContext *s = ctx->priv;
-    AVFilterLink *inlink = ctx->inputs[0];
+    LibplaceboInput *in = &s->input;
     AVFilterLink *outlink = ctx->outputs[0];
     int64_t pts;
 
-    FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
+    FF_FILTER_FORWARD_STATUS_BACK(outlink, in->link);
     pl_log_level_update(s->log, get_log_level());
 
-    if ((ret = handle_input(ctx, &s->input)) < 0)
+    if ((ret = handle_input(ctx, in)) < 0)
         return ret;
 
     if (ff_outlink_frame_wanted(outlink)) {
@@ -957,22 +957,22 @@ static int libplacebo_activate(AVFilterContext *ctx)
 
         if (s->fps.num) {
             pts = outlink->frame_count_out;
-        } else if (av_fifo_peek(s->input.out_pts, &pts, 1, 0) < 0) {
+        } else if (av_fifo_peek(in->out_pts, &pts, 1, 0) < 0) {
             /* No frames queued */
-            if (s->input.status) {
-                pts = s->input.status_pts;
+            if (in->status) {
+                pts = in->status_pts;
             } else {
-                ff_inlink_request_frame(inlink);
+                ff_inlink_request_frame(in->link);
                 return 0;
             }
         }
 
-        if (s->input.status && pts >= s->input.status_pts) {
-            ff_outlink_set_status(outlink, s->input.status, s->input.status_pts);
+        if (in->status && pts >= in->status_pts) {
+            ff_outlink_set_status(outlink, in->status, in->status_pts);
             return 0;
         }
 
-        ret = pl_queue_update(s->input.queue, &mix, pl_queue_params(
+        ret = pl_queue_update(in->queue, &mix, pl_queue_params(
             .pts            = pts * av_q2d(outlink->time_base),
             .radius         = pl_frame_mix_radius(&s->params),
             .vsync_duration = av_q2d(av_inv_q(outlink->frame_rate)),
@@ -980,11 +980,11 @@ static int libplacebo_activate(AVFilterContext *ctx)
 
         switch (ret) {
         case PL_QUEUE_MORE:
-            ff_inlink_request_frame(inlink);
+            ff_inlink_request_frame(in->link);
             return 0;
         case PL_QUEUE_OK:
             if (!s->fps.num)
-                av_fifo_drain2(s->input.out_pts, 1);
+                av_fifo_drain2(in->out_pts, 1);
             return output_frame_mix(ctx, &mix, pts);
         case PL_QUEUE_ERR:
             return AVERROR_EXTERNAL;
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 05/22] lavfi/vf_libplacebo: move temporary vars into per-input struct
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
                   ` (2 preceding siblings ...)
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 04/22] lavfi/vf_libplacebo: cosmetic Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 06/22] lavif/vf_libplacebo: remove pl_frame_mix from output_frame_mix Niklas Haas
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

Including the queue status, because these will need to be re-queried
inside output_frame_mix when that function is refactored to handle
multiple inputs.
---
 libavfilter/vf_libplacebo.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index beddd2f796..4baa766bac 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -117,6 +117,8 @@ enum var_name {
 typedef struct LibplaceboInput {
     pl_renderer renderer;
     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;
@@ -952,9 +954,6 @@ static int libplacebo_activate(AVFilterContext *ctx)
         return ret;
 
     if (ff_outlink_frame_wanted(outlink)) {
-        struct pl_frame_mix mix;
-        enum pl_queue_status ret;
-
         if (s->fps.num) {
             pts = outlink->frame_count_out;
         } else if (av_fifo_peek(in->out_pts, &pts, 1, 0) < 0) {
@@ -972,20 +971,20 @@ static int libplacebo_activate(AVFilterContext *ctx)
             return 0;
         }
 
-        ret = pl_queue_update(in->queue, &mix, pl_queue_params(
+        in->qstatus = pl_queue_update(in->queue, &in->mix, pl_queue_params(
             .pts            = pts * av_q2d(outlink->time_base),
             .radius         = pl_frame_mix_radius(&s->params),
             .vsync_duration = av_q2d(av_inv_q(outlink->frame_rate)),
         ));
 
-        switch (ret) {
+        switch (in->qstatus) {
         case PL_QUEUE_MORE:
             ff_inlink_request_frame(in->link);
             return 0;
         case PL_QUEUE_OK:
             if (!s->fps.num)
                 av_fifo_drain2(in->out_pts, 1);
-            return output_frame_mix(ctx, &mix, pts);
+            return output_frame_mix(ctx, &in->mix, pts);
         case PL_QUEUE_ERR:
             return AVERROR_EXTERNAL;
         }
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 06/22] lavif/vf_libplacebo: remove pl_frame_mix from output_frame_mix
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
                   ` (3 preceding siblings ...)
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 05/22] lavfi/vf_libplacebo: move temporary vars into per-input struct Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 07/22] lavfi/vf_libplacebo: factor out ref frame logic Niklas Haas
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

Instead, rename this function to `output_frame` and make it pull the
`pl_frame_mix` from the input structure. Step towards handling multiple
inputs.
---
 libavfilter/vf_libplacebo.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 4baa766bac..0289187b46 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -760,20 +760,19 @@ static void update_crops(AVFilterContext *ctx,
     }
 }
 
-/* Construct and emit an output frame for a given frame mix */
-static int output_frame_mix(AVFilterContext *ctx,
-                            struct pl_frame_mix *mix,
-                            int64_t pts)
+/* Construct and emit an output frame for a given timestamp */
+static int output_frame(AVFilterContext *ctx, int64_t pts)
 {
     int err = 0, ok, changed_csp;
     LibplaceboContext *s = ctx->priv;
+    LibplaceboInput *in = &s->input;
     AVFilterLink *outlink = ctx->outputs[0];
     const AVPixFmtDescriptor *outdesc = av_pix_fmt_desc_get(outlink->format);
     struct pl_frame target;
     const AVFrame *ref;
     AVFrame *out;
     uint64_t ref_sig;
-    if (!mix->num_frames)
+    if (!in->mix.num_frames)
         return 0;
 
     out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
@@ -781,11 +780,11 @@ static int output_frame_mix(AVFilterContext *ctx,
         return AVERROR(ENOMEM);
 
     /* Use the last frame before current PTS value as reference */
-    for (int i = 0; i < mix->num_frames; i++) {
-        if (i && mix->timestamps[i] > 0.0f)
+    for (int i = 0; i < in->mix.num_frames; i++) {
+        if (i && in->mix.timestamps[i] > 0.0f)
             break;
-        ref = pl_get_mapped_avframe(mix->frames[i]);
-        ref_sig = mix->signatures[i];
+        ref = pl_get_mapped_avframe(in->mix.frames[i]);
+        ref_sig = in->mix.signatures[i];
     }
 
     RET(av_frame_copy_props(out, ref));
@@ -851,8 +850,8 @@ static int output_frame_mix(AVFilterContext *ctx,
         goto fail;
     }
 
-    update_crops(ctx, mix, &target, ref_sig, out->pts * av_q2d(outlink->time_base));
-    pl_render_image_mix(s->input.renderer, mix, &target, &s->params);
+    update_crops(ctx, &in->mix, &target, ref_sig, out->pts * av_q2d(outlink->time_base));
+    pl_render_image_mix(in->renderer, &in->mix, &target, &s->params);
 
     if (outdesc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
         pl_unmap_avframe(s->gpu, &target);
@@ -984,7 +983,7 @@ static int libplacebo_activate(AVFilterContext *ctx)
         case PL_QUEUE_OK:
             if (!s->fps.num)
                 av_fifo_drain2(in->out_pts, 1);
-            return output_frame_mix(ctx, &in->mix, pts);
+            return output_frame(ctx, pts);
         case PL_QUEUE_ERR:
             return AVERROR_EXTERNAL;
         }
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 07/22] lavfi/vf_libplacebo: factor out ref frame logic
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
                   ` (4 preceding siblings ...)
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 06/22] lavif/vf_libplacebo: remove pl_frame_mix from output_frame_mix Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 08/22] lavfi/vf_libplacebo: use correct link in update_crops() Niklas Haas
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

Instead of finding the ref frame in output_frame() and then passing its
signature to update_crops(), pull out the logic and invoke it a second
time inside update_crops().

This may seem wasteful at present, but will actually become required in
the future, since update_crops() runs on *every* input, and needs values
specific to that input (which the signature isn't), while output_frame()
is only interested in a single input. It's much easier to just split the
logic cleanly.
---
 libavfilter/vf_libplacebo.c | 29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 0289187b46..b83df24a84 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -706,11 +706,21 @@ fail:
     return err;
 }
 
+static const AVFrame *ref_frame(const struct pl_frame_mix *mix)
+{
+    for (int i = 0; i < mix->num_frames; i++) {
+        if (i+1 == mix->num_frames || mix->timestamps[i+1] > 0)
+            return pl_get_mapped_avframe(mix->frames[i]);
+    }
+    return NULL;
+}
+
 static void update_crops(AVFilterContext *ctx,
                          struct pl_frame_mix *mix, struct pl_frame *target,
-                         uint64_t ref_sig, double target_pts)
+                         double target_pts)
 {
     LibplaceboContext *s = ctx->priv;
+    const AVFrame *ref = ref_frame(mix);
 
     for (int i = 0; i < mix->num_frames; i++) {
         // Mutate the `pl_frame.crop` fields in-place. This is fine because we
@@ -745,7 +755,7 @@ static void update_crops(AVFilterContext *ctx,
         image->crop.x1 = image->crop.x0 + s->var_values[VAR_CROP_W];
         image->crop.y1 = image->crop.y0 + s->var_values[VAR_CROP_H];
 
-        if (mix->signatures[i] == ref_sig) {
+        if (src == ref) {
             /* Only update the target crop once, for the 'reference' frame */
             target->crop.x0 = av_expr_eval(s->pos_x_pexpr, s->var_values, NULL);
             target->crop.y0 = av_expr_eval(s->pos_y_pexpr, s->var_values, NULL);
@@ -768,25 +778,16 @@ static int output_frame(AVFilterContext *ctx, int64_t pts)
     LibplaceboInput *in = &s->input;
     AVFilterLink *outlink = ctx->outputs[0];
     const AVPixFmtDescriptor *outdesc = av_pix_fmt_desc_get(outlink->format);
+    const AVFrame *ref = ref_frame(&in->mix);
     struct pl_frame target;
-    const AVFrame *ref;
     AVFrame *out;
-    uint64_t ref_sig;
-    if (!in->mix.num_frames)
+    if (!ref)
         return 0;
 
     out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     if (!out)
         return AVERROR(ENOMEM);
 
-    /* Use the last frame before current PTS value as reference */
-    for (int i = 0; i < in->mix.num_frames; i++) {
-        if (i && in->mix.timestamps[i] > 0.0f)
-            break;
-        ref = pl_get_mapped_avframe(in->mix.frames[i]);
-        ref_sig = in->mix.signatures[i];
-    }
-
     RET(av_frame_copy_props(out, ref));
     out->pts = pts;
     out->width = outlink->w;
@@ -850,7 +851,7 @@ static int output_frame(AVFilterContext *ctx, int64_t pts)
         goto fail;
     }
 
-    update_crops(ctx, &in->mix, &target, ref_sig, out->pts * av_q2d(outlink->time_base));
+    update_crops(ctx, &in->mix, &target, out->pts * av_q2d(outlink->time_base));
     pl_render_image_mix(in->renderer, &in->mix, &target, &s->params);
 
     if (outdesc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 08/22] lavfi/vf_libplacebo: use correct link in update_crops()
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
                   ` (5 preceding siblings ...)
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 07/22] lavfi/vf_libplacebo: factor out ref frame logic Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 09/22] lavfi/vf_libplacebo: replace s->input by dynamic array Niklas Haas
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

Instead of hard-coding input 0, pass the per-input structure and use the
link contained inside it.
---
 libavfilter/vf_libplacebo.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index b83df24a84..408fb3918a 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -715,19 +715,18 @@ static const AVFrame *ref_frame(const struct pl_frame_mix *mix)
     return NULL;
 }
 
-static void update_crops(AVFilterContext *ctx,
-                         struct pl_frame_mix *mix, struct pl_frame *target,
-                         double target_pts)
+static void update_crops(AVFilterContext *ctx, LibplaceboInput *in,
+                         struct pl_frame *target, double target_pts)
 {
     LibplaceboContext *s = ctx->priv;
-    const AVFrame *ref = ref_frame(mix);
+    const AVFrame *ref = ref_frame(&in->mix);
 
-    for (int i = 0; i < mix->num_frames; i++) {
+    for (int i = 0; i < in->mix.num_frames; i++) {
         // Mutate the `pl_frame.crop` fields in-place. This is fine because we
         // own the entire pl_queue, and hence, the pointed-at frames.
-        struct pl_frame *image = (struct pl_frame *) mix->frames[i];
+        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(ctx->inputs[0]->time_base);
+        double image_pts = src->pts * av_q2d(in->link->time_base);
 
         /* Update dynamic variables */
         s->var_values[VAR_IN_T]   = s->var_values[VAR_T]  = image_pts;
@@ -851,7 +850,7 @@ static int output_frame(AVFilterContext *ctx, int64_t pts)
         goto fail;
     }
 
-    update_crops(ctx, &in->mix, &target, out->pts * av_q2d(outlink->time_base));
+    update_crops(ctx, in, &target, out->pts * av_q2d(outlink->time_base));
     pl_render_image_mix(in->renderer, &in->mix, &target, &s->params);
 
     if (outdesc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 09/22] lavfi/vf_libplacebo: replace s->input by dynamic array
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
                   ` (6 preceding siblings ...)
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 08/22] lavfi/vf_libplacebo: use correct link in update_crops() Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16 12:09   ` Andreas Rheinhardt
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 10/22] lavfi/vf_libplacebo: keep track of latest status globally Niklas Haas
                   ` (12 subsequent siblings)
  20 siblings, 1 reply; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

For now, hard-coded to 1 element.
---
 libavfilter/vf_libplacebo.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 408fb3918a..fbac1b0354 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -136,7 +136,8 @@ typedef struct LibplaceboContext {
     pl_tex tex[4];
 
     /* input state */
-    LibplaceboInput input;
+    LibplaceboInput *inputs;
+    int nb_inputs;
 
     /* settings */
     char *out_format_string;
@@ -660,7 +661,12 @@ static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwct
     }
 
     /* Initialize inputs */
-    RET(input_init(avctx, avctx->inputs[0], &s->input));
+    s->nb_inputs = 1;
+    s->inputs = av_calloc(s->nb_inputs, sizeof(*s->inputs));
+    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]));
 
     /* fall through */
 fail:
@@ -677,7 +683,9 @@ static void libplacebo_uninit(AVFilterContext *avctx)
         pl_tex_destroy(s->gpu, &s->tex[i]);
     for (int i = 0; i < s->num_hooks; i++)
         pl_mpv_user_shader_destroy(&s->hooks[i]);
-    input_uninit(&s->input);
+    for (int i = 0; i < s->nb_inputs && s->inputs; i++)
+        input_uninit(&s->inputs[i]);
+    av_freep(&s->inputs);
     pl_vulkan_destroy(&s->vulkan);
     pl_log_destroy(&s->log);
     ff_vk_uninit(&s->vkctx);
@@ -774,7 +782,7 @@ static int output_frame(AVFilterContext *ctx, int64_t pts)
 {
     int err = 0, ok, changed_csp;
     LibplaceboContext *s = ctx->priv;
-    LibplaceboInput *in = &s->input;
+    LibplaceboInput *in = &s->inputs[0];
     AVFilterLink *outlink = ctx->outputs[0];
     const AVPixFmtDescriptor *outdesc = av_pix_fmt_desc_get(outlink->format);
     const AVFrame *ref = ref_frame(&in->mix);
@@ -942,7 +950,7 @@ static int libplacebo_activate(AVFilterContext *ctx)
 {
     int ret;
     LibplaceboContext *s = ctx->priv;
-    LibplaceboInput *in = &s->input;
+    LibplaceboInput *in = &s->inputs[0];
     AVFilterLink *outlink = ctx->outputs[0];
     int64_t pts;
 
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 10/22] lavfi/vf_libplacebo: keep track of latest status globally
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
                   ` (7 preceding siblings ...)
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 09/22] lavfi/vf_libplacebo: replace s->input by dynamic array Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 11/22] lavfi/vf_libplacebo: support blending multiple inputs Niklas Haas
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

This field will effectively hold the most recent status set by any
input. Currently functionally equivalent to input->status, but will
change soon.
---
 libavfilter/vf_libplacebo.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index fbac1b0354..d6f19f166d 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -138,6 +138,8 @@ typedef struct LibplaceboContext {
     /* input state */
     LibplaceboInput *inputs;
     int nb_inputs;
+    int64_t status_pts; ///< tracks status of most recently used input
+    int status;
 
     /* settings */
     char *out_format_string;
@@ -941,6 +943,11 @@ static int handle_input(AVFilterContext *ctx, LibplaceboInput *input)
         pl_queue_push(input->queue, NULL); /* Signal EOF to pl_queue */
         input->status = status;
         input->status_pts = pts;
+        if (pts >= s->status_pts) {
+            /* Also propagate to output unless overwritten by later status change */
+            s->status = status;
+            s->status_pts = pts;
+        }
     }
 
     return 0;
@@ -973,8 +980,8 @@ static int libplacebo_activate(AVFilterContext *ctx)
             }
         }
 
-        if (in->status && pts >= in->status_pts) {
-            ff_outlink_set_status(outlink, in->status, in->status_pts);
+        if (s->status && pts >= s->status_pts) {
+            ff_outlink_set_status(outlink, s->status, s->status_pts);
             return 0;
         }
 
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 11/22] lavfi/vf_libplacebo: support blending multiple inputs
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
                   ` (8 preceding siblings ...)
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 10/22] lavfi/vf_libplacebo: keep track of latest status globally Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 12/22] lavfi/vf_libplacebo: handle " Niklas Haas
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

Subsequent inputs required frame blending to be enable, in order to not
overwrite the existing frame contents.

For output metadata, we implicitly copy the metadata of the *first*
available stream (falling back to the second stream if the first has
already reached EOF, and so on). This is done to resolve any conflicts
between inputs with differing metadata. So when e.g. input 1 is HDR and
output 2 is SDR, the output will be HDR, and vice versa. This logic
could probablly be improved by dynamically determining some "superior"
set of metadata, but I don't want to handle that complexity in this
series.
---
 libavfilter/vf_libplacebo.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index d6f19f166d..3d812569f1 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -784,12 +784,18 @@ static int output_frame(AVFilterContext *ctx, int64_t pts)
 {
     int err = 0, ok, changed_csp;
     LibplaceboContext *s = ctx->priv;
-    LibplaceboInput *in = &s->inputs[0];
     AVFilterLink *outlink = ctx->outputs[0];
     const AVPixFmtDescriptor *outdesc = av_pix_fmt_desc_get(outlink->format);
-    const AVFrame *ref = ref_frame(&in->mix);
     struct pl_frame target;
+    const AVFrame *ref = NULL;
     AVFrame *out;
+
+    /* Use the first active input as metadata reference */
+    for (int i = 0; i < s->nb_inputs; i++) {
+        const LibplaceboInput *in = &s->inputs[i];
+        if (in->qstatus == PL_QUEUE_OK && (ref = ref_frame(&in->mix)))
+            break;
+    }
     if (!ref)
         return 0;
 
@@ -860,8 +866,18 @@ static int output_frame(AVFilterContext *ctx, int64_t pts)
         goto fail;
     }
 
-    update_crops(ctx, in, &target, out->pts * av_q2d(outlink->time_base));
-    pl_render_image_mix(in->renderer, &in->mix, &target, &s->params);
+    /* Draw first frame opaque, others with blending */
+    s->params.skip_target_clearing = false;
+    s->params.blend_params = NULL;
+    for (int i = 0; i < s->nb_inputs; i++) {
+        LibplaceboInput *in = &s->inputs[i];
+        if (in->qstatus != PL_QUEUE_OK)
+            continue;
+        update_crops(ctx, in, &target, out->pts * av_q2d(outlink->time_base));
+        pl_render_image_mix(in->renderer, &in->mix, &target, &s->params);
+        s->params.skip_target_clearing = true;
+        s->params.blend_params = &pl_alpha_overlay;
+    }
 
     if (outdesc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
         pl_unmap_avframe(s->gpu, &target);
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 12/22] lavfi/vf_libplacebo: handle multiple inputs
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
                   ` (9 preceding siblings ...)
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 11/22] lavfi/vf_libplacebo: support blending multiple inputs Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 13/22] lavfi/vf_libplacebo: determine PTS of next frame from any input Niklas Haas
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

This commit still relies on a single input for PTS determination, to be
changed in the next commit.
---
 libavfilter/vf_libplacebo.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 3d812569f1..08bb468c6b 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -977,11 +977,13 @@ static int libplacebo_activate(AVFilterContext *ctx)
     AVFilterLink *outlink = ctx->outputs[0];
     int64_t pts;
 
-    FF_FILTER_FORWARD_STATUS_BACK(outlink, in->link);
+    FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, ctx);
     pl_log_level_update(s->log, get_log_level());
 
-    if ((ret = handle_input(ctx, in)) < 0)
-        return ret;
+    for (int i = 0; i < s->nb_inputs; i++) {
+        if ((ret = handle_input(ctx, &s->inputs[i])) < 0)
+            return ret;
+    }
 
     if (ff_outlink_frame_wanted(outlink)) {
         if (s->fps.num) {
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 13/22] lavfi/vf_libplacebo: determine PTS of next frame from any input
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
                   ` (10 preceding siblings ...)
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 12/22] lavfi/vf_libplacebo: handle " Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 14/22] lavfi/vf_libplacebo: only drain actually used PTS Niklas Haas
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

When combining multiple inputs with different PTS and durations, in
input-timed mode, we emit one output frame for every input frame PTS,
from *any* input. So when combining a low FPS stream with a high FPS
stream, the output framerate would match the higher FPS, independent of
which order they are specified in.
---
 libavfilter/vf_libplacebo.c | 33 ++++++++++++++++++++-------------
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 08bb468c6b..5903bd5a01 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -971,11 +971,11 @@ static int handle_input(AVFilterContext *ctx, LibplaceboInput *input)
 
 static int libplacebo_activate(AVFilterContext *ctx)
 {
-    int ret;
+    int ret, retry = 0;
     LibplaceboContext *s = ctx->priv;
     LibplaceboInput *in = &s->inputs[0];
     AVFilterLink *outlink = ctx->outputs[0];
-    int64_t pts;
+    int64_t pts, out_pts;
 
     FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, ctx);
     pl_log_level_update(s->log, get_log_level());
@@ -987,24 +987,31 @@ static int libplacebo_activate(AVFilterContext *ctx)
 
     if (ff_outlink_frame_wanted(outlink)) {
         if (s->fps.num) {
-            pts = outlink->frame_count_out;
-        } else if (av_fifo_peek(in->out_pts, &pts, 1, 0) < 0) {
-            /* No frames queued */
-            if (in->status) {
-                pts = in->status_pts;
-            } else {
-                ff_inlink_request_frame(in->link);
-                return 0;
+            out_pts = outlink->frame_count_out;
+        } else {
+            /* Determine the PTS of the next frame from any active input */
+            out_pts = INT64_MAX;
+            for (int i = 0; i < s->nb_inputs; i++) {
+                LibplaceboInput *in = &s->inputs[i];
+                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);
+                    retry = true;
+                }
             }
+
+            if (retry) /* some inputs are incomplete */
+                return 0;
         }
 
-        if (s->status && pts >= s->status_pts) {
+        if (s->status && out_pts >= s->status_pts) {
             ff_outlink_set_status(outlink, s->status, s->status_pts);
             return 0;
         }
 
         in->qstatus = pl_queue_update(in->queue, &in->mix, pl_queue_params(
-            .pts            = pts * av_q2d(outlink->time_base),
+            .pts            = out_pts * av_q2d(outlink->time_base),
             .radius         = pl_frame_mix_radius(&s->params),
             .vsync_duration = av_q2d(av_inv_q(outlink->frame_rate)),
         ));
@@ -1016,7 +1023,7 @@ static int libplacebo_activate(AVFilterContext *ctx)
         case PL_QUEUE_OK:
             if (!s->fps.num)
                 av_fifo_drain2(in->out_pts, 1);
-            return output_frame(ctx, pts);
+            return output_frame(ctx, out_pts);
         case PL_QUEUE_ERR:
             return AVERROR_EXTERNAL;
         }
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 14/22] lavfi/vf_libplacebo: only drain actually used PTS
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
                   ` (11 preceding siblings ...)
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 13/22] lavfi/vf_libplacebo: determine PTS of next frame from any input Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 15/22] lavfi/vf_libplacebo: generalize frame update to multiple inputs Niklas Haas
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

When combining multiple inputs, the output PTS may be less than the PTS
of the input. In this case, the current's code assumption of always
draining one value from the FIFO is incorrect. Replace by a smarter
function which drains only those PTS values that were actually consumed.
---
 libavfilter/vf_libplacebo.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 5903bd5a01..896bdb4eb8 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -969,6 +969,13 @@ static int handle_input(AVFilterContext *ctx, LibplaceboInput *input)
     return 0;
 }
 
+static void drain_input_pts(LibplaceboInput *in, int64_t until)
+{
+    int64_t pts;
+    while (av_fifo_peek(in->out_pts, &pts, 1, 0) >= 0 && pts <= until)
+        av_fifo_drain2(in->out_pts, 1);
+}
+
 static int libplacebo_activate(AVFilterContext *ctx)
 {
     int ret, retry = 0;
@@ -1021,8 +1028,7 @@ static int libplacebo_activate(AVFilterContext *ctx)
             ff_inlink_request_frame(in->link);
             return 0;
         case PL_QUEUE_OK:
-            if (!s->fps.num)
-                av_fifo_drain2(in->out_pts, 1);
+            drain_input_pts(in, out_pts);
             return output_frame(ctx, out_pts);
         case PL_QUEUE_ERR:
             return AVERROR_EXTERNAL;
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 15/22] lavfi/vf_libplacebo: generalize frame update to multiple inputs
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
                   ` (12 preceding siblings ...)
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 14/22] lavfi/vf_libplacebo: only drain actually used PTS Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 16/22] lavfi/vf_libplacebo: make input-dependent vars dynamic Niklas Haas
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

In the event that some frame mixes are OK while others are not, the
priority goes:

1. Errors in updating any frame -> return error
2. Any input incomplete -> request frames and return
3. Any inputs OK -> ignore EOF streams and render remaining inputs
4. No inputs OK -> set output to most recent status

This logic ensures that we can continue rendering the remaining streams,
no matter which streams reach their end of life, until we have no
streams left at which point we forward the last EOF.
---
 libavfilter/vf_libplacebo.c | 52 ++++++++++++++++++++++++-------------
 1 file changed, 34 insertions(+), 18 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 896bdb4eb8..5af8167bb3 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -978,9 +978,8 @@ static void drain_input_pts(LibplaceboInput *in, int64_t until)
 
 static int libplacebo_activate(AVFilterContext *ctx)
 {
-    int ret, retry = 0;
+    int ret, ok = 0, retry = 0;
     LibplaceboContext *s = ctx->priv;
-    LibplaceboInput *in = &s->inputs[0];
     AVFilterLink *outlink = ctx->outputs[0];
     int64_t pts, out_pts;
 
@@ -1012,26 +1011,43 @@ static int libplacebo_activate(AVFilterContext *ctx)
                 return 0;
         }
 
-        if (s->status && out_pts >= s->status_pts) {
-            ff_outlink_set_status(outlink, s->status, s->status_pts);
-            return 0;
-        }
+        /* Update all input queues to the chosen out_pts */
+        for (int i = 0; i < s->nb_inputs; i++) {
+            LibplaceboInput *in = &s->inputs[i];
+            if (in->status && out_pts >= in->status_pts) {
+                in->qstatus = PL_QUEUE_EOF;
+                continue;
+            }
 
-        in->qstatus = pl_queue_update(in->queue, &in->mix, pl_queue_params(
-            .pts            = out_pts * av_q2d(outlink->time_base),
-            .radius         = pl_frame_mix_radius(&s->params),
-            .vsync_duration = av_q2d(av_inv_q(outlink->frame_rate)),
-        ));
+            in->qstatus = pl_queue_update(in->queue, &in->mix, pl_queue_params(
+                .pts            = out_pts * av_q2d(outlink->time_base),
+                .radius         = pl_frame_mix_radius(&s->params),
+                .vsync_duration = av_q2d(av_inv_q(outlink->frame_rate)),
+            ));
+
+            switch (in->qstatus) {
+            case PL_QUEUE_MORE:
+                ff_inlink_request_frame(in->link);
+                retry = true;
+                break;
+            case PL_QUEUE_OK:
+                ok = true;
+                break;
+            case PL_QUEUE_ERR:
+                return AVERROR_EXTERNAL;
+            }
+        }
 
-        switch (in->qstatus) {
-        case PL_QUEUE_MORE:
-            ff_inlink_request_frame(in->link);
+        if (retry) {
             return 0;
-        case PL_QUEUE_OK:
-            drain_input_pts(in, out_pts);
+        } else if (ok) {
+            /* Got any valid frame mixes, drain PTS queue and render output */
+            for (int i = 0; i < s->nb_inputs; i++)
+                drain_input_pts(&s->inputs[i], out_pts);
             return output_frame(ctx, out_pts);
-        case PL_QUEUE_ERR:
-            return AVERROR_EXTERNAL;
+        } else if (s->status) {
+            ff_outlink_set_status(outlink, s->status, s->status_pts);
+            return 0;
         }
 
         return AVERROR_BUG;
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 16/22] lavfi/vf_libplacebo: make input-dependent vars dynamic
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
                   ` (13 preceding siblings ...)
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 15/22] lavfi/vf_libplacebo: generalize frame update to multiple inputs Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 17/22] lavfi/vf_libplacebo: add in_idx variable Niklas Haas
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

Because these can differ based on the input, for multiple inputs.
---
 libavfilter/vf_libplacebo.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 5af8167bb3..f86493f4e2 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -739,6 +739,11 @@ static void update_crops(AVFilterContext *ctx, LibplaceboInput *in,
         double image_pts = src->pts * av_q2d(in->link->time_base);
 
         /* Update dynamic variables */
+        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_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]      = ctx->outputs[0]->frame_count_out;
@@ -1191,13 +1196,8 @@ static int libplacebo_config_output(AVFilterLink *outlink)
     }
 
     /* Static variables */
-    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_OUT_W]    = s->var_values[VAR_OW] = outlink->w;
     s->var_values[VAR_OUT_H]    = s->var_values[VAR_OH] = outlink->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_DAR]      = outlink->sample_aspect_ratio.num ?
         av_q2d(outlink->sample_aspect_ratio) : 1.0;
     s->var_values[VAR_HSUB]     = 1 << desc->log2_chroma_w;
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 17/22] lavfi/vf_libplacebo: add in_idx variable
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
                   ` (14 preceding siblings ...)
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 16/22] lavfi/vf_libplacebo: make input-dependent vars dynamic Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 18/22] lavfi/vf_libplacebo: set format list for all inputs Niklas Haas
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

To allow placing an input dynamically, as a function of the input index.
---
 doc/filters.texi            | 2 ++
 libavfilter/vf_libplacebo.c | 9 +++++++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index a46357bfd8..2ea4083c3e 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -16197,6 +16197,8 @@ the @option{crop_w}, @option{crop_h}, @option{crop_x}, @option{crop_y},
 also contain the following constants:
 
 @table @option
+@item in_idx, idx
+The (0-based) numeric index of the currently active input stream.
 @item crop_w, cw
 @item crop_h, ch
 The computed values of @option{crop_w} and @option{crop_h}.
diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index f86493f4e2..427a15dc47 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -70,6 +70,7 @@ enum {
 };
 
 static const char *const var_names[] = {
+    "in_idx", "idx",///< index of input
     "in_w", "iw",   ///< width  of the input video frame
     "in_h", "ih",   ///< height of the input video frame
     "out_w", "ow",  ///< width  of the output video frame
@@ -92,6 +93,7 @@ static const char *const var_names[] = {
 };
 
 enum var_name {
+    VAR_IN_IDX, VAR_IDX,
     VAR_IN_W,   VAR_IW,
     VAR_IN_H,   VAR_IH,
     VAR_OUT_W,  VAR_OW,
@@ -115,6 +117,7 @@ enum var_name {
 
 /* per-input dynamic filter state */
 typedef struct LibplaceboInput {
+    int idx;
     pl_renderer renderer;
     pl_queue queue;
     enum pl_queue_status qstatus;
@@ -574,7 +577,7 @@ static void unlock_queue(void *priv, uint32_t qf, uint32_t qidx)
 #endif
 
 static int input_init(AVFilterContext *avctx, AVFilterLink *link,
-                      LibplaceboInput *input)
+                      LibplaceboInput *input, int idx)
 {
     LibplaceboContext *s = avctx->priv;
 
@@ -584,6 +587,7 @@ static int input_init(AVFilterContext *avctx, AVFilterLink *link,
     input->queue = pl_queue_create(s->gpu);
     input->renderer = pl_renderer_create(s->log, s->gpu);
     input->link = link;
+    input->idx = idx;
 
     return 0;
 }
@@ -668,7 +672,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]));
+        RET(input_init(avctx, avctx->inputs[i], &s->inputs[i], i));
 
     /* fall through */
 fail:
@@ -739,6 +743,7 @@ static void update_crops(AVFilterContext *ctx, LibplaceboInput *in,
         double image_pts = src->pts * av_q2d(in->link->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;
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 18/22] lavfi/vf_libplacebo: set format list for all inputs
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
                   ` (15 preceding siblings ...)
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 17/22] lavfi/vf_libplacebo: add in_idx variable Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 19/22] lavfi/vf_libplacebo: skip cache selectively per-input Niklas Haas
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

---
 libavfilter/vf_libplacebo.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 427a15dc47..a30b244843 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -1129,7 +1129,8 @@ static int libplacebo_query_format(AVFilterContext *ctx)
         goto fail;
     }
 
-    RET(ff_formats_ref(infmts, &ctx->inputs[0]->outcfg.formats));
+    for (int i = 0; i < s->nb_inputs; i++)
+        RET(ff_formats_ref(infmts, &ctx->inputs[i]->outcfg.formats));
     RET(ff_formats_ref(outfmts, &ctx->outputs[0]->incfg.formats));
     return 0;
 
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 19/22] lavfi/vf_libplacebo: skip cache selectively per-input
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
                   ` (16 preceding siblings ...)
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 18/22] lavfi/vf_libplacebo: set format list for all inputs Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 20/22] lavfi/vf_libplacebo: also skip cache if in FPS == out FPS Niklas Haas
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

It may be the case that we want to skip the single frame cache for some
inputs but not others.
---
 libavfilter/vf_libplacebo.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index a30b244843..b78391441a 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -182,7 +182,6 @@ typedef struct LibplaceboContext {
     float antiringing;
     int sigmoid;
     int skip_aa;
-    int skip_cache;
     float polar_cutoff;
     int disable_linear;
     int disable_builtin;
@@ -471,7 +470,6 @@ static int update_settings(AVFilterContext *ctx)
         .num_hooks = s->num_hooks,
 
         .skip_anti_aliasing = s->skip_aa,
-        .skip_caching_single_frame = s->skip_cache,
         .polar_cutoff = s->polar_cutoff,
         .disable_linear_scaling = s->disable_linear,
         .disable_builtin_scalers = s->disable_builtin,
@@ -881,8 +879,10 @@ static int output_frame(AVFilterContext *ctx, int64_t pts)
     s->params.blend_params = NULL;
     for (int i = 0; i < s->nb_inputs; i++) {
         LibplaceboInput *in = &s->inputs[i];
+        int high_fps = av_cmp_q(in->link->frame_rate, outlink->frame_rate) > 0;
         if (in->qstatus != PL_QUEUE_OK)
             continue;
+        s->params.skip_caching_single_frame = high_fps;
         update_crops(ctx, in, &target, out->pts * av_q2d(outlink->time_base));
         pl_render_image_mix(in->renderer, &in->mix, &target, &s->params);
         s->params.skip_target_clearing = true;
@@ -1196,9 +1196,6 @@ static int libplacebo_config_output(AVFilterLink *outlink)
     if (s->fps.num) {
         outlink->frame_rate = s->fps;
         outlink->time_base = av_inv_q(s->fps);
-        s->skip_cache = av_cmp_q(inlink->frame_rate, s->fps) > 0;
-    } else {
-        s->skip_cache = true;
     }
 
     /* Static variables */
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 20/22] lavfi/vf_libplacebo: also skip cache if in FPS == out FPS
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
                   ` (17 preceding siblings ...)
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 19/22] lavfi/vf_libplacebo: skip cache selectively per-input Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 21/22] lavfi/vf_libplacebo: set time_base/frame_rate dynamically Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 22/22] lavfi/vf_libplacebo: add nb_inputs option Niklas Haas
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

Fixes an oversight in the previous code which should have been >=, not >.
---
 libavfilter/vf_libplacebo.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index b78391441a..9b1526f19e 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -879,7 +879,7 @@ static int output_frame(AVFilterContext *ctx, int64_t pts)
     s->params.blend_params = NULL;
     for (int i = 0; i < s->nb_inputs; i++) {
         LibplaceboInput *in = &s->inputs[i];
-        int high_fps = av_cmp_q(in->link->frame_rate, outlink->frame_rate) > 0;
+        int high_fps = av_cmp_q(in->link->frame_rate, outlink->frame_rate) >= 0;
         if (in->qstatus != PL_QUEUE_OK)
             continue;
         s->params.skip_caching_single_frame = high_fps;
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 21/22] lavfi/vf_libplacebo: set time_base/frame_rate dynamically
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
                   ` (18 preceding siblings ...)
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 20/22] lavfi/vf_libplacebo: also skip cache if in FPS == out FPS Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 22/22] lavfi/vf_libplacebo: add nb_inputs option Niklas Haas
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

Use the gcd of all input timebases to ensure PTS accuracy. For the
framerate, just pick the highest of all the inputs, under the assumption
that we will render frames with approximately this frequency. Of course,
this is not 100% accurate, in particular if the input frames are badly
misaligned. But this field is informational to begin with.

Importantly, it covers the "common" case of combining high FPS and low
FPS streams with aligned frames.
---
 libavfilter/vf_libplacebo.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 9b1526f19e..7840677b06 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -1156,6 +1156,11 @@ static int libplacebo_config_input(AVFilterLink *inlink)
     return 0;
 }
 
+static inline AVRational max_q(AVRational a, AVRational b)
+{
+    return av_cmp_q(a, b) < 0 ? b : a;
+}
+
 static int libplacebo_config_output(AVFilterLink *outlink)
 {
     int err;
@@ -1196,6 +1201,16 @@ static int libplacebo_config_output(AVFilterLink *outlink)
     if (s->fps.num) {
         outlink->frame_rate = s->fps;
         outlink->time_base = av_inv_q(s->fps);
+    } else {
+        outlink->frame_rate = avctx->inputs[0]->frame_rate;
+        outlink->time_base = avctx->inputs[0]->time_base;
+        for (int i = 1; i < s->nb_inputs; i++) {
+            outlink->frame_rate = max_q(outlink->frame_rate,
+                                        avctx->inputs[i]->frame_rate);
+            outlink->time_base = av_gcd_q(outlink->time_base,
+                                          avctx->inputs[i]->time_base,
+                                          AV_TIME_BASE / 2, AV_TIME_BASE_Q);
+        }
     }
 
     /* Static variables */
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [FFmpeg-devel] [PATCH 22/22] lavfi/vf_libplacebo: add nb_inputs option
  2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
                   ` (19 preceding siblings ...)
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 21/22] lavfi/vf_libplacebo: set time_base/frame_rate dynamically Niklas Haas
@ 2023-06-16  9:29 ` Niklas Haas
  20 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16  9:29 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Niklas Haas

From: Niklas Haas <git@haasn.dev>

To control the number of inputs.
---
 doc/filters.texi            |  5 +++++
 libavfilter/vf_libplacebo.c | 25 ++++++++++++++-----------
 2 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 2ea4083c3e..41cf4976cb 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -16101,6 +16101,11 @@ to preserve the source colorimetry and size as best as it can, but it will
 apply any embedded film grain, dolby vision metadata or anamorphic SAR present
 in source frames.
 @table @option
+@item inputs
+Set the number of inputs. This can be used, alongside the @code{idx} variable,
+to allow placing/blending multiple inputs inside the output frame. This
+effectively enables functionality similar to @ref{hstack}, @ref{overlay}, etc.
+
 @item w
 @item h
 Set the output video dimension expression. Default values are @code{iw} and
diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 7840677b06..cd3a156731 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -502,6 +502,7 @@ static int parse_shader(AVFilterContext *avctx, const void *shader, size_t len)
 }
 
 static void libplacebo_uninit(AVFilterContext *avctx);
+static int libplacebo_config_input(AVFilterLink *inlink);
 
 static int libplacebo_init(AVFilterContext *avctx)
 {
@@ -530,6 +531,17 @@ static int libplacebo_init(AVFilterContext *avctx)
         s->out_format = AV_PIX_FMT_NONE;
     }
 
+    for (int i = 0; i < s->nb_inputs; i++) {
+        AVFilterPad pad = {
+            .name         = av_asprintf("input%d", i),
+            .type         = AVMEDIA_TYPE_VIDEO,
+            .config_props = &libplacebo_config_input,
+        };
+        if (!pad.name)
+            return AVERROR(ENOMEM);
+        RET(ff_append_inpad_free_name(avctx, &pad));
+    }
+
     RET(update_settings(avctx));
     RET(av_expr_parse(&s->crop_x_pexpr, s->crop_x_expr, var_names,
                       NULL, NULL, NULL, NULL, 0, s));
@@ -665,7 +677,6 @@ static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwct
     }
 
     /* Initialize inputs */
-    s->nb_inputs = 1;
     s->inputs = av_calloc(s->nb_inputs, sizeof(*s->inputs));
     if (!s->inputs)
         return AVERROR(ENOMEM);
@@ -1250,6 +1261,7 @@ fail:
 #define DYNAMIC (STATIC | AV_OPT_FLAG_RUNTIME_PARAM)
 
 static const AVOption libplacebo_options[] = {
+    { "inputs", "Number of inputs", OFFSET(nb_inputs), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, .flags = STATIC },
     { "w", "Output video frame width",  OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, .flags = STATIC },
     { "h", "Output video frame height", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, .flags = STATIC },
     { "fps", "Output video frame rate", OFFSET(fps_string), AV_OPT_TYPE_STRING, {.str = "none"}, .flags = STATIC },
@@ -1441,14 +1453,6 @@ static const AVOption libplacebo_options[] = {
 
 AVFILTER_DEFINE_CLASS(libplacebo);
 
-static const AVFilterPad libplacebo_inputs[] = {
-    {
-        .name         = "default",
-        .type         = AVMEDIA_TYPE_VIDEO,
-        .config_props = &libplacebo_config_input,
-    },
-};
-
 static const AVFilterPad libplacebo_outputs[] = {
     {
         .name         = "default",
@@ -1465,10 +1469,9 @@ const AVFilter ff_vf_libplacebo = {
     .uninit         = &libplacebo_uninit,
     .activate       = &libplacebo_activate,
     .process_command = &libplacebo_process_command,
-    FILTER_INPUTS(libplacebo_inputs),
     FILTER_OUTPUTS(libplacebo_outputs),
     FILTER_QUERY_FUNC(libplacebo_query_format),
     .priv_class     = &libplacebo_class,
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
-    .flags          = AVFILTER_FLAG_HWDEVICE,
+    .flags          = AVFILTER_FLAG_HWDEVICE | AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
-- 
2.41.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [FFmpeg-devel] [PATCH 09/22] lavfi/vf_libplacebo: replace s->input by dynamic array
  2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 09/22] lavfi/vf_libplacebo: replace s->input by dynamic array Niklas Haas
@ 2023-06-16 12:09   ` Andreas Rheinhardt
  2023-06-16 12:22     ` Niklas Haas
  0 siblings, 1 reply; 24+ messages in thread
From: Andreas Rheinhardt @ 2023-06-16 12:09 UTC (permalink / raw)
  To: ffmpeg-devel

Niklas Haas:
> From: Niklas Haas <git@haasn.dev>
> 
> For now, hard-coded to 1 element.
> ---
>  libavfilter/vf_libplacebo.c | 18 +++++++++++++-----
>  1 file changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
> index 408fb3918a..fbac1b0354 100644
> --- a/libavfilter/vf_libplacebo.c
> +++ b/libavfilter/vf_libplacebo.c
> @@ -136,7 +136,8 @@ typedef struct LibplaceboContext {
>      pl_tex tex[4];
>  
>      /* input state */
> -    LibplaceboInput input;
> +    LibplaceboInput *inputs;
> +    int nb_inputs;
>  
>      /* settings */
>      char *out_format_string;
> @@ -660,7 +661,12 @@ static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwct
>      }
>  
>      /* Initialize inputs */
> -    RET(input_init(avctx, avctx->inputs[0], &s->input));
> +    s->nb_inputs = 1;
> +    s->inputs = av_calloc(s->nb_inputs, sizeof(*s->inputs));
> +    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]));
>  
>      /* fall through */
>  fail:
> @@ -677,7 +683,9 @@ static void libplacebo_uninit(AVFilterContext *avctx)
>          pl_tex_destroy(s->gpu, &s->tex[i]);
>      for (int i = 0; i < s->num_hooks; i++)
>          pl_mpv_user_shader_destroy(&s->hooks[i]);
> -    input_uninit(&s->input);
> +    for (int i = 0; i < s->nb_inputs && s->inputs; i++)
> +        input_uninit(&s->inputs[i]);
> +    av_freep(&s->inputs);

In case the allocation of s->inputs fails, nb_inputs is 1 and the above
loop will try to uninit a non-existant input.

>      pl_vulkan_destroy(&s->vulkan);
>      pl_log_destroy(&s->log);
>      ff_vk_uninit(&s->vkctx);
> @@ -774,7 +782,7 @@ static int output_frame(AVFilterContext *ctx, int64_t pts)
>  {
>      int err = 0, ok, changed_csp;
>      LibplaceboContext *s = ctx->priv;
> -    LibplaceboInput *in = &s->input;
> +    LibplaceboInput *in = &s->inputs[0];
>      AVFilterLink *outlink = ctx->outputs[0];
>      const AVPixFmtDescriptor *outdesc = av_pix_fmt_desc_get(outlink->format);
>      const AVFrame *ref = ref_frame(&in->mix);
> @@ -942,7 +950,7 @@ static int libplacebo_activate(AVFilterContext *ctx)
>  {
>      int ret;
>      LibplaceboContext *s = ctx->priv;
> -    LibplaceboInput *in = &s->input;
> +    LibplaceboInput *in = &s->inputs[0];
>      AVFilterLink *outlink = ctx->outputs[0];
>      int64_t pts;
>  

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [FFmpeg-devel] [PATCH 09/22] lavfi/vf_libplacebo: replace s->input by dynamic array
  2023-06-16 12:09   ` Andreas Rheinhardt
@ 2023-06-16 12:22     ` Niklas Haas
  0 siblings, 0 replies; 24+ messages in thread
From: Niklas Haas @ 2023-06-16 12:22 UTC (permalink / raw)
  To: ffmpeg-devel

On Fri, 16 Jun 2023 14:09:56 +0200 Andreas Rheinhardt <andreas.rheinhardt@outlook.com> wrote:
> Niklas Haas:
> > From: Niklas Haas <git@haasn.dev>
> > 
> > For now, hard-coded to 1 element.
> > ---
> >  libavfilter/vf_libplacebo.c | 18 +++++++++++++-----
> >  1 file changed, 13 insertions(+), 5 deletions(-)
> > 
> > diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
> > index 408fb3918a..fbac1b0354 100644
> > --- a/libavfilter/vf_libplacebo.c
> > +++ b/libavfilter/vf_libplacebo.c
> > @@ -136,7 +136,8 @@ typedef struct LibplaceboContext {
> >      pl_tex tex[4];
> >  
> >      /* input state */
> > -    LibplaceboInput input;
> > +    LibplaceboInput *inputs;
> > +    int nb_inputs;
> >  
> >      /* settings */
> >      char *out_format_string;
> > @@ -660,7 +661,12 @@ static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwct
> >      }
> >  
> >      /* Initialize inputs */
> > -    RET(input_init(avctx, avctx->inputs[0], &s->input));
> > +    s->nb_inputs = 1;
> > +    s->inputs = av_calloc(s->nb_inputs, sizeof(*s->inputs));
> > +    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]));
> >  
> >      /* fall through */
> >  fail:
> > @@ -677,7 +683,9 @@ static void libplacebo_uninit(AVFilterContext *avctx)
> >          pl_tex_destroy(s->gpu, &s->tex[i]);
> >      for (int i = 0; i < s->num_hooks; i++)
> >          pl_mpv_user_shader_destroy(&s->hooks[i]);
> > -    input_uninit(&s->input);
> > +    for (int i = 0; i < s->nb_inputs && s->inputs; i++)
> > +        input_uninit(&s->inputs[i]);
> > +    av_freep(&s->inputs);
> 
> In case the allocation of s->inputs fails, nb_inputs is 1 and the above
> loop will try to uninit a non-existant input.

There's an extra `s->inputs` check in the loop condition. I'll make it more
explicit.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2023-06-16 12:22 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-16  9:29 [FFmpeg-devel] [PATCH 01/22] lavfi/vf_libplacebo: drop redundant case Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 02/22] lavfi/vf_libplacebo: move input-specific state to struct Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 03/22] lavfi/vf_libplacebo: move input handling to separate function Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 04/22] lavfi/vf_libplacebo: cosmetic Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 05/22] lavfi/vf_libplacebo: move temporary vars into per-input struct Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 06/22] lavif/vf_libplacebo: remove pl_frame_mix from output_frame_mix Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 07/22] lavfi/vf_libplacebo: factor out ref frame logic Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 08/22] lavfi/vf_libplacebo: use correct link in update_crops() Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 09/22] lavfi/vf_libplacebo: replace s->input by dynamic array Niklas Haas
2023-06-16 12:09   ` Andreas Rheinhardt
2023-06-16 12:22     ` Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 10/22] lavfi/vf_libplacebo: keep track of latest status globally Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 11/22] lavfi/vf_libplacebo: support blending multiple inputs Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 12/22] lavfi/vf_libplacebo: handle " Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 13/22] lavfi/vf_libplacebo: determine PTS of next frame from any input Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 14/22] lavfi/vf_libplacebo: only drain actually used PTS Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 15/22] lavfi/vf_libplacebo: generalize frame update to multiple inputs Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 16/22] lavfi/vf_libplacebo: make input-dependent vars dynamic Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 17/22] lavfi/vf_libplacebo: add in_idx variable Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 18/22] lavfi/vf_libplacebo: set format list for all inputs Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 19/22] lavfi/vf_libplacebo: skip cache selectively per-input Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 20/22] lavfi/vf_libplacebo: also skip cache if in FPS == out FPS Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 21/22] lavfi/vf_libplacebo: set time_base/frame_rate dynamically Niklas Haas
2023-06-16  9:29 ` [FFmpeg-devel] [PATCH 22/22] lavfi/vf_libplacebo: add nb_inputs option Niklas Haas

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git