[FFmpeg-cvslog] lavfi/vf_libplacebo: move input-specific state to struct
Niklas Haas
git at videolan.org
Tue Jun 20 18:11:12 EEST 2023
ffmpeg | branch: master | Niklas Haas <git at haasn.dev> | Tue Jun 13 15:44:13 2023 +0200| [c3b17ccc6251ec26ac3a06ed2571b45489ce7f46] | committer: Niklas Haas
lavfi/vf_libplacebo: move input-specific state to struct
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.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=c3b17ccc6251ec26ac3a06ed2571b45489ce7f46
---
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;
More information about the ffmpeg-cvslog
mailing list