PR #21327 opened by Olivier Crête (ocrete) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21327 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21327.patch
The sqrt operation is costly, so avoid it if possible by comparing squared values. From 74113a4666cf71a97b7569ef747b99d21c236cea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cr=C3=AAte?= <[email protected]> Date: Tue, 30 Dec 2025 12:55:33 -0500 Subject: [PATCH] libavfilter/vf_chromakey: Avoid sqrt when possible The sqrt operation is costly, so avoid it if possible by comparing squared values. --- libavfilter/vf_chromakey.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/libavfilter/vf_chromakey.c b/libavfilter/vf_chromakey.c index e5a7ac15b5..e741e9e3b5 100644 --- a/libavfilter/vf_chromakey.c +++ b/libavfilter/vf_chromakey.c @@ -47,44 +47,44 @@ typedef struct ChromakeyContext { static uint8_t do_chromakey_pixel(ChromakeyContext *ctx, uint8_t u[9], uint8_t v[9]) { - double diff = 0.0; + double diff_squared = 0.0; int du, dv, i; for (i = 0; i < 9; ++i) { du = (int)u[i] - ctx->chromakey_uv[0]; dv = (int)v[i] - ctx->chromakey_uv[1]; - diff += sqrt((du * du + dv * dv) / (255.0 * 255.0 * 2)); + diff_squared += (du * du + dv * dv) / (255.0 * 255.0 * 2); } - diff /= 9.0; + diff_squared /= 81.0; if (ctx->blend > 0.0001) { - return av_clipd((diff - ctx->similarity) / ctx->blend, 0.0, 1.0) * 255.0; + return av_clipd((sqrt(diff_squared) - ctx->similarity) / ctx->blend, 0.0, 1.0) * 255.0; } else { - return (diff > ctx->similarity) ? 255 : 0; + return (diff_squared > ctx->similarity * ctx->similarity) ? 255 : 0; } } static uint16_t do_chromakey_pixel16(ChromakeyContext *ctx, uint16_t u[9], uint16_t v[9]) { double max = ctx->max; - double diff = 0.0; + double diff_squared = 0.0; int du, dv, i; for (i = 0; i < 9; ++i) { du = (int)u[i] - ctx->chromakey_uv[0]; dv = (int)v[i] - ctx->chromakey_uv[1]; - diff += sqrt((du * du + dv * dv) / (max * max * 2)); + diff_squared += (du * du + dv * dv) / (max * max * 2); } - diff /= 9.0; + diff_squared /= 81.0; if (ctx->blend > 0.0001) { - return av_clipd((diff - ctx->similarity) / ctx->blend, 0.0, 1.0) * max; + return av_clipd((sqrt(diff_squared) - ctx->similarity) / ctx->blend, 0.0, 1.0) * max; } else { - return (diff > ctx->similarity) ? max : 0; + return (diff_squared > ctx->similarity * ctx->similarity) ? max : 0; } } @@ -189,17 +189,17 @@ static int do_chromahold_slice(AVFilterContext *avctx, void *arg, int jobnr, int for (x = 0; x < frame->width >> ctx->hsub_log2; ++x) { int u = frame->data[1][frame->linesize[1] * y + x]; int v = frame->data[2][frame->linesize[2] * y + x]; - double diff; + double diff_squared; int du, dv; du = u - ctx->chromakey_uv[0]; dv = v - ctx->chromakey_uv[1]; - diff = sqrt((du * du + dv * dv) / (255.0 * 255.0 * 2.0)); + diff_squared = (du * du + dv * dv) / (255.0 * 255.0 * 2.0); - alpha = diff > ctx->similarity; + alpha = diff_squared > ctx->similarity * ctx->similarity; if (ctx->blend > 0.0001) { - double f = 1. - av_clipd((diff - ctx->similarity) / ctx->blend, 0.0, 1.0); + double f = 1. - av_clipd((sqrt(diff_squared) - ctx->similarity) / ctx->blend, 0.0, 1.0); frame->data[1][frame->linesize[1] * y + x] = 128 + (u - 128) * f; frame->data[2][frame->linesize[2] * y + x] = 128 + (v - 128) * f; @@ -228,17 +228,17 @@ static int do_chromahold16_slice(AVFilterContext *avctx, void *arg, int jobnr, i for (x = 0; x < frame->width >> ctx->hsub_log2; ++x) { int u = AV_RN16(&frame->data[1][frame->linesize[1] * y + 2 * x]); int v = AV_RN16(&frame->data[2][frame->linesize[2] * y + 2 * x]); - double diff; + double diff_squared; int du, dv; du = u - ctx->chromakey_uv[0]; dv = v - ctx->chromakey_uv[1]; - diff = sqrt((du * du + dv * dv) / (max * max * 2.0)); + diff_squared = (du * du + dv * dv) / (max * max * 2.0); - alpha = diff > ctx->similarity; + alpha = diff_squared > ctx->similarity * ctx->similarity; if (ctx->blend > 0.0001) { - double f = 1. - av_clipd((diff - ctx->similarity) / ctx->blend, 0.0, 1.0); + double f = 1. - av_clipd((sqrt(diff_squared) - ctx->similarity) / ctx->blend, 0.0, 1.0); AV_WN16(&frame->data[1][frame->linesize[1] * y + 2 * x], mid + (u - mid) * f); AV_WN16(&frame->data[2][frame->linesize[2] * y + 2 * x], mid + (v - mid) * f); -- 2.49.1 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
