summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Haas <[email protected]>2023-06-15 15:56:33 +0200
committerNiklas Haas <[email protected]>2023-06-20 17:09:58 +0200
commit56e550b2645963ad38f0211c6f01720d5bf0d6f3 (patch)
tree782f3bdab44a639801918c5f6579b71a131e09cc
parent0c66d912ba2248a3650fb1ed8563adf28bff2987 (diff)
lavfi/vf_libplacebo: support blending multiple inputs
Subsequent inputs require frame blending to be enabled, 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.
-rw-r--r--libavfilter/vf_libplacebo.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 5b45d4f8fb..5ea6fcd792 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -786,12 +786,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;
@@ -862,8 +868,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);